@oroinc/oro-webpack-config-builder 5.1.0-alpha8 → 5.1.0-lts001
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/error-handler.js +95 -0
- package/loader/config-loader.js +1 -2
- package/loader/inject-loader/LICENSE.md +21 -0
- package/loader/inject-loader/README.md +54 -0
- package/loader/inject-loader/index.js +10 -0
- package/loader/inject-loader/injectify.js +66 -0
- package/loader/inject-loader/package.json +55 -0
- package/loader/inject-loader/wrapper_template.js +32 -0
- package/modules-config/layout-modules-config-loader.js +66 -2
- package/modules-config/modules-config-loader.js +52 -19
- package/oro-webpack-config.js +416 -301
- package/package.json +37 -37
- package/plugin/logs/after-webpack-logs-plugin.js +25 -0
- package/style/admin-style-loader.js +23 -0
- package/style/layout-style-loader.js +12 -109
- package/style/style-loader.js +156 -46
- package/theme-config-factory.js +45 -6
- package/utils.js +30 -0
- package/validation/assets-validator.js +104 -0
- package/validation/errors/assets-input-file-error.js +24 -0
- package/validation/errors/assets-schema-error.js +40 -0
- package/validation/errors/base-error.js +37 -0
- package/validation/errors/jsmodules-extra-modules-error.js +22 -0
- package/validation/errors/jsmodules-schema-error.js +40 -0
- package/validation/errors/styles-error.js +24 -0
- package/validation/index.js +36 -0
- package/validation/jsmodules-validator.js +53 -0
- package/validation/schema-validator.js +62 -0
- package/validation/schemas/assets-schema-full.js +22 -0
- package/validation/schemas/assets-schema.js +32 -0
- package/validation/schemas/jsmodules-schema-full.js +11 -0
- package/validation/schemas/jsmodules-schema.js +76 -0
- package/writer/configs-file-writer.js +1 -1
- package/writer/dynamic-imports-file-writer.js +3 -3
- package/writer/scss-entry-point-file-writer.js +1 -1
package/package.json
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oroinc/oro-webpack-config-builder",
|
|
3
|
-
"version": "5.1.0-
|
|
3
|
+
"version": "5.1.0-lts001",
|
|
4
4
|
"author": "Oro, Inc (https://www.oroinc.com)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "An integration of OroPlatform based applications with the Webpack.",
|
|
7
7
|
"main": "oro-webpack-config.js",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@babel/core": "
|
|
10
|
-
"@babel/plugin-transform-runtime": "
|
|
11
|
-
"@babel/preset-env": "
|
|
12
|
-
"autoprefixer": "
|
|
13
|
-
"babel-loader": "
|
|
14
|
-
"bindings": "
|
|
15
|
-
"css-loader": "^
|
|
16
|
-
"css-minimizer-webpack-plugin": "
|
|
17
|
-
"deepmerge": "
|
|
18
|
-
"exports-loader": "
|
|
19
|
-
"expose-loader": "
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"minimist": "^1.2.3",
|
|
28
|
-
"nan": "^2.14.2",
|
|
9
|
+
"@babel/core": "~7.21.3",
|
|
10
|
+
"@babel/plugin-transform-runtime": "~7.21.0",
|
|
11
|
+
"@babel/preset-env": "~7.20.2",
|
|
12
|
+
"autoprefixer": "~10.4.13",
|
|
13
|
+
"babel-loader": "~9.1.0",
|
|
14
|
+
"bindings": "~1.5.0",
|
|
15
|
+
"css-loader": "^6.7.3",
|
|
16
|
+
"css-minimizer-webpack-plugin": "~4.2.2",
|
|
17
|
+
"deepmerge": "~4.3.1",
|
|
18
|
+
"exports-loader": "~4.0.0",
|
|
19
|
+
"expose-loader": "~4.1.0",
|
|
20
|
+
"file-loader": "~6.2.0",
|
|
21
|
+
"html-webpack-plugin": "~5.5.0",
|
|
22
|
+
"imports-loader": "~4.0.1",
|
|
23
|
+
"js-yaml": "~4.1.0",
|
|
24
|
+
"mini-css-extract-plugin": "~2.7.1",
|
|
25
|
+
"minimist": "~1.2.7",
|
|
26
|
+
"nan": "~2.17.0",
|
|
29
27
|
"path": "0.12.7",
|
|
30
|
-
"postcss": "
|
|
31
|
-
"postcss-loader": "
|
|
32
|
-
"printf": "
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"sass
|
|
36
|
-
"
|
|
37
|
-
"
|
|
28
|
+
"postcss": "~8.4.19",
|
|
29
|
+
"postcss-loader": "~7.1.0",
|
|
30
|
+
"printf": "~0.6.0",
|
|
31
|
+
"resolve-url-loader": "^5.0.0",
|
|
32
|
+
"rtlcss-webpack-plugin": "~4.0.6",
|
|
33
|
+
"sass": "~1.59.3",
|
|
34
|
+
"sass-loader": "~13.2.0",
|
|
35
|
+
"schema-utils": "^4.0.0",
|
|
36
|
+
"style-loader": "~3.3.1",
|
|
37
|
+
"terser": "~5.16.1",
|
|
38
38
|
"text-loader": "0.0.1",
|
|
39
|
-
"underscore": "
|
|
40
|
-
"url-loader": "
|
|
41
|
-
"webpack": "
|
|
42
|
-
"webpack-bundle-analyzer": "
|
|
43
|
-
"webpack-cli": "
|
|
44
|
-
"webpack-dev-server": "^
|
|
45
|
-
"webpack-merge": "
|
|
46
|
-
"wildcard": "
|
|
39
|
+
"underscore": "1.13.*",
|
|
40
|
+
"url-loader": "~4.1.1",
|
|
41
|
+
"webpack": "~5.76.3",
|
|
42
|
+
"webpack-bundle-analyzer": "~4.8.0",
|
|
43
|
+
"webpack-cli": "~5.0.0",
|
|
44
|
+
"webpack-dev-server": "^4.11.1",
|
|
45
|
+
"webpack-merge": "~5.8.0",
|
|
46
|
+
"wildcard": "~2.0.0"
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const {once} = require('underscore');
|
|
2
|
+
|
|
3
|
+
class AfterWebpackLogsPlugin {
|
|
4
|
+
/**
|
|
5
|
+
* @param {function} afterLogsCb
|
|
6
|
+
*/
|
|
7
|
+
constructor(afterLogsCb) {
|
|
8
|
+
if (typeof afterLogsCb !== 'function') {
|
|
9
|
+
throw new Error('The "afterLogsCb" arg should be a function');
|
|
10
|
+
}
|
|
11
|
+
this._afterLogsCb = once(afterLogsCb);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
apply(compiler) {
|
|
15
|
+
compiler.hooks.done.tap('AfterWebpackLogsPlugin', stats => {
|
|
16
|
+
const compilerStats = stats;
|
|
17
|
+
stats.compilation.hooks.statsPrinter.tap('AfterWebpackLogsPlugin', stats => {
|
|
18
|
+
// Making logs to be after all webpack logs in the console
|
|
19
|
+
setImmediate(() => this._afterLogsCb(compilerStats));
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = AfterWebpackLogsPlugin;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const merge = require('deepmerge');
|
|
2
|
+
const StyleLoader = require('./style-loader');
|
|
3
|
+
|
|
4
|
+
class AdminStyleLoader extends StyleLoader {
|
|
5
|
+
/**
|
|
6
|
+
* @inheritdoc
|
|
7
|
+
*/
|
|
8
|
+
_fetchThemeConfig(themeName) {
|
|
9
|
+
const {rtl_support: rtlSupport = false, styles: extraThemeConfig} =
|
|
10
|
+
this._configLoader.loadConfig(themeName, 'Resources/public/themes/' + themeName + '/settings.yml');
|
|
11
|
+
const baseThemeConfig = this._configLoader.loadConfig(themeName, 'Resources/config/oro/assets.yml');
|
|
12
|
+
const appRootExtraConfig = this._configLoader.loadConfig(themeName, 'config/oro/assets.yml');
|
|
13
|
+
/** @type {Object.<string, ThemeGroupConfig>} */
|
|
14
|
+
const themeConfig = merge(baseThemeConfig, appRootExtraConfig, extraThemeConfig);
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
themeConfig,
|
|
18
|
+
settings: {rtlSupport}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = AdminStyleLoader;
|
|
@@ -1,115 +1,18 @@
|
|
|
1
|
-
const
|
|
2
|
-
const wildcard = require('wildcard');
|
|
3
|
-
const _ = require('underscore')
|
|
1
|
+
const StyleLoader = require('./style-loader');
|
|
4
2
|
|
|
5
|
-
class LayoutStyleLoader {
|
|
3
|
+
class LayoutStyleLoader extends StyleLoader {
|
|
6
4
|
/**
|
|
7
|
-
* @
|
|
8
|
-
* @param {SCSSEntryPointFileWriter} entryPointFileWriter
|
|
5
|
+
* @inheritdoc
|
|
9
6
|
*/
|
|
10
|
-
|
|
11
|
-
this._configLoader
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
*/
|
|
20
|
-
getThemeEntryPoints(theme, buildPath) {
|
|
21
|
-
const entryPoints = {};
|
|
22
|
-
const {rtl_support: rtlSupport = false} = this._configLoader.themes[theme];
|
|
23
|
-
const themeConfig = this._configLoader.loadConfig(theme, 'config/assets.yml');
|
|
24
|
-
const writingOptions = {};
|
|
25
|
-
|
|
26
|
-
for (const [key, config] of Object.entries(themeConfig)) {
|
|
27
|
-
let {inputs, output, auto_rtl_inputs: rtlMasks = []} = config;
|
|
28
|
-
if (config.output === undefined) {
|
|
29
|
-
throw new Error('"output" for "' + key + '" group in theme "' + theme + '" is not defined');
|
|
30
|
-
}
|
|
31
|
-
inputs = this._overrideInputs(inputs);
|
|
32
|
-
inputs = this._sortInputs(inputs);
|
|
33
|
-
if (rtlSupport) {
|
|
34
|
-
writingOptions.ignoreRTLInputs = _.difference(inputs, this._matchInputs(rtlMasks, inputs));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const entryPointName = output.replace(/\.[^/.]+$/, '');
|
|
38
|
-
const filePath = path.join(buildPath, output);
|
|
39
|
-
entryPoints[entryPointName] =
|
|
40
|
-
this._entryPointFileWriter.write('./../../../', inputs, filePath, writingOptions);
|
|
41
|
-
}
|
|
42
|
-
return entryPoints;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* @param {Object} inputs
|
|
47
|
-
* @returns {string[]} List of inputs
|
|
48
|
-
* @private
|
|
49
|
-
*/
|
|
50
|
-
_overrideInputs(inputs) {
|
|
51
|
-
const newInputs = [];
|
|
52
|
-
|
|
53
|
-
inputs.forEach((input, index) => {
|
|
54
|
-
if (typeof input !== 'string') {
|
|
55
|
-
const oldInput = Object.keys(input)[0];
|
|
56
|
-
const newInput = input[oldInput];
|
|
57
|
-
const oldInputIndex = newInputs.findIndex(element => element === oldInput);
|
|
58
|
-
|
|
59
|
-
if (newInput) { // replace input
|
|
60
|
-
newInputs[oldInputIndex] = newInput;
|
|
61
|
-
} else { // delete input
|
|
62
|
-
newInputs.splice(oldInputIndex, 1);
|
|
63
|
-
}
|
|
64
|
-
newInputs.splice(index);
|
|
65
|
-
} else {
|
|
66
|
-
newInputs[index] = input;
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
return newInputs;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Sort inputs, so first will be settings, then variables, then other files
|
|
75
|
-
* @param {Object} inputs
|
|
76
|
-
* @returns {string[]} List of ordered inputs
|
|
77
|
-
* @private
|
|
78
|
-
*/
|
|
79
|
-
_sortInputs(inputs) {
|
|
80
|
-
const settingsInputs = [];
|
|
81
|
-
const variablesInputs = [];
|
|
82
|
-
const restInputs = [];
|
|
83
|
-
|
|
84
|
-
inputs.forEach(input => {
|
|
85
|
-
if (input.indexOf('/settings/') > 0) {
|
|
86
|
-
settingsInputs.push(input);
|
|
87
|
-
} else if (input.indexOf('/variables/') > 0) {
|
|
88
|
-
variablesInputs.push(input);
|
|
89
|
-
} else {
|
|
90
|
-
restInputs.push(input);
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
return [...settingsInputs, ...variablesInputs, ...restInputs];
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Filter inputs that matches any mask from the list
|
|
98
|
-
*
|
|
99
|
-
* @param {[string]} masks list of wildcard masks
|
|
100
|
-
* @param {[string]} inputs
|
|
101
|
-
* @return {[string]} matched inputs
|
|
102
|
-
* @private
|
|
103
|
-
*/
|
|
104
|
-
_matchInputs(masks, inputs) {
|
|
105
|
-
masks = masks.map(mask => wildcard(mask));
|
|
106
|
-
|
|
107
|
-
const whiteListedInputs = masks.reduce((include, mask) => {
|
|
108
|
-
include.push(...mask.match(inputs));
|
|
109
|
-
return include;
|
|
110
|
-
}, []);
|
|
111
|
-
|
|
112
|
-
return _.unique(whiteListedInputs);
|
|
7
|
+
_fetchThemeConfig(themeName) {
|
|
8
|
+
const {rtl_support: rtlSupport = false} = this._configLoader.themes[themeName];
|
|
9
|
+
/** @type {Object.<string, ThemeGroupConfig>} */
|
|
10
|
+
const themeConfig = this._configLoader.loadConfig(themeName, 'config/assets.yml');
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
themeConfig,
|
|
14
|
+
settings: {rtlSupport}
|
|
15
|
+
};
|
|
113
16
|
}
|
|
114
17
|
}
|
|
115
18
|
|
package/style/style-loader.js
CHANGED
|
@@ -1,78 +1,188 @@
|
|
|
1
|
-
const
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const wildcard = require('wildcard');
|
|
3
|
+
const _ = require('underscore');
|
|
4
|
+
const {isProdMode} = require('../utils');
|
|
5
|
+
const {assetsValidation} = require('../validation');
|
|
6
|
+
const StylesError = require('../validation/errors/styles-error');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef ThemeGroupConfig
|
|
10
|
+
* @type {Object}
|
|
11
|
+
* @property {Array.<string|Object>} inputs - list of input resources for import into root SCSS file
|
|
12
|
+
* @property {Array.<string>} entries - list of direct entry resources
|
|
13
|
+
* @property {string} output - name or out put resource
|
|
14
|
+
* @property {[boolean]} auto_rtl_inputs - whether theme support RTL
|
|
15
|
+
*/
|
|
2
16
|
|
|
3
17
|
class StyleLoader {
|
|
4
18
|
/**
|
|
5
19
|
* @param {YamlConfigLoader} configLoader
|
|
20
|
+
* @param {SCSSEntryPointFileWriter} entryPointFileWriter
|
|
6
21
|
*/
|
|
7
|
-
constructor(configLoader) {
|
|
22
|
+
constructor(configLoader, entryPointFileWriter) {
|
|
8
23
|
this._configLoader = configLoader;
|
|
24
|
+
this._entryPointFileWriter = entryPointFileWriter;
|
|
9
25
|
}
|
|
10
26
|
|
|
11
27
|
/**
|
|
12
28
|
* @param {string} theme Theme name
|
|
29
|
+
* @param {string} buildPath Build path
|
|
13
30
|
* @return {Object} List of Webpack entry-points
|
|
14
31
|
*/
|
|
15
|
-
getThemeEntryPoints(theme) {
|
|
32
|
+
getThemeEntryPoints(theme, buildPath) {
|
|
33
|
+
const {themeConfig, settings = {}} = this._fetchThemeConfig(theme);
|
|
34
|
+
|
|
35
|
+
assetsValidation.checkFullSchema(themeConfig, this._configLoader.processedFiles, theme);
|
|
36
|
+
|
|
16
37
|
const entryPoints = {};
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const config = themeConfig[key];
|
|
24
|
-
if (commonConfig[key]) {
|
|
25
|
-
commonConfig[key] = merge(commonConfig[key], config);
|
|
26
|
-
}
|
|
38
|
+
const writingOptions = {};
|
|
39
|
+
for (const [group, config] of Object.entries(themeConfig)) {
|
|
40
|
+
let {inputs, entries = [], output, auto_rtl_inputs: rtlMasks = []} = config;
|
|
41
|
+
|
|
42
|
+
if (isProdMode() && output === void 0) {
|
|
43
|
+
throw new StylesError('output', group, theme);
|
|
27
44
|
}
|
|
28
|
-
}
|
|
29
45
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const config = commonConfig[key];
|
|
33
|
-
const inputs = this._overrideInputs(config.inputs);
|
|
34
|
-
if (config.output === undefined) {
|
|
35
|
-
throw new Error('"output" for "' + key + '" group in theme "' + theme + '" is not defined');
|
|
36
|
-
}
|
|
37
|
-
entryPoints[config.output.replace(/\.[^/.]+$/, '')] = inputs;
|
|
46
|
+
if (isProdMode() && inputs === void 0) {
|
|
47
|
+
throw new StylesError('inputs', group, theme);
|
|
38
48
|
}
|
|
49
|
+
|
|
50
|
+
inputs = this._overrideInputs(inputs);
|
|
51
|
+
inputs = this._sortInputs(inputs);
|
|
52
|
+
inputs = this._applyInputsBasePathPrefix(inputs);
|
|
53
|
+
|
|
54
|
+
if (settings.rtlSupport) {
|
|
55
|
+
writingOptions.ignoreRTLInputs = _.difference(inputs, this._matchInputs(rtlMasks, inputs));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const entryPointName = output.replace(/\.[^/.]+$/, '');
|
|
59
|
+
const filePath = path.join(buildPath, output);
|
|
60
|
+
entryPoints[entryPointName] = [
|
|
61
|
+
...entries,
|
|
62
|
+
this._entryPointFileWriter.write('./../../', inputs, filePath, writingOptions)
|
|
63
|
+
];
|
|
39
64
|
}
|
|
40
65
|
return entryPoints;
|
|
41
66
|
}
|
|
42
67
|
|
|
43
68
|
/**
|
|
44
|
-
*
|
|
69
|
+
* Extracts theme configuration with its settings
|
|
70
|
+
*
|
|
71
|
+
* @param {string} themeName
|
|
72
|
+
* @return {{themeConfig: Object.<string, ThemeGroupConfig>, settings: {rtlSupport: boolean}}}
|
|
73
|
+
* @abstract
|
|
74
|
+
* @protected
|
|
75
|
+
*/
|
|
76
|
+
_fetchThemeConfig(themeName) {
|
|
77
|
+
throw new Error('Method `_fetchThemeConfig` has to be implemented in extends');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Override inputs
|
|
82
|
+
*
|
|
83
|
+
* @param {(string|Object)[]} inputs
|
|
45
84
|
* @returns {string[]} List of inputs
|
|
46
|
-
* @
|
|
85
|
+
* @protected
|
|
47
86
|
*/
|
|
48
87
|
_overrideInputs(inputs) {
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const oldInput = Object.keys(input)[0];
|
|
54
|
-
const newInput = input[oldInput];
|
|
55
|
-
const oldInputIndex = newInputs.findIndex(element => element === oldInput);
|
|
56
|
-
|
|
57
|
-
if (newInput) { // replace input
|
|
58
|
-
newInputs[oldInputIndex] = newInput;
|
|
59
|
-
} else { // delete input
|
|
60
|
-
newInputs.splice(oldInputIndex, 1);
|
|
61
|
-
}
|
|
62
|
-
newInputs.splice(index);
|
|
88
|
+
const mappedInputs = [];
|
|
89
|
+
inputs.forEach(input => {
|
|
90
|
+
if (typeof input === 'string') {
|
|
91
|
+
mappedInputs.push(input);
|
|
63
92
|
} else {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
93
|
+
const [oldInput, newInput] = Object.entries(input)[0];
|
|
94
|
+
const oldInputIndex = mappedInputs.findIndex(item => item === oldInput);
|
|
95
|
+
|
|
96
|
+
if (oldInputIndex === -1) {
|
|
97
|
+
// old input does not exist anymore
|
|
98
|
+
mappedInputs.push(newInput);
|
|
99
|
+
} else if (newInput) {
|
|
100
|
+
// replace input
|
|
101
|
+
mappedInputs[oldInputIndex] = newInput;
|
|
102
|
+
} else {
|
|
103
|
+
// delete input
|
|
104
|
+
mappedInputs.splice(oldInputIndex, 1);
|
|
70
105
|
}
|
|
71
|
-
newInputs.push(input);
|
|
72
106
|
}
|
|
73
107
|
});
|
|
108
|
+
return mappedInputs;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Sort inputs, so first will be settings, then variables, then other files
|
|
113
|
+
*
|
|
114
|
+
* @param {string[]} inputs
|
|
115
|
+
* @returns {string[]} List of ordered inputs
|
|
116
|
+
* @protected
|
|
117
|
+
*/
|
|
118
|
+
_sortInputs(inputs) {
|
|
119
|
+
const primarySettingsInputs = [];
|
|
120
|
+
const settingsInputs = [];
|
|
121
|
+
const primaryVariablesInputs = [];
|
|
122
|
+
const variablesInputs = [];
|
|
123
|
+
const restInputs = [];
|
|
124
|
+
|
|
125
|
+
inputs.forEach(input => {
|
|
126
|
+
if (input.indexOf('/settings/primary-settings') > 0) {
|
|
127
|
+
primarySettingsInputs.push(input);
|
|
128
|
+
} else if (input.indexOf('/settings/') > 0) {
|
|
129
|
+
settingsInputs.push(input);
|
|
130
|
+
} else if (input.indexOf('/variables/primary-variables') > 0) {
|
|
131
|
+
primaryVariablesInputs.push(input);
|
|
132
|
+
} else if (input.indexOf('/variables/') > 0) {
|
|
133
|
+
variablesInputs.push(input);
|
|
134
|
+
} else {
|
|
135
|
+
restInputs.push(input);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
return [
|
|
140
|
+
...primarySettingsInputs,
|
|
141
|
+
...settingsInputs,
|
|
142
|
+
...primaryVariablesInputs,
|
|
143
|
+
...variablesInputs,
|
|
144
|
+
...restInputs
|
|
145
|
+
];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Filter inputs that matches any mask from the list
|
|
150
|
+
*
|
|
151
|
+
* @param {string[]} masks list of wildcard masks
|
|
152
|
+
* @param {string[]} inputs
|
|
153
|
+
* @return {string[]} matched inputs
|
|
154
|
+
* @protected
|
|
155
|
+
*/
|
|
156
|
+
_matchInputs(masks, inputs) {
|
|
157
|
+
masks = this._applyInputsBasePathPrefix(masks);
|
|
158
|
+
masks = masks.map(mask => wildcard(mask));
|
|
159
|
+
|
|
160
|
+
const whiteListedInputs = masks.reduce((include, mask) => {
|
|
161
|
+
include.push(...mask.match(inputs));
|
|
162
|
+
return include;
|
|
163
|
+
}, []);
|
|
164
|
+
|
|
165
|
+
return _.unique(whiteListedInputs);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Considering base path as application's root.
|
|
170
|
+
* Bundles based *.scss sources go with '../' prefix.
|
|
171
|
+
*
|
|
172
|
+
* @param {string[]} inputs
|
|
173
|
+
* @private
|
|
174
|
+
*/
|
|
175
|
+
_applyInputsBasePathPrefix(inputs) {
|
|
176
|
+
const processedInputs = [];
|
|
177
|
+
|
|
178
|
+
inputs.forEach(input => {
|
|
179
|
+
if (input.indexOf('bundles') === 0) {
|
|
180
|
+
input = '../' + input;
|
|
181
|
+
}
|
|
182
|
+
processedInputs.push(input);
|
|
183
|
+
});
|
|
74
184
|
|
|
75
|
-
return
|
|
185
|
+
return processedInputs;
|
|
76
186
|
}
|
|
77
187
|
}
|
|
78
188
|
|
package/theme-config-factory.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const JSModulesExtraModulesError = require('./validation/errors/jsmodules-extra-modules-error');
|
|
2
|
+
|
|
1
3
|
class ThemeConfigFactory {
|
|
2
4
|
/**
|
|
3
5
|
* @param {ModulesConfigLoader} configLoader
|
|
@@ -11,22 +13,59 @@ class ThemeConfigFactory {
|
|
|
11
13
|
this._appModulesFileWriter = appModulesFileWriter;
|
|
12
14
|
this._configsFileWriter = configsFileWriter;
|
|
13
15
|
}
|
|
14
|
-
|
|
15
16
|
/**
|
|
16
17
|
* @param {string} theme Theme name
|
|
17
|
-
* @param {string} buildPath Path to theme build folder
|
|
18
18
|
* @param {string|string[]} configFilepath Path (or paths with fallback) to yaml config file in a bundle
|
|
19
|
-
* @return {Object}
|
|
19
|
+
* @return {Object} Merged Configs loaded from all the bundles Yaml files matched by filePath
|
|
20
|
+
*/
|
|
21
|
+
loadConfig(theme, configFilepath) {
|
|
22
|
+
return this._configLoader.loadConfig(theme, configFilepath);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
extendConfig(baseConfig, extraConfig) {
|
|
26
|
+
const {
|
|
27
|
+
aliases = {},
|
|
28
|
+
configs,
|
|
29
|
+
map = {},
|
|
30
|
+
shim = {}
|
|
31
|
+
} = baseConfig;
|
|
32
|
+
|
|
33
|
+
const {
|
|
34
|
+
['app-modules']: appModules,
|
|
35
|
+
['dynamic-imports']: dynamicImports,
|
|
36
|
+
entry,
|
|
37
|
+
...rest
|
|
38
|
+
} = extraConfig;
|
|
39
|
+
|
|
40
|
+
const beyondKeys = Object.keys(rest);
|
|
41
|
+
if (beyondKeys.length) {
|
|
42
|
+
throw new JSModulesExtraModulesError(beyondKeys);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
aliases,
|
|
47
|
+
'app-modules': appModules,
|
|
48
|
+
configs,
|
|
49
|
+
'dynamic-imports': dynamicImports,
|
|
50
|
+
entry,
|
|
51
|
+
map,
|
|
52
|
+
shim
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {string} buildPath Path to theme build folder
|
|
58
|
+
* @param {Object} jsModulesConfig configuration loaded from jsmodules files and merged together
|
|
59
|
+
* @return {Object} webpack configuration fragment
|
|
20
60
|
*/
|
|
21
|
-
create(
|
|
22
|
-
const jsModulesConfig = this._configLoader.loadConfig(theme, configFilepath);
|
|
61
|
+
create(buildPath, jsModulesConfig) {
|
|
23
62
|
const {
|
|
24
63
|
entry,
|
|
25
64
|
map = {},
|
|
26
65
|
shim = {},
|
|
27
66
|
configs,
|
|
28
67
|
aliases = {},
|
|
29
|
-
['app-modules']: appModules,
|
|
68
|
+
['app-modules']: appModules = [],
|
|
30
69
|
['dynamic-imports']: dynamicImports
|
|
31
70
|
} = jsModulesConfig;
|
|
32
71
|
|
package/utils.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
let prodMode;
|
|
2
|
+
let verboseMode;
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
isVerboseMode() {
|
|
6
|
+
if (verboseMode === void 0) {
|
|
7
|
+
verboseMode = process.argv.filter(arg => {
|
|
8
|
+
// Depending on how the command was run (-v, -vv, -vvv, --verbose) -
|
|
9
|
+
// arguments can be present in different formats: stats=normal, stats=detailed, stats=verbose, verbose
|
|
10
|
+
return arg.search(/^verbose|(^stats=(normal|detailed|verbose))/) !== -1;
|
|
11
|
+
}).length > 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return verboseMode;
|
|
15
|
+
},
|
|
16
|
+
isProdMode() {
|
|
17
|
+
if (prodMode !== void 0) {
|
|
18
|
+
return prodMode;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
process.argv.forEach(arg => {
|
|
22
|
+
if (prodMode) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
prodMode = ['--mode=production', '--env=prod'].some(item => item === arg);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return prodMode;
|
|
29
|
+
}
|
|
30
|
+
};
|