@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 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",