@zohodesk/react-cli 1.1.11 → 1.1.12
Sign up to get free protection for your applications and to get access to all the features.
- 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",
|