@zohodesk/react-cli 1.1.11 → 1.1.13
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 +19 -0
- package/lib/pluginUtils/getDevPlugins.js +5 -0
- package/lib/pluginUtils/getProdPlugins.js +20 -2
- package/lib/plugins/EfcResourceCleanupPlugin.js +43 -0
- package/lib/plugins/StatsPlugin.js +82 -0
- package/lib/schemas/index.js +9 -0
- package/lib/utils/getOptions.js +2 -1
- package/lib/utils/object-manipulation.js +88 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,6 +44,25 @@ Now to run app
|
|
|
44
44
|
|
|
45
45
|
# Change Logs
|
|
46
46
|
|
|
47
|
+
# 1.1.13 (4-9-2023)
|
|
48
|
+
|
|
49
|
+
**Changes**
|
|
50
|
+
|
|
51
|
+
- Fixed the issue related to the resource cleanup plugin. (EfcResouceCleanupPlugin)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# 1.1.12 (1-9-2023)
|
|
55
|
+
|
|
56
|
+
**Features**
|
|
57
|
+
|
|
58
|
+
- Generating stats.json file for the build assets only in production mode. To use this feature we need to add `stats > enable` or cli flags `enable_stats`.
|
|
59
|
+
- Added Resource Cleanup plugin to cleanup resource retained by build tool. this plugin is controlled by custom attributes enable flag.
|
|
60
|
+
|
|
61
|
+
**Changes**
|
|
62
|
+
|
|
63
|
+
- Added a new config `stats` to control stats file generation.
|
|
64
|
+
- Using Existing custom attributes flag, we can control resource cleanup plugin.
|
|
65
|
+
|
|
47
66
|
# 1.1.11 (4-8-2023)
|
|
48
67
|
|
|
49
68
|
**Changes**
|
|
@@ -35,6 +35,8 @@ var _SelectorPlugin = _interopRequireDefault(require("../plugins/SelectorPlugin"
|
|
|
35
35
|
|
|
36
36
|
var _configHtmlWebpackPlugins = require("./configHtmlWebpackPlugins");
|
|
37
37
|
|
|
38
|
+
var _EfcResourceCleanupPlugin = _interopRequireDefault(require("../plugins/EfcResourceCleanupPlugin"));
|
|
39
|
+
|
|
38
40
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
39
41
|
|
|
40
42
|
// import { windowsModification } from '../loaderUtils/windowsModification';
|
|
@@ -191,6 +193,9 @@ const getDevPlugins = (options, publicPath) => {
|
|
|
191
193
|
}));
|
|
192
194
|
instrumentScript && pluginsArr.push(new _plugins.ScriptInstrumentPlugin());
|
|
193
195
|
customAttributes.enable && pluginsArr.push(new _CustomAttributePlugin.CustomAttributePlugin(customAttributes));
|
|
196
|
+
customAttributes.enable && pluginsArr.push(new _EfcResourceCleanupPlugin.default(Object.assign({}, customAttributes, {
|
|
197
|
+
globalCacheObj: context
|
|
198
|
+
})));
|
|
194
199
|
hasShadowDOM && pluginsArr.push(new _plugins.ShadowDOMSupportPlugin());
|
|
195
200
|
|
|
196
201
|
if (devCssFileBountry) {
|
|
@@ -35,6 +35,10 @@ var _RtlCssPlugin = require("../plugins/RtlSplitPlugin/RtlCssPlugin");
|
|
|
35
35
|
|
|
36
36
|
var _configHtmlWebpackPlugins = require("./configHtmlWebpackPlugins");
|
|
37
37
|
|
|
38
|
+
var _StatsPlugin = _interopRequireDefault(require("../plugins/StatsPlugin"));
|
|
39
|
+
|
|
40
|
+
var _EfcResourceCleanupPlugin = _interopRequireDefault(require("../plugins/EfcResourceCleanupPlugin"));
|
|
41
|
+
|
|
38
42
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
39
43
|
|
|
40
44
|
// eslint-disable-next-line no-unused-vars
|
|
@@ -88,6 +92,12 @@ const getProdPlugins = (options, publicPath = '') => {
|
|
|
88
92
|
templateFilePath,
|
|
89
93
|
localeAttr: efcLocaleAttr
|
|
90
94
|
} = options.efc;
|
|
95
|
+
const {
|
|
96
|
+
enable: enableStats,
|
|
97
|
+
options: statsOptions,
|
|
98
|
+
excludeKeys: statsOutputExcludeKeys,
|
|
99
|
+
fileName: statsFileName
|
|
100
|
+
} = options.stats;
|
|
91
101
|
const hasEFC = newOptionForEnableEFC || prevOptionForEnableEFC;
|
|
92
102
|
const hashTempalate = enableChunkHash ? '.[chunkhash:20]_' : '';
|
|
93
103
|
const cssLTRFileNameTempalte = `css/[name]${hashTempalate}${enableRTLSplit ? '.ltr' : ''}.css`;
|
|
@@ -227,9 +237,9 @@ const getProdPlugins = (options, publicPath = '') => {
|
|
|
227
237
|
if (bundleAnalyze) {
|
|
228
238
|
pluginsArr.push(new _webpackBundleAnalyzer.BundleAnalyzerPlugin({
|
|
229
239
|
analyzerMode: 'static',
|
|
230
|
-
generateStatsFile:
|
|
240
|
+
generateStatsFile: !enableStats,
|
|
231
241
|
openAnalyzer: false,
|
|
232
|
-
statsOptions: {
|
|
242
|
+
statsOptions: enableStats ? null : {
|
|
233
243
|
source: false,
|
|
234
244
|
normal: true,
|
|
235
245
|
chunks: false,
|
|
@@ -288,6 +298,14 @@ const getProdPlugins = (options, publicPath = '') => {
|
|
|
288
298
|
|
|
289
299
|
|
|
290
300
|
customAttributes.enable && pluginsArr.push(new _CustomAttributePlugin.CustomAttributePlugin(customAttributes));
|
|
301
|
+
customAttributes.enable && pluginsArr.push(new _EfcResourceCleanupPlugin.default(Object.assign({}, customAttributes, {
|
|
302
|
+
globalCacheObj: context
|
|
303
|
+
})));
|
|
304
|
+
enableStats && pluginsArr.push(new _StatsPlugin.default({
|
|
305
|
+
statsOptions,
|
|
306
|
+
statsOutputExcludeKeys,
|
|
307
|
+
statsFileName
|
|
308
|
+
}));
|
|
291
309
|
return pluginsArr;
|
|
292
310
|
};
|
|
293
311
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
Template
|
|
5
|
+
} = require('webpack');
|
|
6
|
+
|
|
7
|
+
const plugInName = 'EFCResourceCleanup';
|
|
8
|
+
module.exports = class EfcResouceCleanupPlugin {
|
|
9
|
+
constructor(options) {
|
|
10
|
+
this.options = options;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
apply(compiler) {
|
|
14
|
+
compiler.hooks.thisCompilation.tap(plugInName, ({
|
|
15
|
+
mainTemplate
|
|
16
|
+
}) => {
|
|
17
|
+
mainTemplate.hooks.afterStartup.tap(plugInName, source => {
|
|
18
|
+
const {
|
|
19
|
+
attributes,
|
|
20
|
+
globalCacheObj
|
|
21
|
+
} = this.options;
|
|
22
|
+
const attributesArr = Object.entries(attributes);
|
|
23
|
+
const [[attributekey, attributeValue]] = attributesArr;
|
|
24
|
+
const resourceSelector = `[${attributekey}="${attributeValue}"]`;
|
|
25
|
+
return Template.asString([source, Template.indent([` window['${globalCacheObj}Jsonp'].unInstall = function() {
|
|
26
|
+
Object.keys(installedModules).forEach(installedModulesKey => installedModules[installedModulesKey] = null);
|
|
27
|
+
Object.keys(modules).forEach(moduleKey => modules[moduleKey] = null);
|
|
28
|
+
`, `
|
|
29
|
+
installedModules = null;
|
|
30
|
+
modules = null;
|
|
31
|
+
__webpack_require__.m = null;
|
|
32
|
+
__webpack_require__.c = null;
|
|
33
|
+
|
|
34
|
+
`, attributekey && attributeValue ? `
|
|
35
|
+
const addedResources = document.querySelectorAll('${resourceSelector}');
|
|
36
|
+
addedResources.forEach(addedResource => addedResource.remove());
|
|
37
|
+
}
|
|
38
|
+
` : ''])]);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
Readable
|
|
9
|
+
} = require('stream');
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
removeKeysFromObject,
|
|
13
|
+
convertObjectToStringGen
|
|
14
|
+
} = require('../utils/object-manipulation');
|
|
15
|
+
|
|
16
|
+
const pluginName = 'stats-plugin';
|
|
17
|
+
const statsSchema = {
|
|
18
|
+
all: true
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
class StatsPlugin {
|
|
22
|
+
constructor({
|
|
23
|
+
statsOptions,
|
|
24
|
+
statsOutputExcludeKeys,
|
|
25
|
+
statsFileName
|
|
26
|
+
}) {
|
|
27
|
+
this.excludeKeysInStat = statsOutputExcludeKeys || [];
|
|
28
|
+
this.statsFileName = statsFileName || 'bundle-report-integrity.json';
|
|
29
|
+
this.statsOptions = Object.assign({}, statsSchema, statsOptions || {});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
apply(compiler) {
|
|
33
|
+
compiler.hooks.done.tapAsync(pluginName, (stats, callback) => {
|
|
34
|
+
const statsJson = removeKeysFromObject(stats.toJson(this.statsOptions), this.excludeKeysInStat);
|
|
35
|
+
this.emitStats(statsJson).on('end', () => {
|
|
36
|
+
callback();
|
|
37
|
+
}).on('error', e => {
|
|
38
|
+
callback(e);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
writeStatsFileInAStream(statsObj) {
|
|
44
|
+
const {
|
|
45
|
+
outputPath
|
|
46
|
+
} = statsObj;
|
|
47
|
+
const ouputFileName = path.join(outputPath, this.statsFileName);
|
|
48
|
+
return this.createReadStream(statsObj).pipe(fs.createWriteStream(ouputFileName));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
createReadStream(statsObj) {
|
|
52
|
+
const excludeKeys = this.excludeKeysInStat;
|
|
53
|
+
return new Readable({
|
|
54
|
+
read() {
|
|
55
|
+
let isDone = false;
|
|
56
|
+
const objToStringGen = convertObjectToStringGen(statsObj, excludeKeys);
|
|
57
|
+
|
|
58
|
+
while (!isDone) {
|
|
59
|
+
const {
|
|
60
|
+
done,
|
|
61
|
+
value
|
|
62
|
+
} = objToStringGen.next();
|
|
63
|
+
|
|
64
|
+
if (done) {
|
|
65
|
+
isDone = true;
|
|
66
|
+
this.push(null);
|
|
67
|
+
} else {
|
|
68
|
+
this.push(value);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
emitStats(statsJson) {
|
|
77
|
+
return this.writeStatsFileInAStream(statsJson);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = StatsPlugin;
|
package/lib/schemas/index.js
CHANGED
|
@@ -723,6 +723,15 @@ var _default = {
|
|
|
723
723
|
cli: 'module_mode'
|
|
724
724
|
},
|
|
725
725
|
disableES5Transpile: true
|
|
726
|
+
},
|
|
727
|
+
stats: {
|
|
728
|
+
enable: {
|
|
729
|
+
value: false,
|
|
730
|
+
cli: 'enable_stats'
|
|
731
|
+
},
|
|
732
|
+
fileName: null,
|
|
733
|
+
options: null,
|
|
734
|
+
excludeKeys: null
|
|
726
735
|
}
|
|
727
736
|
};
|
|
728
737
|
exports.default = _default;
|
package/lib/utils/getOptions.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.default = void 0;
|
|
6
|
+
exports.defaulter = exports.default = void 0;
|
|
7
7
|
|
|
8
8
|
var _child_process = require("child_process");
|
|
9
9
|
|
|
@@ -132,6 +132,7 @@ const defaulter = (target, source) => {
|
|
|
132
132
|
return defaultObject;
|
|
133
133
|
};
|
|
134
134
|
|
|
135
|
+
exports.defaulter = defaulter;
|
|
135
136
|
global.reactCLIOptions = null;
|
|
136
137
|
|
|
137
138
|
const getOptionsFromConfigFile = (appPath, configFileName) => {
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.convertObjectToStringGen = convertObjectToStringGen;
|
|
7
|
+
exports.removeKeysFromObject = removeKeysFromObject;
|
|
8
|
+
|
|
9
|
+
function objectPathMatcher(currentKey, objHierarchy = [], keysToBeRemoved = []) {
|
|
10
|
+
const objPathKey = objHierarchy.length > 0 ? `${objHierarchy.join('.')}.${currentKey}` : currentKey;
|
|
11
|
+
return keysToBeRemoved.some(key => {
|
|
12
|
+
const isWildPath = /^\*/.test(key);
|
|
13
|
+
|
|
14
|
+
if (isWildPath) {
|
|
15
|
+
const newKey = key.replace(/\*\.?/, '');
|
|
16
|
+
return objPathKey.includes(newKey);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return key === objPathKey;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/*
|
|
23
|
+
1) *.keyTobeRemoved -> means match every object path, this key will be removed
|
|
24
|
+
2) keyToBeremoved -> means root object key
|
|
25
|
+
3) nestedPath.keyToBeRemoved -> means only that nested path key
|
|
26
|
+
4) don't need to account for array iteration, just object key path is enough in the key to be removed.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
function removeKeysFromObject(obj, keysToBeRemoved, prevKeys = []) {
|
|
31
|
+
if (Array.isArray(obj)) {
|
|
32
|
+
return obj.map(item => removeKeysFromObject(item, keysToBeRemoved, prevKeys));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (obj && typeof obj === 'object') {
|
|
36
|
+
const filteredKeyObject = {};
|
|
37
|
+
const ObjectKeys = Object.keys(obj);
|
|
38
|
+
|
|
39
|
+
for (const objectKey of ObjectKeys) {
|
|
40
|
+
const isKeyToBeRemoved = objectPathMatcher(objectKey, prevKeys, keysToBeRemoved);
|
|
41
|
+
|
|
42
|
+
if (!isKeyToBeRemoved) {
|
|
43
|
+
filteredKeyObject[objectKey] = removeKeysFromObject(obj[objectKey], keysToBeRemoved, [...prevKeys, objectKey]);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return filteredKeyObject;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return obj;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function* convertObjectToStringGen(obj) {
|
|
54
|
+
if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || obj === null) {
|
|
55
|
+
yield JSON.stringify(obj);
|
|
56
|
+
} else if (Array.isArray(obj)) {
|
|
57
|
+
yield '[';
|
|
58
|
+
let isFirst = true;
|
|
59
|
+
|
|
60
|
+
for (let item of obj) {
|
|
61
|
+
if (item === undefined) {
|
|
62
|
+
item = null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
yield `${isFirst ? '' : ','}`;
|
|
66
|
+
yield* convertObjectToStringGen(item);
|
|
67
|
+
isFirst = false;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
yield ']';
|
|
71
|
+
} else {
|
|
72
|
+
yield '{';
|
|
73
|
+
let isFirst = true;
|
|
74
|
+
const entries = Object.entries(obj);
|
|
75
|
+
|
|
76
|
+
for (const [itemKey, itemValue] of entries) {
|
|
77
|
+
if (itemValue === undefined) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
yield `${isFirst ? '' : ','}${JSON.stringify(itemKey)}: `;
|
|
82
|
+
yield* convertObjectToStringGen(itemValue);
|
|
83
|
+
isFirst = false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
yield '}';
|
|
87
|
+
}
|
|
88
|
+
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zohodesk/react-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.10",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@zohodesk/react-cli",
|
|
9
|
-
"version": "1.1.
|
|
9
|
+
"version": "1.1.10",
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@babel/cli": "7.10.5",
|