@henderea/static-site-builder 1.9.5 → 1.9.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/static-site-builder.js +30 -31
- package/config/cache-config.js +99 -99
- package/config/env.js +10 -11
- package/config/paths.js +55 -50
- package/config/webpack.config.dev.js +168 -168
- package/config/webpack.config.prod.js +253 -253
- package/package.json +44 -31
- package/scripts/build.js +89 -89
- package/scripts/watch.js +82 -82
- package/utils/FileSizeReporter.js +25 -25
- package/utils/checkRequiredFiles.js +5 -7
- package/utils/formatWebpackMessages.js +13 -15
- package/utils/printBuildError.js +5 -5
- package/utils/workspaceUtils.js +12 -13
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import webpack from 'webpack';
|
|
4
|
+
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
|
5
|
+
import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin';
|
|
6
|
+
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
|
7
|
+
import { WebpackManifestPlugin } from 'webpack-manifest-plugin';
|
|
8
|
+
import CopyPlugin from 'copy-webpack-plugin';
|
|
9
|
+
import { GenerateSW } from 'workbox-webpack-plugin';
|
|
10
|
+
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
|
|
11
|
+
import MomentLocalesPlugin from 'moment-locales-webpack-plugin';
|
|
12
|
+
import getClientEnvironment from './env';
|
|
13
|
+
import * as paths from './paths';
|
|
14
|
+
import _ from 'lodash';
|
|
15
|
+
import crypto from 'crypto';
|
|
16
|
+
import { globbySync } from 'globby';
|
|
17
17
|
|
|
18
18
|
// Webpack uses `publicPath` to determine where the app is being served from.
|
|
19
19
|
// It requires a trailing slash, or the file assets will get an incorrect path.
|
|
20
20
|
let publicPath = paths.servedPath;
|
|
21
21
|
// Some apps do not use client-side routing with pushState.
|
|
22
22
|
// For these, "homepage" can be set to "." to enable relative asset paths.
|
|
23
|
-
const shouldUseRelativeAssetPaths = publicPath === './';
|
|
23
|
+
// const shouldUseRelativeAssetPaths = publicPath === './';
|
|
24
24
|
// `publicUrl` is just like `publicPath`, but we will provide it to our app
|
|
25
25
|
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
|
|
26
26
|
// Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
|
|
@@ -30,339 +30,339 @@ let env = getClientEnvironment(publicUrl);
|
|
|
30
30
|
|
|
31
31
|
const cssFilename = '[name].css';
|
|
32
32
|
|
|
33
|
-
const getRevision = file => crypto.createHash('md5').update(fs.readFileSync(file)).digest('hex')
|
|
33
|
+
const getRevision = (file) => crypto.createHash('md5').update(fs.readFileSync(file)).digest('hex');
|
|
34
34
|
|
|
35
35
|
let additionalManifestEntries = undefined;
|
|
36
36
|
|
|
37
37
|
if(fs.existsSync(paths.publicDir)) {
|
|
38
|
-
|
|
38
|
+
additionalManifestEntries = globbySync(['**/*', '!asset-manifest.json', '!service-worker.js'], { cwd: paths.publicDir }).map((f) => ({ url: `${publicUrl}/${f}`, revision: getRevision(path.join(paths.publicDir, f)) }));
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
let ssbConfig = {};
|
|
42
42
|
|
|
43
43
|
if(fs.existsSync(paths.ssbConfig)) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
44
|
+
let ssbConfigObj = require(paths.ssbConfig);
|
|
45
|
+
if(ssbConfigObj) {
|
|
46
|
+
if(_.isFunction(ssbConfigObj)) {
|
|
47
|
+
ssbConfig = ssbConfigObj(env.raw, 'production', { publicUrl, ...paths });
|
|
48
|
+
} else if(_.isPlainObject(ssbConfigObj)) {
|
|
49
|
+
if(_.has(ssbConfigObj, 'prod')) {
|
|
50
|
+
ssbConfig = _.get(ssbConfigObj, 'prod');
|
|
51
|
+
} else if(_.has(ssbConfigObj, 'production')) {
|
|
52
|
+
ssbConfig = _.get(ssbConfigObj, 'production');
|
|
53
|
+
} else {
|
|
54
|
+
ssbConfig = ssbConfigObj;
|
|
55
|
+
}
|
|
57
56
|
}
|
|
57
|
+
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
ssbConfig = ssbConfig || {};
|
|
61
61
|
|
|
62
62
|
if(ssbConfig.env && _.isPlainObject(ssbConfig.env)) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
63
|
+
const raw = _.extend({}, env.raw, ssbConfig.env);
|
|
64
|
+
const stringified = {
|
|
65
|
+
'process.env': Object.keys(raw).reduce((env, key) => {
|
|
66
|
+
env[key] = JSON.stringify(raw[key]);
|
|
67
|
+
return env;
|
|
68
|
+
}, {}),
|
|
69
|
+
};
|
|
70
|
+
env = { raw, stringified };
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
if(ssbConfig.additionalManifestEntries && _.isArray(ssbConfig.additionalManifestEntries)) {
|
|
74
|
-
|
|
74
|
+
additionalManifestEntries.push(...ssbConfig.additionalManifestEntries);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
let runtimeCaching = require('./cache-config');
|
|
78
78
|
|
|
79
79
|
if(ssbConfig.runtimeCaching && _.isArray(ssbConfig.runtimeCaching)) {
|
|
80
|
-
|
|
80
|
+
runtimeCaching = ssbConfig.runtimeCaching;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
runtimeCaching.unshift({
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
84
|
+
urlPattern: publicPath,
|
|
85
|
+
handler: 'NetworkFirst',
|
|
86
|
+
options: {
|
|
87
|
+
cacheName: 'start-url',
|
|
88
|
+
expiration: {
|
|
89
|
+
maxEntries: 1,
|
|
90
|
+
maxAgeSeconds: 24 * 60 * 60 // 24 hours
|
|
92
91
|
}
|
|
92
|
+
}
|
|
93
93
|
});
|
|
94
94
|
|
|
95
95
|
let htmlWebpackPluginOptions = {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
filename: 'index.html',
|
|
97
|
+
template: paths.appTemplate,
|
|
98
|
+
inject: 'head',
|
|
99
|
+
minify: { collapseWhitespace: true }
|
|
100
100
|
};
|
|
101
101
|
|
|
102
102
|
if(ssbConfig.htmlWebpackPluginOptions && _.isPlainObject(ssbConfig.htmlWebpackPluginOptions)) {
|
|
103
|
-
|
|
103
|
+
htmlWebpackPluginOptions = _.extend({}, htmlWebpackPluginOptions, ssbConfig.htmlWebpackPluginOptions);
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
const plugins = [
|
|
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
|
-
|
|
107
|
+
new webpack.DefinePlugin(env.stringified),
|
|
108
|
+
new HtmlWebpackPlugin(htmlWebpackPluginOptions),
|
|
109
|
+
new CaseSensitivePathsPlugin(),
|
|
110
|
+
new MiniCssExtractPlugin({
|
|
111
|
+
filename: cssFilename
|
|
112
|
+
}),
|
|
113
|
+
new WebpackManifestPlugin({
|
|
114
|
+
fileName: 'asset-manifest.json',
|
|
115
|
+
publicPath,
|
|
116
|
+
filter(file) {
|
|
117
|
+
if(/^[/]?[.]{2}[/]?/.test(file.path)) { return false; }
|
|
118
|
+
if(/\.ts$/.test(file.path)) { return false; }
|
|
119
|
+
if(/(^|[/])\./.test(file.name)) { return false; }
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}),
|
|
123
|
+
new GenerateSW({
|
|
124
|
+
// Don't precache sourcemaps (they're large) and build asset manifest:
|
|
125
|
+
exclude: [/\.map$/, /asset-manifest\.json$/, /^[/]?[.]{2}/, /.ts$/],
|
|
126
|
+
// `navigateFallback` and `navigateFallbackWhitelist` are disabled by default; see
|
|
127
|
+
// https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#service-worker-considerations
|
|
128
|
+
navigateFallback: publicUrl + '/index.html',
|
|
129
|
+
navigateFallbackDenylist: [/^\/_/],
|
|
130
|
+
additionalManifestEntries,
|
|
131
|
+
cleanupOutdatedCaches: true,
|
|
132
|
+
clientsClaim: true,
|
|
133
|
+
skipWaiting: true,
|
|
134
|
+
runtimeCaching,
|
|
135
|
+
}),
|
|
136
136
|
];
|
|
137
137
|
|
|
138
138
|
if(ssbConfig.plugins && _.isArray(ssbConfig.plugins)) {
|
|
139
|
-
|
|
139
|
+
plugins.push(...ssbConfig.plugins);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
const copyPatterns = [];
|
|
143
143
|
|
|
144
144
|
if(fs.existsSync(paths.publicDir)) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
copyPatterns.push({
|
|
146
|
+
from: paths.publicDir,
|
|
147
|
+
to: paths.appDist
|
|
148
|
+
});
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
if(ssbConfig.copyPatterns && _.isArray(ssbConfig.copyPatterns)) {
|
|
152
|
-
|
|
152
|
+
copyPatterns.push(...ssbConfig.copyPatterns);
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
if(copyPatterns.length > 0) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
plugins.push(new CopyPlugin({
|
|
157
|
+
patterns: copyPatterns
|
|
158
|
+
}));
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
let tsConfigPath = paths.tsConfig;
|
|
162
162
|
|
|
163
163
|
if(ssbConfig.tsConfigPath && fs.existsSync(paths.resolveApp(ssbConfig.tsConfigPath))) {
|
|
164
|
-
|
|
164
|
+
tsConfigPath = paths.resolveApp(ssbConfig.tsConfigPath);
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
const resolvePlugins = [];
|
|
168
168
|
|
|
169
169
|
if(fs.existsSync(tsConfigPath)) {
|
|
170
|
-
|
|
170
|
+
resolvePlugins.push(new TsconfigPathsPlugin({ configFile: tsConfigPath }));
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
let appIndex = paths.appIndex;
|
|
174
174
|
|
|
175
175
|
if(ssbConfig.appIndex && fs.existsSync(paths.resolveApp(appIndex))) {
|
|
176
|
-
|
|
176
|
+
appIndex = paths.resolveApp(appIndex);
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
const packageJson = require(paths.appPackageJson);
|
|
180
180
|
const config = _.extend({}, packageJson.staticSiteBuilderConfig || {}, ssbConfig);
|
|
181
181
|
const rawMomentLocales = config && config.momentLocales;
|
|
182
182
|
if(rawMomentLocales === '') {
|
|
183
|
-
|
|
183
|
+
plugins.push(new MomentLocalesPlugin());
|
|
184
184
|
} else if(rawMomentLocales) {
|
|
185
|
-
|
|
185
|
+
plugins.push(new MomentLocalesPlugin({ localesToKeep: rawMomentLocales.split(/\s*,\s*/g) }));
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
const performance = {};
|
|
189
189
|
|
|
190
190
|
if(config && (config.sizeHints === false || config.sizeHints == 'warning' || config.sizeHints == 'error')) {
|
|
191
|
-
|
|
191
|
+
performance.hints = config.sizeHints;
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
const getSizeValue = val => {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
}
|
|
194
|
+
const getSizeValue = (val) => {
|
|
195
|
+
if(_.isNil(val) || val === false) { return null; }
|
|
196
|
+
if(_.isNumber(val) && !_.isNaN(val)) { return Math.round(val); }
|
|
197
|
+
if(_.isString(val)) {
|
|
198
|
+
let m = val.match(/^(\d+(?:\.\d+)?|\.\d+)([bkmg])?$/i);
|
|
199
|
+
if(m) {
|
|
200
|
+
let num = parseFloat(m[1]);
|
|
201
|
+
if(!_.isNaN(num)) {
|
|
202
|
+
let unit = m[2];
|
|
203
|
+
if(!unit || unit === '') { unit = 'b'; }
|
|
204
|
+
unit = unit.toLowerCase();
|
|
205
|
+
let unitIndex = 'bkmg'.indexOf(unit);
|
|
206
|
+
if(unitIndex >= 0 || unitIndex <= 3) {
|
|
207
|
+
return Math.round(num * Math.pow(1024, unitIndex));
|
|
210
208
|
}
|
|
209
|
+
}
|
|
211
210
|
}
|
|
212
|
-
|
|
213
|
-
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
213
|
+
};
|
|
214
214
|
|
|
215
215
|
let maxEntrypointSize = getSizeValue(config && config.maxEntrypointSize);
|
|
216
216
|
|
|
217
217
|
if(config && maxEntrypointSize) {
|
|
218
|
-
|
|
218
|
+
performance.maxEntrypointSize = maxEntrypointSize;
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
let maxAssetSize = getSizeValue(config && config.maxAssetSize);
|
|
222
222
|
|
|
223
223
|
if(config && maxAssetSize) {
|
|
224
|
-
|
|
224
|
+
performance.maxAssetSize = maxAssetSize;
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
const extraLoaders = [];
|
|
228
228
|
|
|
229
229
|
if(ssbConfig.extraLoaders && _.isArray(ssbConfig.extraLoaders)) {
|
|
230
|
-
|
|
230
|
+
extraLoaders.push(...ssbConfig.extraLoaders);
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
module.exports = _.defaultsDeep({}, ssbConfig.webpack || {}, {
|
|
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
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
]
|
|
234
|
+
mode: 'production',
|
|
235
|
+
entry: {
|
|
236
|
+
index: appIndex
|
|
237
|
+
},
|
|
238
|
+
devtool: 'source-map',
|
|
239
|
+
output: {
|
|
240
|
+
pathinfo: true,
|
|
241
|
+
path: paths.appDist,
|
|
242
|
+
publicPath: publicPath
|
|
243
|
+
},
|
|
244
|
+
resolve: {
|
|
245
|
+
modules: ['node_modules'].concat(
|
|
246
|
+
// It is guaranteed to exist because we tweak it in `env.js`
|
|
247
|
+
process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
|
|
248
|
+
),
|
|
249
|
+
extensions: ['.js', '.ts', '.json'],
|
|
250
|
+
plugins: resolvePlugins,
|
|
251
|
+
roots: [paths.appPath, paths.publicDir],
|
|
252
|
+
},
|
|
253
|
+
module: {
|
|
254
|
+
strictExportPresence: true,
|
|
255
|
+
rules: [
|
|
256
|
+
{
|
|
257
|
+
test: /\.[tj]s$/,
|
|
258
|
+
parser: { requireEnsure: false }
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
oneOf: [
|
|
262
|
+
...extraLoaders,
|
|
263
|
+
{
|
|
264
|
+
test: /\.ts$/,
|
|
265
|
+
exclude: [/[/\\\\]node_modules[/\\\\]/],
|
|
266
|
+
use: [
|
|
267
|
+
{
|
|
268
|
+
loader: require.resolve('ts-loader'),
|
|
269
|
+
options: {
|
|
270
|
+
configFile: tsConfigPath
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
]
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
test: /\.js$/,
|
|
277
|
+
exclude: [/[/\\\\]node_modules[/\\\\]/],
|
|
278
|
+
use: [
|
|
279
|
+
require.resolve('thread-loader'),
|
|
280
|
+
{
|
|
281
|
+
loader: require.resolve('babel-loader'),
|
|
282
|
+
options: {
|
|
283
|
+
babelrc: false,
|
|
284
|
+
compact: true,
|
|
285
|
+
highlightCode: true,
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
]
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
test: /\.js$/,
|
|
292
|
+
use: [
|
|
293
|
+
require.resolve('thread-loader'),
|
|
294
|
+
{
|
|
295
|
+
loader: require.resolve('babel-loader'),
|
|
296
|
+
options: {
|
|
297
|
+
babelrc: false,
|
|
298
|
+
compact: false,
|
|
299
|
+
// This is a feature of `babel-loader` for webpack (not Babel itself).
|
|
300
|
+
// It enables caching results in ./node_modules/.cache/babel-loader/
|
|
301
|
+
// directory for faster rebuilds.
|
|
302
|
+
cacheDirectory: true,
|
|
303
|
+
highlightCode: true,
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
]
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
test: /\.css$/,
|
|
310
|
+
use: [
|
|
311
|
+
MiniCssExtractPlugin.loader,
|
|
312
|
+
{
|
|
313
|
+
loader: 'css-loader',
|
|
314
|
+
options: {
|
|
315
|
+
sourceMap: true,
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
]
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
test: /\.scss$/,
|
|
322
|
+
use: [
|
|
323
|
+
MiniCssExtractPlugin.loader,
|
|
324
|
+
{
|
|
325
|
+
loader: 'css-loader',
|
|
326
|
+
options: {
|
|
327
|
+
importLoaders: 1,
|
|
328
|
+
sourceMap: true,
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
loader: 'postcss-loader',
|
|
333
|
+
options: {
|
|
334
|
+
postcssOptions: {
|
|
335
|
+
plugins: ['postcss-preset-env']
|
|
336
|
+
},
|
|
337
|
+
sourceMap: true
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
loader: 'sass-loader',
|
|
342
|
+
options: {
|
|
343
|
+
sassOptions: {
|
|
344
|
+
outputStyle: 'compressed'
|
|
345
|
+
},
|
|
346
|
+
sourceMap: true
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
]
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
loader: require.resolve('file-loader'),
|
|
353
|
+
// Exclude `js` files to keep "css" loader working as it injects
|
|
354
|
+
// its runtime that would otherwise processed through "file" loader.
|
|
355
|
+
// Also exclude `html` and `json` extensions so they get processed
|
|
356
|
+
// by webpack's internal loaders.
|
|
357
|
+
exclude: [/\.js$/, /\.ts$/, /\.html$/, /\.ejs$/, /\.hbs$/, /\.json$/],
|
|
358
|
+
options: {
|
|
359
|
+
name: '[name].[ext]'
|
|
363
360
|
}
|
|
361
|
+
}
|
|
364
362
|
]
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
363
|
+
}
|
|
364
|
+
]
|
|
365
|
+
},
|
|
366
|
+
plugins,
|
|
367
|
+
performance
|
|
368
|
+
});
|