@oroinc/oro-webpack-config-builder 5.1.0-alpha3 → 5.1.0-alpha30
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/README.md +1 -1
- package/messages.js +29 -0
- package/modules-config/layout-modules-config-loader.js +62 -2
- package/modules-config/modules-config-loader.js +32 -14
- package/oro-webpack-config.js +361 -298
- package/package.json +29 -26
- package/prepare-modules-shim.js +13 -1
- package/style/admin-style-loader.js +22 -0
- package/style/layout-style-loader.js +12 -109
- package/style/style-loader.js +130 -46
- package/theme-config-factory.js +48 -5
- package/writer/configs-file-writer.js +1 -1
- package/writer/dynamic-imports-file-writer.js +3 -3
package/oro-webpack-config.js
CHANGED
|
@@ -14,14 +14,17 @@ const ModulesConfigLoader = require('./modules-config/modules-config-loader');
|
|
|
14
14
|
const DynamicImportsFileWriter = require('./writer/dynamic-imports-file-writer');
|
|
15
15
|
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
|
16
16
|
const prepareModulesShim = require('./prepare-modules-shim');
|
|
17
|
-
const
|
|
17
|
+
const AdminStyleLoader = require('./style/admin-style-loader');
|
|
18
18
|
const ThemeConfigFactory = require('./theme-config-factory');
|
|
19
19
|
const path = require('path');
|
|
20
|
+
const fs = require('fs');
|
|
20
21
|
const prepareModulesMap = require('./plugin/map/prepare-modules-map');
|
|
21
22
|
const resolve = require('enhanced-resolve');
|
|
22
23
|
const {merge: webpackMerge} = require('webpack-merge');
|
|
23
24
|
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
|
24
25
|
const RtlCssWebpackPlugin = require('rtlcss-webpack-plugin');
|
|
26
|
+
const {red: colorRed} = require('colorette');
|
|
27
|
+
require('resolve-url-loader');
|
|
25
28
|
|
|
26
29
|
class ConfigBuilder {
|
|
27
30
|
constructor() {
|
|
@@ -29,18 +32,18 @@ class ConfigBuilder {
|
|
|
29
32
|
this._adminTheme = 'admin.oro';
|
|
30
33
|
this._enableLayoutThemes = false;
|
|
31
34
|
this._defaultLayoutThemes = null;
|
|
32
|
-
this._versionFormat = '%s?
|
|
35
|
+
this._versionFormat = '%s?v=%s';
|
|
33
36
|
this._babelConfig = {
|
|
34
37
|
sourceType: 'unambiguous',
|
|
35
38
|
presets: [
|
|
36
39
|
[
|
|
37
40
|
'@babel/preset-env', {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
41
|
+
useBuiltIns: 'usage',
|
|
42
|
+
corejs: {
|
|
43
|
+
version: 3,
|
|
44
|
+
proposals: true
|
|
43
45
|
}
|
|
46
|
+
}
|
|
44
47
|
]
|
|
45
48
|
],
|
|
46
49
|
plugins: [
|
|
@@ -71,7 +74,7 @@ class ConfigBuilder {
|
|
|
71
74
|
|
|
72
75
|
/**
|
|
73
76
|
* Specifies a sprintf pattern that will be used with the version option to construct an asset’s path.
|
|
74
|
-
* By default ts `%s?
|
|
77
|
+
* By default ts `%s?v=%s`
|
|
75
78
|
* @param {string} versionFormat
|
|
76
79
|
* @returns {ConfigBuilder}
|
|
77
80
|
*/
|
|
@@ -125,310 +128,365 @@ class ConfigBuilder {
|
|
|
125
128
|
return (env = {}, args = {}) => {
|
|
126
129
|
this._initialize(args, env);
|
|
127
130
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (selectedTheme === undefined) {
|
|
135
|
-
// themes.push(this._adminTheme.split(".")[1]);
|
|
136
|
-
themes.push(this._adminTheme);
|
|
137
|
-
} else if (this._adminThemes.indexOf(selectedTheme) !== -1) {
|
|
138
|
-
// themes.push(selectedTheme.split(".")[1]);
|
|
139
|
-
themes.push(selectedTheme);
|
|
131
|
+
let commonConfig = {};
|
|
132
|
+
try {
|
|
133
|
+
commonConfig = this._getCommonWebpackConfig(args, env);
|
|
134
|
+
} catch (e) {
|
|
135
|
+
console.error(colorRed(`Error: ${e.message}`));
|
|
136
|
+
process.exit(1);
|
|
140
137
|
}
|
|
141
138
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
139
|
+
const webpackConfigs = [];
|
|
140
|
+
const requestedBuildNames = env.theme ? env.theme.split(',') : [];
|
|
141
|
+
const buildNames = this._getBuildNames(requestedBuildNames);
|
|
142
|
+
buildNames.forEach(buildName => {
|
|
143
|
+
let buildConfig;
|
|
144
|
+
try {
|
|
145
|
+
buildConfig = this._getThemeWebpackConfig(buildName, args, env);
|
|
146
|
+
} catch (e) {
|
|
147
|
+
console.error(colorRed(`Error: ${e.message}`));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (buildConfig) {
|
|
152
|
+
webpackConfigs.push(webpackMerge(buildConfig, commonConfig));
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
return webpackConfigs;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
get resolvedPublicPath() {
|
|
161
|
+
if (this._resolvedPublicPath === undefined) {
|
|
162
|
+
this._resolvedPublicPath = path.resolve(this._publicPath);
|
|
163
|
+
}
|
|
164
|
+
return this._resolvedPublicPath;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
get resolvedNodeModulesPath() {
|
|
168
|
+
if (this._resolvedNodeModulesPath === undefined) {
|
|
169
|
+
this._resolvedNodeModulesPath = path.resolve('node_modules');
|
|
170
|
+
}
|
|
171
|
+
return this._resolvedNodeModulesPath;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
get assetVersion() {
|
|
175
|
+
if (this._assetVersion === undefined) {
|
|
176
|
+
const filePath = path.join(this.resolvedPublicPath, '/build/build_version.txt');
|
|
177
|
+
this._assetVersion = fs.existsSync(filePath) ? String(fs.readFileSync(filePath)) : null;
|
|
178
|
+
}
|
|
179
|
+
return this._assetVersion;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
_getBuildNames(requestedBuildNames = []) {
|
|
183
|
+
const buildNames = [];
|
|
184
|
+
requestedBuildNames.forEach(buildName => this._validateBuildName(buildName));
|
|
185
|
+
|
|
186
|
+
// Admin themes
|
|
187
|
+
if (!requestedBuildNames.length) {
|
|
188
|
+
buildNames.push(this._adminTheme);
|
|
189
|
+
} else {
|
|
190
|
+
requestedBuildNames.forEach(buildName => {
|
|
191
|
+
if (this._isAdminTheme(buildName)) {
|
|
192
|
+
buildNames.push(buildName);
|
|
154
193
|
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Layout Themes
|
|
198
|
+
if (this._enableLayoutThemes) {
|
|
199
|
+
if (!requestedBuildNames.length) {
|
|
200
|
+
// build all layout themes
|
|
201
|
+
const themes = this._defaultLayoutThemes || this._appConfig.themes;
|
|
202
|
+
buildNames.push(...themes);
|
|
203
|
+
themes.forEach(theme => {
|
|
204
|
+
buildNames.push(...this._layoutModulesConfigLoader.extraJSBuildNames(theme));
|
|
205
|
+
});
|
|
206
|
+
} else {
|
|
207
|
+
// build single layout theme
|
|
208
|
+
requestedBuildNames.forEach(buildName => {
|
|
209
|
+
if (this._layoutModulesConfigLoader.buildNames.includes(buildName)) {
|
|
210
|
+
buildNames.push(buildName);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
155
213
|
}
|
|
214
|
+
}
|
|
156
215
|
|
|
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
|
-
reuseExistingChunk: true
|
|
197
|
-
},
|
|
198
|
-
tinymce: {
|
|
199
|
-
test: /tinymce/,
|
|
200
|
-
name: 'tinymce.min',
|
|
201
|
-
minChunks: 1
|
|
202
|
-
},
|
|
203
|
-
fusioncharts: {
|
|
204
|
-
test: /fusioncharts/,
|
|
205
|
-
name: 'fusioncharts',
|
|
206
|
-
minChunks: 1
|
|
207
|
-
}
|
|
208
|
-
}
|
|
216
|
+
return buildNames;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
_getCommonWebpackConfig(args, env) {
|
|
220
|
+
const stats = env.stats || {
|
|
221
|
+
hash: false,
|
|
222
|
+
version: false,
|
|
223
|
+
// Do not write the information about files emitted from node_modules or public bundles,
|
|
224
|
+
// and hide css/*/*.js files from the output.
|
|
225
|
+
excludeAssets: [/^bundles\//, /^\.\.\/_static\//, /^css\/.+\.js/],
|
|
226
|
+
children: false,
|
|
227
|
+
entrypoints: false,
|
|
228
|
+
performance: this._isProduction,
|
|
229
|
+
chunks: false,
|
|
230
|
+
modules: false,
|
|
231
|
+
source: false,
|
|
232
|
+
publicPath: true,
|
|
233
|
+
builtAt: false,
|
|
234
|
+
warnings: false
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const webpackConfig = {
|
|
238
|
+
watchOptions: {
|
|
239
|
+
aggregateTimeout: 200,
|
|
240
|
+
ignored: /[\/\\]node_modules[\/\\].*\.js$/
|
|
241
|
+
},
|
|
242
|
+
stats,
|
|
243
|
+
output: {
|
|
244
|
+
filename: '[name].js',
|
|
245
|
+
// Because we use third party libraries 'chunkFilename' should include only [name]
|
|
246
|
+
chunkFilename: this._getVersionedPath('chunk/[name].js', this.assetVersion)
|
|
247
|
+
},
|
|
248
|
+
devtool: !env.skipSourcemap && 'inline-cheap-module-source-map',
|
|
249
|
+
mode: 'development',
|
|
250
|
+
optimization: {
|
|
251
|
+
moduleIds: 'named',
|
|
252
|
+
splitChunks: {
|
|
253
|
+
cacheGroups: {
|
|
254
|
+
defaultVendors: false
|
|
209
255
|
}
|
|
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
|
-
sassOptions: {
|
|
248
|
-
includePaths: [
|
|
249
|
-
resolvedPublicPath + '/bundles'
|
|
250
|
-
],
|
|
251
|
-
outputStyle: 'expanded'
|
|
252
|
-
},
|
|
253
|
-
sourceMap: true
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
resolveLoader: {
|
|
259
|
+
modules: [
|
|
260
|
+
this.resolvedPublicPath,
|
|
261
|
+
path.join(__dirname, './loader'),
|
|
262
|
+
path.join(this.resolvedPublicPath, '/bundles'),
|
|
263
|
+
this.resolvedNodeModulesPath
|
|
264
|
+
]
|
|
265
|
+
},
|
|
266
|
+
module: {
|
|
267
|
+
noParse: [
|
|
268
|
+
/[\/\\]bundles[\/\\]\.*[\/\\]lib[\/\\](?!chaplin|bootstrap|jquery\.dialog).*\.js$/
|
|
269
|
+
],
|
|
270
|
+
rules: [
|
|
271
|
+
{
|
|
272
|
+
test: /\.s?css$/,
|
|
273
|
+
use: [{
|
|
274
|
+
loader: args.hot ? 'style-loader' : MiniCssExtractPlugin.loader
|
|
275
|
+
}, {
|
|
276
|
+
loader: 'css-loader',
|
|
277
|
+
options: {
|
|
278
|
+
importLoaders: 1,
|
|
279
|
+
sourceMap: true,
|
|
280
|
+
// can't use esModule since resolve-url-loader needs file path to start with '~'
|
|
281
|
+
esModule: false
|
|
282
|
+
}
|
|
283
|
+
}, {
|
|
284
|
+
loader: 'resolve-url-loader'
|
|
285
|
+
}, {
|
|
286
|
+
loader: 'postcss-loader',
|
|
287
|
+
options: {
|
|
288
|
+
sourceMap: true,
|
|
289
|
+
postcssOptions: {
|
|
290
|
+
plugins: [
|
|
291
|
+
require('autoprefixer')
|
|
292
|
+
]
|
|
254
293
|
}
|
|
255
|
-
}
|
|
256
|
-
},
|
|
257
|
-
|
|
258
|
-
test: /\.(eot|ttf|woff|woff2|cur|ico|svg|png|jpg|gif)$/,
|
|
259
|
-
loader: 'url-loader',
|
|
294
|
+
}
|
|
295
|
+
}, {
|
|
296
|
+
loader: 'sass-loader',
|
|
260
297
|
options: {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
298
|
+
sassOptions: {
|
|
299
|
+
includePaths: [
|
|
300
|
+
path.join(this.resolvedPublicPath, '/bundles')
|
|
301
|
+
],
|
|
302
|
+
outputStyle: 'expanded'
|
|
303
|
+
},
|
|
304
|
+
sourceMap: true
|
|
266
305
|
}
|
|
306
|
+
}]
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
test: /\.(eot|ttf|woff|woff2|cur|ico|svg|png|jpg|gif)$/,
|
|
310
|
+
loader: 'url-loader',
|
|
311
|
+
options: {
|
|
312
|
+
limit: 1,
|
|
313
|
+
emitFile: true,
|
|
314
|
+
outputPath: '../_static/',
|
|
315
|
+
publicPath: '../../_static/',
|
|
316
|
+
name: this._getVersionedPath('[path][name].[ext]', this.assetVersion)
|
|
267
317
|
}
|
|
268
|
-
|
|
269
|
-
},
|
|
270
|
-
performance: {hints: false},
|
|
271
|
-
plugins: [
|
|
272
|
-
new MiniCssExtractPlugin({
|
|
273
|
-
filename: '[name].css'
|
|
274
|
-
}),
|
|
275
|
-
new CleanupStatsPlugin(),
|
|
276
|
-
// Ignore all locale files of moment.js
|
|
277
|
-
new webpack.IgnorePlugin({
|
|
278
|
-
resourceRegExp: /^\.[\/\\]locale$/,
|
|
279
|
-
contextRegExp: /moment$/
|
|
280
|
-
}),
|
|
281
|
-
new webpack.optimize.MinChunkSizePlugin({
|
|
282
|
-
minChunkSize: 30000 // Minimum number of characters
|
|
283
|
-
})
|
|
318
|
+
}
|
|
284
319
|
]
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
320
|
+
},
|
|
321
|
+
performance: {hints: false},
|
|
322
|
+
plugins: [
|
|
323
|
+
new MiniCssExtractPlugin({
|
|
324
|
+
filename: '[name].css'
|
|
325
|
+
}),
|
|
326
|
+
new CleanupStatsPlugin(),
|
|
327
|
+
// Ignore all locale files of moment.js
|
|
328
|
+
new webpack.IgnorePlugin({
|
|
329
|
+
resourceRegExp: /^\.[\/\\]locale$/,
|
|
330
|
+
contextRegExp: /moment$/
|
|
331
|
+
}),
|
|
332
|
+
new webpack.optimize.MinChunkSizePlugin({
|
|
333
|
+
minChunkSize: 30000 // Minimum number of characters
|
|
334
|
+
})
|
|
335
|
+
]
|
|
336
|
+
};
|
|
290
337
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
loaders: [
|
|
295
|
-
{
|
|
296
|
-
loader: 'babel-loader',
|
|
297
|
-
options: this._babelConfig
|
|
298
|
-
}
|
|
299
|
-
]
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
webpackConfig.plugins.push(new HappyPack(happyPackOptions));
|
|
303
|
-
|
|
304
|
-
webpackConfig.module.rules.push({
|
|
305
|
-
test: /\.js$/,
|
|
306
|
-
exclude: [
|
|
307
|
-
/[\/\\]platform[\/\\]build[\/\\]/,
|
|
308
|
-
/[\/\\]node_modules[\/\\]/,
|
|
309
|
-
/[\/\\]bundles[\/\\].+[\/\\]lib[\/\\]?/
|
|
310
|
-
],
|
|
311
|
-
use: 'happypack/loader?id=babel'
|
|
312
|
-
});
|
|
313
|
-
}
|
|
338
|
+
if (env.analyze) {
|
|
339
|
+
webpackConfig.plugins.push(new BundleAnalyzerPlugin());
|
|
340
|
+
}
|
|
314
341
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
host: devServerHost,
|
|
323
|
-
port: devServerPort,
|
|
324
|
-
https: https,
|
|
325
|
-
compress: true,
|
|
326
|
-
stats: stats,
|
|
327
|
-
disableHostCheck: true,
|
|
328
|
-
clientLogLevel: 'error',
|
|
329
|
-
headers: {
|
|
330
|
-
'Access-Control-Allow-Origin': '*'
|
|
342
|
+
if (!env.skipJS && !env.skipBabel) {
|
|
343
|
+
const happyPackOptions = {
|
|
344
|
+
id: 'babel',
|
|
345
|
+
loaders: [
|
|
346
|
+
{
|
|
347
|
+
loader: 'babel-loader',
|
|
348
|
+
options: this._babelConfig
|
|
331
349
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
350
|
+
]
|
|
351
|
+
};
|
|
335
352
|
|
|
336
|
-
|
|
337
|
-
if (this._isProduction) {
|
|
338
|
-
webpackConfig = webpackMerge(webpackConfig, {
|
|
339
|
-
devtool: false,
|
|
353
|
+
webpackConfig.plugins.push(new HappyPack(happyPackOptions));
|
|
340
354
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
355
|
+
webpackConfig.module.rules.push({
|
|
356
|
+
test: /\.js$/,
|
|
357
|
+
exclude: [
|
|
358
|
+
/[\/\\]platform[\/\\]build[\/\\]/,
|
|
359
|
+
/[\/\\]node_modules[\/\\]/,
|
|
360
|
+
/[\/\\]bundles[\/\\].+[\/\\]lib[\/\\]?/
|
|
361
|
+
],
|
|
362
|
+
use: 'happypack/loader?id=babel'
|
|
363
|
+
});
|
|
364
|
+
}
|
|
348
365
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
const resolvedBuildPath = path.join(resolvedPublicPath, buildPublicPath);
|
|
366
|
-
|
|
367
|
-
const resolverConfig = {
|
|
368
|
-
modules: [
|
|
369
|
-
resolvedBuildPath,
|
|
370
|
-
resolvedPublicPath,
|
|
371
|
-
resolvedPublicPath + '/bundles',
|
|
372
|
-
resolvedPublicPath + '/js',
|
|
373
|
-
resolvedNodeModulesPath
|
|
374
|
-
],
|
|
375
|
-
alias: themeConfig.aliases,
|
|
376
|
-
symlinks: false
|
|
377
|
-
};
|
|
378
|
-
const resolver = (resolver => {
|
|
379
|
-
return moduleName => resolver({}, '', moduleName, {});
|
|
380
|
-
})(resolve.create.sync({...resolverConfig}));
|
|
381
|
-
|
|
382
|
-
const plugins = [];
|
|
383
|
-
if (rtlSupport && !env.skipCSS && !env.skipRTL) {
|
|
384
|
-
plugins.push(new RtlCssWebpackPlugin({
|
|
385
|
-
filename: '[name].rtl.css'
|
|
386
|
-
}));
|
|
366
|
+
if (args.hot) {
|
|
367
|
+
const https = this._appConfig.devServerOptions.https;
|
|
368
|
+
const schema = https ? 'https' : 'http';
|
|
369
|
+
const devServerHost = this._appConfig.devServerOptions.host;
|
|
370
|
+
const devServerPort = this._appConfig.devServerOptions.port;
|
|
371
|
+
webpackConfig.devServer = {
|
|
372
|
+
contentBase: this.resolvedPublicPath,
|
|
373
|
+
host: devServerHost,
|
|
374
|
+
port: devServerPort,
|
|
375
|
+
https: https,
|
|
376
|
+
compress: true,
|
|
377
|
+
stats: webpackConfig.stats,
|
|
378
|
+
disableHostCheck: true,
|
|
379
|
+
clientLogLevel: 'error',
|
|
380
|
+
headers: {
|
|
381
|
+
'Access-Control-Allow-Origin': '*'
|
|
387
382
|
}
|
|
383
|
+
};
|
|
384
|
+
webpackConfig.output.publicPath = `${schema}://${devServerHost}:${devServerPort}/`;
|
|
385
|
+
}
|
|
388
386
|
|
|
389
|
-
|
|
390
|
-
|
|
387
|
+
// Additional setting for production mode
|
|
388
|
+
if (this._isProduction) {
|
|
389
|
+
webpackConfig.devtool = false;
|
|
390
|
+
webpackConfig.plugins.push(new CssMinimizerPlugin());
|
|
391
|
+
}
|
|
391
392
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
webpackConfigs.push(webpackMerge({
|
|
397
|
-
entry: entryPoints,
|
|
398
|
-
name: theme + ' theme',
|
|
399
|
-
output: {
|
|
400
|
-
publicPath: buildPublicPath,
|
|
401
|
-
path: resolvedBuildPath
|
|
402
|
-
},
|
|
403
|
-
context: resolvedPublicPath,
|
|
404
|
-
resolve: {
|
|
405
|
-
...resolverConfig,
|
|
406
|
-
plugins: [
|
|
407
|
-
new MapModulesPlugin(prepareModulesMap(resolver, themeConfig.map))
|
|
408
|
-
]
|
|
409
|
-
},
|
|
410
|
-
plugins,
|
|
411
|
-
module: {
|
|
412
|
-
rules: [
|
|
413
|
-
{
|
|
414
|
-
test: /[\/\\]configs\.json$/,
|
|
415
|
-
loader: 'config-loader',
|
|
416
|
-
options: {
|
|
417
|
-
resolver,
|
|
418
|
-
relativeTo: resolvedPublicPath
|
|
419
|
-
}
|
|
420
|
-
},
|
|
421
|
-
...prepareModulesShim(resolver, themeConfig.shim)
|
|
422
|
-
]
|
|
423
|
-
}
|
|
424
|
-
}, webpackConfig));
|
|
425
|
-
});
|
|
393
|
+
return webpackConfig;
|
|
394
|
+
}
|
|
426
395
|
|
|
427
|
-
|
|
396
|
+
_getThemeWebpackConfig(buildName, args, env) {
|
|
397
|
+
let {skipCSS, skipJS, skipRTL} = env;
|
|
398
|
+
let themeDefinition;
|
|
399
|
+
let jsBuildConfig;
|
|
400
|
+
let buildPublicPath;
|
|
401
|
+
if (this._isAdminTheme(buildName)) {
|
|
402
|
+
themeDefinition = this._modulesConfigLoader.themes[buildName.split('.')[1]];
|
|
403
|
+
buildPublicPath = '/build/admin/';
|
|
404
|
+
const jsModulesConfig = this._themeConfigFactory.loadConfig(buildName,
|
|
405
|
+
['Resources/config/oro/jsmodules.yml', 'Resources/config/jsmodules.yml']);
|
|
406
|
+
jsBuildConfig = this._themeConfigFactory.create(buildPublicPath, jsModulesConfig);
|
|
407
|
+
} else if (this._layoutModulesConfigLoader.isExtraJSBuild(buildName)) {
|
|
408
|
+
const [theme, suffix] = this._layoutModulesConfigLoader.splitBuildName(buildName);
|
|
409
|
+
skipCSS = true;
|
|
410
|
+
themeDefinition = this._layoutModulesConfigLoader.themes[theme];
|
|
411
|
+
buildPublicPath = `/build/${buildName}/`;
|
|
412
|
+
const baseConfig = this._layoutThemeConfigFactory.loadConfig(theme, 'config/jsmodules.yml');
|
|
413
|
+
const extraConfig = this._layoutThemeConfigFactory.loadConfig(theme, `config/jsmodules-${suffix}.yml`);
|
|
414
|
+
const jsModulesConfig = this._layoutThemeConfigFactory.extendConfig(baseConfig, extraConfig);
|
|
415
|
+
jsBuildConfig = this._layoutThemeConfigFactory.create(buildPublicPath, jsModulesConfig);
|
|
416
|
+
} else {
|
|
417
|
+
themeDefinition = this._layoutModulesConfigLoader.themes[buildName];
|
|
418
|
+
buildPublicPath = `/build/${buildName}/`;
|
|
419
|
+
const jsModulesConfig = this._layoutThemeConfigFactory.loadConfig(buildName, 'config/jsmodules.yml');
|
|
420
|
+
jsBuildConfig = this._layoutThemeConfigFactory.create(buildPublicPath, jsModulesConfig);
|
|
421
|
+
}
|
|
422
|
+
const {rtl_support: rtlSupport = false} = themeDefinition;
|
|
423
|
+
const resolvedBuildPath = path.join(this.resolvedPublicPath, buildPublicPath);
|
|
424
|
+
|
|
425
|
+
const resolverConfig = {
|
|
426
|
+
modules: [
|
|
427
|
+
resolvedBuildPath,
|
|
428
|
+
this.resolvedPublicPath,
|
|
429
|
+
path.join(this.resolvedPublicPath, '/bundles'),
|
|
430
|
+
path.join(this.resolvedPublicPath, '/js'),
|
|
431
|
+
this.resolvedNodeModulesPath
|
|
432
|
+
],
|
|
433
|
+
alias: jsBuildConfig.aliases,
|
|
434
|
+
cacheWithContext: true,
|
|
435
|
+
symlinks: false
|
|
428
436
|
};
|
|
437
|
+
const resolver = (resolver => {
|
|
438
|
+
return moduleName => resolver({}, '', moduleName, {});
|
|
439
|
+
})(resolve.create.sync({...resolverConfig}));
|
|
440
|
+
|
|
441
|
+
const plugins = [];
|
|
442
|
+
if (rtlSupport && !skipCSS && !skipRTL) {
|
|
443
|
+
plugins.push(new RtlCssWebpackPlugin({
|
|
444
|
+
filename: '[name].rtl.css'
|
|
445
|
+
}));
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
const cssEntryPoints = !skipCSS ? this._getCssEntryPoints(buildName, buildPublicPath) : {};
|
|
449
|
+
const jsEntryPoints = !skipJS ? jsBuildConfig.entry : {};
|
|
450
|
+
|
|
451
|
+
const entryPoints = {...cssEntryPoints, ...jsEntryPoints};
|
|
452
|
+
if (Object.keys(entryPoints).length === 0) {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
return {
|
|
457
|
+
entry: entryPoints,
|
|
458
|
+
name: buildName + ' theme',
|
|
459
|
+
output: {
|
|
460
|
+
publicPath: buildPublicPath,
|
|
461
|
+
path: resolvedBuildPath
|
|
462
|
+
},
|
|
463
|
+
context: this.resolvedPublicPath,
|
|
464
|
+
resolve: {
|
|
465
|
+
...resolverConfig,
|
|
466
|
+
plugins: [
|
|
467
|
+
new MapModulesPlugin(prepareModulesMap(resolver, jsBuildConfig.map))
|
|
468
|
+
]
|
|
469
|
+
},
|
|
470
|
+
plugins,
|
|
471
|
+
module: {
|
|
472
|
+
rules: [
|
|
473
|
+
{
|
|
474
|
+
test: /[\/\\]configs\.json$/,
|
|
475
|
+
loader: 'config-loader',
|
|
476
|
+
options: {
|
|
477
|
+
resolver,
|
|
478
|
+
relativeTo: this.resolvedPublicPath
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
...prepareModulesShim(resolver, jsBuildConfig.shim)
|
|
482
|
+
]
|
|
483
|
+
}
|
|
484
|
+
}
|
|
429
485
|
}
|
|
430
486
|
|
|
431
487
|
_initialize(args, env) {
|
|
488
|
+
const entryPointFileWriter = new EntryPointFileWriter(this._publicPath);
|
|
489
|
+
|
|
432
490
|
this._isProduction = args.mode === 'production';
|
|
433
491
|
this._symfonyEnv = env.symfony;
|
|
434
492
|
this._appConfig = AppConfigLoader.getConfig(this._cachePath, this._symfonyEnv);
|
|
@@ -439,7 +497,7 @@ class ConfigBuilder {
|
|
|
439
497
|
'settings.yml'
|
|
440
498
|
);
|
|
441
499
|
this._adminThemes = this._modulesConfigLoader.themeNames.map(themeName => 'admin.' + themeName);
|
|
442
|
-
this.
|
|
500
|
+
this._adminStyleLoader = new AdminStyleLoader(this._modulesConfigLoader, entryPointFileWriter);
|
|
443
501
|
this._themeConfigFactory = new ThemeConfigFactory(
|
|
444
502
|
this._modulesConfigLoader,
|
|
445
503
|
new DynamicImportsFileWriter(this._publicPath),
|
|
@@ -452,8 +510,6 @@ class ConfigBuilder {
|
|
|
452
510
|
'/Resources/views/layouts/',
|
|
453
511
|
'theme.yml'
|
|
454
512
|
);
|
|
455
|
-
this._layoutThemes = this._layoutModulesConfigLoader.themeNames;
|
|
456
|
-
const entryPointFileWriter = new EntryPointFileWriter(this._publicPath);
|
|
457
513
|
this._layoutStyleLoader = new LayoutStyleLoader(this._layoutModulesConfigLoader, entryPointFileWriter);
|
|
458
514
|
this._layoutThemeConfigFactory = new ThemeConfigFactory(
|
|
459
515
|
this._layoutModulesConfigLoader,
|
|
@@ -463,33 +519,40 @@ class ConfigBuilder {
|
|
|
463
519
|
);
|
|
464
520
|
}
|
|
465
521
|
|
|
522
|
+
_getVersionedPath(name, assetVersion) {
|
|
523
|
+
if(!assetVersion) {
|
|
524
|
+
return name;
|
|
525
|
+
}
|
|
526
|
+
return printf(this._versionFormat, name, assetVersion);
|
|
527
|
+
}
|
|
528
|
+
|
|
466
529
|
_getCssEntryPoints(theme, buildPath) {
|
|
467
530
|
if (this._isAdminTheme(theme)) {
|
|
468
|
-
return this.
|
|
531
|
+
return this._adminStyleLoader.getThemeEntryPoints(theme.split('.')[1], buildPath);
|
|
469
532
|
}
|
|
470
533
|
|
|
471
534
|
return this._layoutStyleLoader.getThemeEntryPoints(theme, buildPath);
|
|
472
535
|
}
|
|
473
536
|
|
|
474
|
-
|
|
475
|
-
|
|
537
|
+
_validateBuildName(buildName) {
|
|
538
|
+
const buildNames = [...this._adminThemes];
|
|
476
539
|
if (this._enableLayoutThemes) {
|
|
477
|
-
|
|
540
|
+
buildNames.push(...this._layoutModulesConfigLoader.buildNames);
|
|
478
541
|
}
|
|
479
|
-
if (
|
|
542
|
+
if (buildName === 'admin') {
|
|
480
543
|
throw new Error(
|
|
481
544
|
'The "admin" is a reserved word and cannot be used as a theme name.'
|
|
482
545
|
);
|
|
483
546
|
}
|
|
484
|
-
if (
|
|
547
|
+
if (buildName !== undefined && !buildNames.includes(buildName)) {
|
|
485
548
|
throw new Error(
|
|
486
|
-
'Theme "' +
|
|
549
|
+
'Theme "' + buildName + '" doesn\'t exists. Existing themes:' + buildNames.join(', ')
|
|
487
550
|
);
|
|
488
551
|
}
|
|
489
552
|
}
|
|
490
553
|
|
|
491
554
|
_isAdminTheme(theme) {
|
|
492
|
-
return this._adminThemes.
|
|
555
|
+
return this._adminThemes.includes(theme);
|
|
493
556
|
}
|
|
494
557
|
}
|
|
495
558
|
|