@zohodesk/react-cli 1.1.11 → 1.1.12
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 +45 -0
- package/lib/pluginUtils/getDevPlugins.js +3 -0
- package/lib/pluginUtils/getProdPlugins.js +18 -2
- package/lib/plugins/EfcResourceCleanupPlugin.js +39 -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,51 @@ Now to run app
|
|
44
44
|
|
45
45
|
# Change Logs
|
46
46
|
|
47
|
+
# 1.1.12
|
48
|
+
|
49
|
+
**Features**
|
50
|
+
- 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`.
|
51
|
+
- Added Resource Cleanup plugin to cleanup resource retained by build tool. this plugin is controlled by custom attributes enable flag.
|
52
|
+
|
53
|
+
**Changes**
|
54
|
+
- Added a new config `stats` to control stats file generation.
|
55
|
+
- Using Existing custom attributes flag, we can control resource cleanup plugin.
|
56
|
+
|
57
|
+
# 1.1.11-exp.6 (31-8-2023)
|
58
|
+
|
59
|
+
**Features**
|
60
|
+
|
61
|
+
- Added Resource Cleanup plugin to cleanup resource retained by build tool. this plugin is controlled by custom attributes enable flag.
|
62
|
+
|
63
|
+
**Changes**
|
64
|
+
|
65
|
+
- For stats plugin, added the separation of object manipulation method with converting object to string.
|
66
|
+
|
67
|
+
# 1.1.11-exp.3 (22-8-2023)
|
68
|
+
|
69
|
+
**Changes**
|
70
|
+
|
71
|
+
- Changed the default name of stats file to `build-report-integrity.json`
|
72
|
+
- Added optimization to reduce the stats file creation time. like streaming.
|
73
|
+
- Added support to exclude keys suggested
|
74
|
+
|
75
|
+
# 1.1.11-exp.2 (11-8-2023)
|
76
|
+
|
77
|
+
**Changes**
|
78
|
+
|
79
|
+
- Added more customization support for `stats.json` output.
|
80
|
+
- Disabling `bundle-analyser` stats report for our customized stats output based on a flag.
|
81
|
+
|
82
|
+
# 1.1.11-exp.1 (8-8-2023)
|
83
|
+
|
84
|
+
**Changes**
|
85
|
+
|
86
|
+
- Added a new config `stats` to control stats file generation.
|
87
|
+
|
88
|
+
**Features:-**
|
89
|
+
|
90
|
+
- 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`.
|
91
|
+
|
47
92
|
# 1.1.11 (4-8-2023)
|
48
93
|
|
49
94
|
**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,7 @@ 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(customAttributes));
|
194
197
|
hasShadowDOM && pluginsArr.push(new _plugins.ShadowDOMSupportPlugin());
|
195
198
|
|
196
199
|
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,12 @@ 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(customAttributes));
|
302
|
+
enableStats && pluginsArr.push(new _StatsPlugin.default({
|
303
|
+
statsOptions,
|
304
|
+
statsOutputExcludeKeys,
|
305
|
+
statsFileName
|
306
|
+
}));
|
291
307
|
return pluginsArr;
|
292
308
|
};
|
293
309
|
|
@@ -0,0 +1,39 @@
|
|
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 attributesArr = Object.entries(this.options.attributes);
|
19
|
+
const [[attributekey, attributeValue]] = attributesArr;
|
20
|
+
const resourceSelector = `[${attributekey}="${attributeValue}"]`;
|
21
|
+
return Template.asString([source, Template.indent([` jsonpArray.unInstall = function() {
|
22
|
+
Object.keys(installedModules).forEach(installedModulesKey => installedModules[installedModulesKey] = null);
|
23
|
+
Object.keys(modules).forEach(moduleKey => modules[moduleKey] = null);
|
24
|
+
`, `
|
25
|
+
installedModules = null;
|
26
|
+
modules = null;
|
27
|
+
__webpack_require__.m = null;
|
28
|
+
__webpack_require__.c = null;
|
29
|
+
|
30
|
+
`, `
|
31
|
+
const addedResources = document.querySelectorAll('${resourceSelector}');
|
32
|
+
addedResources.forEach(addedResource => addedResource.remove());
|
33
|
+
}
|
34
|
+
`])]);
|
35
|
+
});
|
36
|
+
});
|
37
|
+
}
|
38
|
+
|
39
|
+
};
|
@@ -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 = 'bundle-report-integrity.json'
|
26
|
+
}) {
|
27
|
+
this.excludeKeysInStat = statsOutputExcludeKeys;
|
28
|
+
this.statsOptions = Object.assign({}, statsSchema, statsOptions);
|
29
|
+
this.statsFileName = statsFileName;
|
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: undefined,
|
733
|
+
options: undefined,
|
734
|
+
excludeKeys: undefined
|
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",
|