@zohodesk/react-cli 1.1.29-exp.1 → 1.1.29-exp.3

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,24 @@ Now to run app
44
44
 
45
45
  # Change Logs
46
46
 
47
+ # 1.1.28 (29-01-2025)
48
+
49
+ **Fixes**
50
+
51
+ - We've changed the i18n Unicode conversion process. Instead of converting the Unicode at runtime, we now convert it to the corresponding language during the build process and emit the final build
52
+ - Added @zohodesk-private in transformIgnorePatterns in jest.config.js file , fix in jest
53
+
54
+ **changes**
55
+
56
+ - separate the disableES5Transpile flag as two flags disableES5Transpile and disableES5Import
57
+ - disableES5Import flag handles the alias part
58
+ - disableES5Transpile flag handles the esmodules or common modules conversion part
59
+
60
+
61
+ # 1.1.27 (16-12-2024)
62
+
63
+ - While rendering i18n keys at runtime, we convert any keys containing Unicode to their corresponding language characters before rendering. This enhances performance and reduces file size.
64
+
47
65
  # 1.1.26 (06-09-2024)
48
66
 
49
67
  **Features**
@@ -30,7 +30,11 @@ const defaultPlugins = [[require.resolve('babel-plugin-transform-define'), isPro
30
30
  }]];
31
31
  const resolvedPlugins = [];
32
32
  babelPlugins.forEach(plugin => {
33
- resolvedPlugins.push(require.resolve(plugin));
33
+ if (Array.isArray(plugin)) {
34
+ resolvedPlugins.push([require.resolve(plugin[0]), plugin[1]]);
35
+ } else {
36
+ resolvedPlugins.push(require.resolve(plugin));
37
+ }
34
38
  });
35
39
  const plugins = [...defaultPlugins, ...resolvedPlugins];
