@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 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: true,
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;
@@ -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;
@@ -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
+ }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@zohodesk/react-cli",
3
- "version": "1.1.11",
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.11",
9
+ "version": "1.1.10",
10
10
  "license": "ISC",
11
11
  "dependencies": {
12
12
  "@babel/cli": "7.10.5",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zohodesk/react-cli",
3
- "version": "1.1.11",
3
+ "version": "1.1.12",
4
4
  "description": "A CLI tool for build modern web application and libraries",
5
5
  "scripts": {
6
6
  "init": "node ./lib/utils/init.js",