-
Notifications
You must be signed in to change notification settings - Fork 0
/
webpack.config.js
298 lines (277 loc) · 9.56 KB
/
webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
const webpack = require('webpack');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const MinifyPlugin = require('babel-minify-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const CleanWebpackPlugin = require('clean-webpack-plugin').CleanWebpackPlugin;
/*
* Imatic View bundle webpack configuration.
*
* Compiles javascript sources and styles into one bundle usable in browser.
*
* Supported browsers are defined in package.json under browserslist key.
* Available queries can be found here: https://github.com/ai/browserslist#queries
*
* These files are also available as sources if there is need for custom version of them.
*/
module.exports = function configure(env, opts) {
env = env || {dev: true};
/*
* Options for babel loader.
* Babel loader is used for javascript code as well as for javascript generated by typescript.
*/
const babelOptions = {
babelrc: false, // Ignore .babelrc files encountered in libraries.
presets: [
/*
* Transpile for browsers determined by browserslist query in package.json.
*/
['@babel/preset-env', { // Preset for configured browsers.
modules: false,
loose: true, // Loose mode generated less strict but simpler transpiled code.
}]
]
};
/*
* Options for postcss preprocessor.
*/
const postcssOptions = {
ident: 'postcss',
sourceMaps: !env.prod,
plugins: [
/*
* Supported browsers are determined by browserslist query in package.json.
*/
require('autoprefixer')(),
require('cssnano')()
]
};
/*
* Returned configuration ...
*/
const config = {
/*
* Source map depends on environment ...
*/
devtool: !!env.prod
? 'nosources-source-map'
: 'inline-source-map',
/*
* Entries for platform and demo ...
*/
entry: {
platform: ['./Resources/assets/platform.scss', './Resources/assets/platform'],
demo: ['./Resources/assets/platform.scss', './Resources/assets/demo']
},
/*
* Output to dist folder ...
*/
output: {
path: path.resolve(__dirname, 'Resources/public'),
filename: '[name].js',
publicPath: '/bundles/imaticview/'
},
/*
* Loader rules ...
*/
module: {
rules: [
/*
* Basic css compilation.
*
* CSS is minimized in production.
* Source maps are not generated in production (css source maps affect performance).
*/
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: 'css-loader',
options: {
sourceMap: !env.prod,
importLoaders: 1,
}
},
{
loader: 'postcss-loader',
options: postcssOptions
}
]
},
/*
* Sass compilation.
*
* Same rules as for css loader apply.
*/
{
test: /\.s[ca]ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: 'css-loader',
options: {
sourceMap: !env.prod,
importLoaders: 3,
}
},
{
loader: 'postcss-loader',
options: postcssOptions
},
'resolve-url-loader',
{
loader: 'sass-loader',
options: {
sourceMap: true,
sourceMapContents: false
}
}
]
},
/*
* ES6 compilation.
*/
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: babelOptions
}
]
},
/*
* TypeScript compilation.
*
* Typescript files are checked and transpiled to js.
* Resulting JS files are then transpiled using babel with same configuration as straight js files.
*/
{
test: /\.ts$/,
use: [
{
loader: 'babel-loader',
options: babelOptions
},
{
loader: 'ts-loader',
options: {
silent: !!opts.json
}
}
]
},
/*
* Fonts are copied to fonts directory.
*/
{
test: /\.(woff2?|ttf|eot)$/,
use: {
loader: 'file-loader',
options: {
name: 'fonts/[name].[ext]'
}
}
},
/*
* Images are copied to images directory.
*/
{
test: /\.(jpe?g|png|gif|svg)($|\?)/i,
use: [
{
loader: 'file-loader',
options: {
hash: 'sha512',
digest: 'hex',
name: 'images/[name].[ext]'
}
}
]
},
/*
* expose jQuery
*/
{
test: require.resolve('jquery'),
use: [{
loader: 'expose-loader',
options: 'jQuery'
},{
loader: 'expose-loader',
options: '$'
}]
}
]
},
/*
* Resolve configuration ...
*/
resolve: {
extensions: ['.ts', '.js'], // Typescript and javascript files should be resolved without extension.
modules: [
'node_modules',
/*
* Search for modules in vendors directory too.
* Resolution works the same way as for node_modules directory.
* Any file required is searched for in ./vendor then ../vendor etc.
* This means you can require a file from php package and it doesn't matter,
* if you work on the bundle alone or the bundle is par of a bigger project.
* Example: require('imatic/form-bundle/Resources/public/js/Form')
*/
'vendor'
]
},
/*
* Plugins configuration ...
*/
plugins: [
/*
* Define NODE_ENV for some libraries that take it into account nad provide more compact version.
*/
new webpack.DefinePlugin({
NODE_ENV: JSON.stringify(!!env.prod ? 'production' : 'development')
}),
/*
* Only require en cs and sk locales for moment.js.
*/
new webpack.ContextReplacementPlugin(/moment[\\/]locale$/, /^\.\/(en|cs)$/),
/*
* Extract css files imported throughout the bundle into a separate css file.
*/
new MiniCssExtractPlugin({
filename: '[name].css'
}),
/*
* Clean output folder before rebuild.
*/
new CleanWebpackPlugin()
]
};
/*
* In production, include MinifyPlugin which serves as a replacement for UglifyJs plugin.
* UglifyJs only minifies ES% code which is not desirable when generating partially ES6 code.
* ES6 is generated thanks to env babel preset. There is no need to transpile code
* which is already supported in all major browsers.
*/
if (!!env.prod) {
config.plugins.push(new MinifyPlugin({
evaluate: false,
numericLiterals: false,
propertyLiterals: false,
}));
}
/*
* In analyze environment add bundle analyzer.
* This plugin is extremely useful when optimizing built file sizes.
*/
if (!!env.analyze) {
config.plugins.push(new BundleAnalyzerPlugin());
}
return config;
};