36
40
  const presets = [require.resolve('@babel/preset-env'), (0, _babelPresetReactOption.default)({
@@ -26,12 +26,16 @@ const isProd = mode.toLowerCase() === 'prod';
26
26
  const defaultPlugins = [[require.resolve('babel-plugin-transform-define'), isProd ? {
27
27
  __DOCS__: false
28
28
  } : {}], require.resolve('@babel/plugin-syntax-dynamic-import'), [require.resolve('babel-plugin-module-resolver'), {
29
- "root": ["./"],
29
+ 'root': ['./'],
30
30
  alias
31
31
  }]];
32
32
  const resolvedPlugins = [];
33
33
  babelPlugins.forEach(plugin => {
34
- resolvedPlugins.push(require.resolve(plugin));
34
+ if (Array.isArray(plugin)) {
35
+ resolvedPlugins.push([require.resolve(plugin[0]), plugin[1]]);
36
+ } else {
37
+ resolvedPlugins.push(require.resolve(plugin));
38
+ }
35
39
  });
36
40
  const plugins = [...defaultPlugins, ...resolvedPlugins];
37
41
  const presets = [[require.resolve('@babel/preset-env'), disableES5Transpile ? {
@@ -26,7 +26,7 @@ const commonConfig = {
26
26
  // ...moduleNameMapper,
27
27
  // '\\.(css|less)$': 'identity-obj-proxy'
28
28
  // },
29
- transformIgnorePatterns: ['/node_modules/(?!(@zohodesk)/)'],
29
+ transformIgnorePatterns: ['/node_modules/(?!(@zohodesk|@zohodesk-private)/)'],
30
30
  // transformIgnorePatterns: ['/node_modules.*?.js$'],
31
31
  moduleFileExtensions: ['js', 'ts', 'tsx'],
32
32
  setupFiles: [(0, _fs.existsSync)(appGlobals) && appGlobals, _path.default.resolve(__dirname, '..', 'jest', 'setup.js')].filter(Boolean),
@@ -23,7 +23,7 @@ const {
23
23
  app
24
24
  } = (0, _utils.getOptions)();
25
25
  const {
26
- disableES5Transpile
26
+ disableES5Import
27
27
  } = app;
28
28
 
29
29
  function aliasPathCreation(customAlias) {
@@ -64,7 +64,7 @@ const libAlias = {
64
64
  // '^@components(.*)$': '<rootDir>/src/components$1',
65
65
 
66
66
  exports.libAlias = libAlias;
67
- const totalAlias = disableES5Transpile ? Object.assign({}, libAlias, aliasPathCreation(alias)) : aliasPathCreation(alias);
67
+ const totalAlias = disableES5Import ? Object.assign({}, libAlias, aliasPathCreation(alias)) : aliasPathCreation(alias);
68
68
  const jestModuleNameMapper = Object.keys(totalAlias).reduce((previousValue, key) => {
69
69
  previousValue[`^${key}(.*)$`] = `${totalAlias[key]}$1`;
70
70
  return previousValue;
@@ -19,7 +19,7 @@ var _client_packages_group = require("@zohodesk/client_packages_group");
19
19
  function moduleResolver(options) {
20
20
  const {
21
21
  moduleResolvePath,
22
- disableES5Transpile
22
+ disableES5Import
23
23
  } = options.app;
24
24
  const customAlias = options.alias;
25
25
  let required = moduleResolvePath && (0, _requireLocalOrGlobal.requireLocal)(moduleResolvePath);
@@ -33,7 +33,7 @@ function moduleResolver(options) {
33
33
  }
34
34
 
35
35
  const nodeModulesPath = required ? required.nodeModulesPath : _client_packages_group.nodeModulesPath;
36
- const totalAlias = disableES5Transpile ? Object.assign({}, _libAlias.libAlias, (0, _libAlias.aliasPathCreation)(customAlias)) : (0, _libAlias.aliasPathCreation)(customAlias);
36
+ const totalAlias = disableES5Import ? Object.assign({}, _libAlias.libAlias, (0, _libAlias.aliasPathCreation)(customAlias)) : (0, _libAlias.aliasPathCreation)(customAlias);
37
37
  return {
38
38
  extensions: ['.js', '.jsx', '.ts', '.tsx'],
39
39
  modules: [nodeModulesPath, _constants.cliNodeModulesPath, 'node_modules'].filter(Boolean),
@@ -15,7 +15,11 @@ const {
15
15
  } = babelCustomizationForLibrary;
16
16
  const resolvedPlugins = [];
17
17
  babelPlugins.forEach(plugin => {
18
- resolvedPlugins.push(require.resolve(plugin));
18
+ if (Array.isArray(plugin)) {
19
+ resolvedPlugins.push([require.resolve(plugin[0]), plugin[1]]);
20
+ } else {
21
+ resolvedPlugins.push(require.resolve(plugin));
22
+ }
19
23
  });
20
24
  const presets = [require.resolve('@babel/preset-env'), require.resolve('@babel/preset-react')];
21
25
 
@@ -63,13 +63,10 @@ class I18NInjectIntoIndexPlugin {
63
63
  const {
64
64
  assets
65
65
  } = data; // Manipulate the content
66
- // const i18nManifest = this.getI18nManifest(compilation);
67
- // const entryPoint = compilation.entrypoints.get(this.entryPointName);
68
66
 
69
- const i18nScriptURLs = [];
70
- i18nScriptURLs.push("desk-i18n-manifest.js");
71
- i18nScriptURLs.push("master.i18n.js");
72
- i18nScriptURLs.push("masterchunk.i18n.js"); // .map(url => getI18nScriptTagObj(url));
67
+ const i18nManifest = this.getI18nManifest(compilation);
68
+ const entryPoint = compilation.entrypoints.get(this.entryPointName);
69
+ const i18nScriptURLs = entryPoint.chunks.filter(c => !!i18nManifest[c.id]).map(c => this.getI18nFileUrlPath(c, compilation)); // .map(url => getI18nScriptTagObj(url));
73
70
  // .join('');
74
71
  // Tell webpack to move on
75
72
 
@@ -9,6 +9,8 @@ var _webpack = require("webpack");
9
9
 
10
10
  var _I18nKeysIdentifer = _interopRequireDefault(require("./I18nKeysIdentifer"));
11
11
 
12
+ var _hashUtils = require("./utils/hashUtils");
13
+
12
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
15
 
14
16
  /**
@@ -29,9 +31,43 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
29
31
  * some thing missing in this definetion
30
32
  *
31
33
  */
32
- const pluginName = 'DownloadLogicOfI18n';
34
+ // import { REGEXP_HASH, REGEXP_CHUNKHASH } from './utils/hashUtils';
35
+ const pluginName = 'DownloadLogicOfI18n'; // const pluginName = 'i18n-plugin';
36
+
33
37
  const MODULE_TYPE = 'json/i18n';
34
38
 
39
+ const ltype = locale => `${MODULE_TYPE}/${locale}`;
40
+
41
+ function hashesWithLength(hashes, length) {
42
+ const shortChunkHashMap = {};
43
+
44
+ for (let key of Object.keys(hashes)) {
45
+ if (typeof hashes[key] === 'string') {
46
+ shortChunkHashMap[key] = hashes.slice(0, length);
47
+ }
48
+ }
49
+
50
+ return shortChunkHashMap;
51
+ }
52
+
53
+ function getContentHashMaxLength(filenameTemplate) {
54
+ let length = 0;
55
+ let matches = filenameTemplate.match(_hashUtils.REGEXP_CONTENTHASH);
56
+
57
+ for (let match of matches) {
58
+ let tem = match.match(/\d+/);
59
+
60
+ if (tem) {
61
+ length = Math.max(parseInt(tem[0]), length);
62
+ } else {
63
+ length = 0;
64
+ break;
65
+ }
66
+ }
67
+
68
+ return length;
69
+ }
70
+
35
71
  class I18nDownlodLogic {
36
72
  constructor({
37
73
  filenameTemplate,
@@ -45,33 +81,34 @@ class I18nDownlodLogic {
45
81
  filenameTemplate,
46
82
  localeVarName
47
83
  };
48
- this.finalChunkIds = new Map();
49
84
  }
50
85
 
51
- captureChunkIds(compilation) {
52
- this.finalChunkIds.clear();
53
- compilation.chunks.forEach(chunk => {
54
- this.finalChunkIds.set(chunk.id, {
55
- original: chunk.id,
56
- name: chunk.name || null
57
- });
86
+ getShortContentHashes(chunk, hashLength) {
87
+ let allContenHashes = {};
88
+ const chunkMaps = chunk.getChunkMaps();
89
+ this.locales.forEach(locale => {
90
+ allContenHashes[locale] = chunkMaps.contentHash[ltype(locale)];
58
91
  });
92
+
93
+ if (!length) {
94
+ return allContenHashes;
95
+ }
96
+
97
+ let shortContentHashMap = {};
98
+
99
+ for (const locale of this.locales) {
100
+ shortContentHashMap[locale] = hashesWithLength(allContenHashes[locale], hashLength);
101
+ }
102
+
103
+ return shortContentHashMap;
59
104
  }
60
105
 
61
106
  getI18nChunkObject(mainChunk) {
62
107
  const obj = {};
63
108
 
64
109
  for (const chunk of mainChunk.getAllAsyncChunks()) {
65
- const finalChunkId = chunk.id;
66
-
67
110
  if (_I18nKeysIdentifer.default.isChunkHasI18n(chunk)) {
68
- // Store using the final chunk ID
69
- obj[finalChunkId] = 1; // Also keep track of which chunks have i18n content
70
-
71
- this.finalChunkIds.set(finalChunkId, {
72
- original: chunk.id,
73
- name: chunk.name || null
74
- });
111
+ obj[chunk.id] = 1;
75
112
  }
76
113
  }
77
114
 
@@ -79,7 +116,6 @@ class I18nDownlodLogic {
79
116
  }
80
117
 
81
118
  addDownloadLogicOfI18nInMainTemplate(mainTemplate) {
82
- // Extend localVars to create a container for tracking loaded i18n chunks.
83
119
  mainTemplate.hooks.localVars.tap(pluginName, (source, mainChunk) => {
84
120
  const chunkMap = this.getI18nChunkObject(mainChunk);
85
121
 
@@ -87,113 +123,141 @@ class I18nDownlodLogic {
87
123
  return source;
88
124
  }
89
125
 
90
- return _webpack.Template.asString([source, '', '// Object to store loaded I18N chunks', '// Using final chunk IDs from webpack', 'var installedI18nChunks = {', _webpack.Template.indent(mainChunk.ids.map(id => `${JSON.stringify(id)}: 0`).join(',\n')), '};']);
91
- }); // Extend requireEnsure so that whenever a JS chunk is requested,
92
- // we also download its associated i18n file (if available).
93
-
126
+ return _webpack.Template.asString([source, '', '// object to store loaded I18N chunks', 'var installedI18nChunks = {', _webpack.Template.indent(mainChunk.ids.map(id => `${JSON.stringify(id)}: 0`).join(',\n')), '};']);
127
+ });
94
128
  mainTemplate.hooks.requireEnsure.tap(pluginName, (source, mainChunk, hash) => {
129
+ /**
130
+ * for Information this is tapped in mainTemplate ,
131
+ * So this hooks argument chunk is main chunk means entry chunk mostly.
132
+ * if any chunk has i18n then we must write our download i18n logic,
133
+ */
95
134
  const chunkMap = this.getI18nChunkObject(mainChunk);
96
135
 
97
136
  if (!Object.keys(chunkMap).length) {
98
137
  return source;
99
138
  }
139
+ /**
140
+ * chunkMaps has
141
+ * @property {Object} hash [it has key as chunk id and value as chunkHash ]
142
+ * @property {Object} name [it has key as chunk id and value as chunk name ]
143
+ */
144
+
100
145
 
146
+ const chunkMaps = mainChunk.getChunkMaps();
101
147
  const {
102
148
  crossOriginLoading
103
149
  } = mainTemplate.outputOptions;
104
150
  const {
151
+ filenameTemplate,
105
152
  localeVarName = 'document.documentElement.lang'
106
- } = this.options; // Use the provided publicPath or fallback to the one provided by Webpack.
153
+ } = this.options;
154
+ const i18nSrcPath = mainTemplate.getAssetPath(JSON.stringify(filenameTemplate).replace(/\[locale\]/gi, '"+ locale +"'), // "i18n-chunk/[locale]/[name].[chunkhash].js"
155
+ {
156
+ hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`,
157
+ hashWithLength: length => `" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`,
158
+ chunk: {
159
+ id: '" + chunkId + "',
160
+ hash: `" + ${JSON.stringify(chunkMaps.hash)}[chunkId] + "`,
161
+
162
+ hashWithLength(length) {
163
+ const shortChunkHashMap = hashesWithLength(chunkMaps.hash, length);
164
+ return `" + ${JSON.stringify(shortChunkHashMap)}[chunkId] + "`;
165
+ },
166
+
167
+ // contentHash: contentHashMap,
168
+ // contentHashWithLength: contentHashLengthMap,
169
+ contentHash: {
170
+ [MODULE_TYPE]: '" + contentHash + "'
171
+ },
172
+ contentHashWithLength: {
173
+ [MODULE_TYPE]: length => `" + contentHash.slice(0,${length}) + "`
174
+ },
175
+ name: `" + (${JSON.stringify(chunkMaps.name)}[chunkId]||chunkId) + "`
176
+ },
177
+ contentHashType: MODULE_TYPE
178
+ });
179
+ /** IDEA:
180
+ * as my suggestion ignore this `jsop` approch,
181
+ * Because json parse is faster then js parse.
182
+ * my suggestion is make ajax or fetch request
183
+ */
184
+
185
+ const buf = [];
186
+ /*
187
+ if (REGEXP_HASH.test(filenameTemplate)) {
188
+ buf.push(
189
+ `var hash = ${mainTemplate.renderCurrentHashCode(hash)};`
190
+ );
191
+ }
192
+ if (REGEXP_CHUNKHASH.test(filenameTemplate)) {
193
+ buf.push(`var chunkHashes = ${JSON.stringify(chunkMaps.hash)};`);
194
+ }
195
+ */
196
+
197
+ if ((0, _hashUtils.hasContentHash)(filenameTemplate)) {
198
+ const hashLength = getContentHashMaxLength(filenameTemplate);
199
+ const contentHashes = this.getShortContentHashes(mainChunk, hashLength);
200
+ buf.push(_webpack.Template.asString(['// all i18n files contentHash ', `var i18nContentHashes = ${JSON.stringify(contentHashes)};`, '', 'if (!i18nContentHashes[locale]) {', ' console.warn("this locale is "+locale + " not has support")', ' return;', '}', 'if (!i18nContentHashes[locale][chunkId]) {', ' console.warn("this chunkId is " + chunkId + " does not have \'"+locale+"\' locale chunk")', ' return;', '}']));
201
+ buf.push('var contentHash = i18nContentHashes[locale][chunkId]');
202
+ }
203
+
204
+ const hashUtils = _webpack.Template.asString(buf);
107
205
 
108
206
  const publicPath = this.publicPath ? JSON.stringify(this.publicPath) : `${mainTemplate.requireFn}.p`;
109
207
  return _webpack.Template.asString([source, `
110
208
  (function() {
111
- // ${pluginName} I18N loading with final chunk IDs
209
+ // ${pluginName} I18N loading
112
210
  var i18nChunks = ${JSON.stringify(chunkMap)};
113
211
  var locale = ${localeVarName};
114
-
115
- // Check if the current chunkId has an associated i18n resource
116
- if (installedI18nChunks[chunkId]) {
212
+ // ${pluginName} I18N hasehes
213
+ ${hashUtils}
214
+ if(installedI18nChunks[chunkId]) {
117
215
  promises.push(installedI18nChunks[chunkId]);
118
- } else if (installedI18nChunks[chunkId] !== 0 && i18nChunks[chunkId]) {
216
+ } else if(installedI18nChunks[chunkId] !== 0 && i18nChunks[chunkId]) {
119
217
  promises.push(installedI18nChunks[chunkId] = new Promise(function(resolve, reject) {
120
- // Retrieve the i18n manifest from the global window.desk_i18n_manifest
121
- var deskManifest = window.desk_i18n_manifest;
122
-
123
- if (!deskManifest || !deskManifest.chunks || !deskManifest.chunks[chunkId]) {
124
- console.warn("No i18n file available for chunk " + chunkId);
125
- return resolve();
218
+ var srcPath = (${i18nSrcPath});
219
+ ${'' // TODO: I think this is the area for download chunk of i18n we can
220
+ // change mainTemplate.requireFn as our cdn server urls !!!
221
+ // and we can change the i18n download logic here
126
222
  }
127
-
128
- // Replace [locale] in the basePath with the actual locale
129
- var basePath = deskManifest.basePath.replace("[locale]", locale);
130
-
131
- // Construct the final URL for the i18n file
132
- var srcPath = basePath + deskManifest.chunks[chunkId];
133
223
  var fullsrcPath = ${publicPath} + srcPath;
134
-
135
- // Avoid duplicate loading by checking existing script tags
136
- var existingScriptTags = document.getElementsByTagName("script");
137
- for (var i = 0; i < existingScriptTags.length; i++) {
138
- var tag = existingScriptTags[i];
224
+ var existingLinkTags = document.getElementsByTagName("script");
225
+ for(var i = 0; i < existingLinkTags.length; i++) {
226
+ var tag = existingLinkTags[i];
139
227
  var dataSrc = tag.getAttribute("data-src") || tag.getAttribute("src");
140
- if (dataSrc === srcPath || dataSrc === fullsrcPath) {
141
- return resolve();
142
- }
228
+ if(dataSrc === srcPath || dataSrc === fullsrcPath){ return resolve();}
143
229
  }
144
-
145
- // Create a script tag to load the i18n file
146
230
  var scriptTag = document.createElement("script");
147
- scriptTag.onload = function() {
231
+ scriptTag.onload = () => {
148
232
  scriptTag.onerror = scriptTag.onload = null;
149
233
  resolve();
150
234
  };
151
-
152
235
  scriptTag.onerror = function(event) {
153
236
  scriptTag.onerror = scriptTag.onload = null;
154
- var request = (event && event.target && event.target.src) || fullsrcPath;
237
+ var request = event && event.target && event.target.src || fullsrcPath;
155
238
  var err = new Error("Loading I18N chunk " + chunkId + " failed.\\n(" + request + ")");
156
239
  err.code = "I18N_CHUNK_LOAD_FAILED";
157
240
  err.request = request;
158
241
  delete installedI18nChunks[chunkId];
159
- if (scriptTag.parentNode) {
160
- scriptTag.parentNode.removeChild(scriptTag);
161
- }
242
+ scriptTag.parentNode.removeChild(scriptTag);
162
243
  reject(err);
163
244
  };
164
-
165
245
  ${mainTemplate.requireFn}.nc && scriptTag.setAttribute("nonce", ${mainTemplate.requireFn}.nc);
166
246
  scriptTag.src = fullsrcPath;
167
-
168
247
  ${crossOriginLoading ? `if (scriptTag.src.indexOf(window.location.origin + '/') !== 0) {
169
- scriptTag.crossOrigin = ${JSON.stringify(crossOriginLoading)};
170
- }` : ''}
171
-
248
+ scriptTag.crossOrigin = ${JSON.stringify(crossOriginLoading)};
249
+ }` : ''}
172
250
  document.body.appendChild(scriptTag);
173
251
  }).then(function() {
174
252
  installedI18nChunks[chunkId] = 0;
175
253
  }));
176
254
  }
177
- })()
178
- `]);
255
+ })()`]);
179
256
  });
180
257
  }
181
- /**
182
- * Applies the plugin by tapping into the appropriate Webpack hooks.
183
- * Now captures final chunk IDs after compilation is complete.
184
- *
185
- * @param {Compiler} compiler - The Webpack compiler instance.
186
- */
187
-
188
258
 
189
259
  apply(compiler) {
190
- // First capture final chunk IDs after compilation
191
- compiler.hooks.afterCompile.tap(pluginName, compilation => {
192
- this.captureChunkIds(compilation);
193
- }); // Then inject download logic in thisCompilation
194
-
195
260
  compiler.hooks.thisCompilation.tap(pluginName, compilation => {
196
- // console.log(`${pluginName}: Adding download logic with final chunk IDs`);
197
261
  const {
198
262
  mainTemplate
199
263
  } = compilation;