@zohodesk/client_build_tool 0.0.9-exp.4 → 0.0.9-exp.8

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/CHANGELOG.md CHANGED
@@ -1,16 +1,4 @@
1
1
  # Changelog and Release Notes
2
- # v0.0.9-exp.3 (11-05-2025)
3
- **Feature:-**
4
- - `alias` support for `build:es` and `build:lib`
5
- - Add babel-plugin-module-resolver dependencies
6
- - Modify getBabelPlugin to include module resolver with aliases
7
-
8
- **Bug Fix:-**
9
- - Enhance runBabelForTSFile to handle both .tsx and .ts file extensions
10
- - Update mockApiHandler to ensure mock function is called correctly
11
-
12
- **Change:-**
13
- - Refactor defaultConfigValues.js to include cli options for enableRTLSplit
14
2
 
15
3
 
16
4
 
package/README.md CHANGED
@@ -99,18 +99,80 @@ fixes :-
99
99
  - preload plc undefined url fixed
100
100
 
101
101
  # Changelog and Release Notes
102
- # v0.0.9-exp.3 (11-05-2025)
102
+
103
+
104
+
103
105
  **Feature:-**
104
- - `alias` support for `build:es` and `build:lib`
105
- - Add babel-plugin-module-resolver dependencies
106
- - Modify getBabelPlugin to include module resolver with aliases
106
+ - externals was added to Prevent bundling of certain imported packages and retrieve these external dependencies at runtime.
107
+ - to use externals, we use the following pattern in `app > externals` :
108
+
109
+ For example
110
+ ```
111
+ externals: {
112
+ <key> : <value>
113
+ }
114
+ ```
107
115
 
108
- **Bug Fix:-**
109
- - Enhance runBabelForTSFile to handle both .tsx and .ts file extensions
110
- - Update mockApiHandler to ensure mock function is called correctly
116
+ ## v0.0.6 (4-09-2023)
117
+
118
+ **Feature:-**
119
+ - Generating bundle integrity report 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`.
120
+ - Added Resource Cleanup plugin to cleanup resource retained by build tool. this plugin is controlled by efc flag resourcecleanup flag.
121
+ - added support for using regex expression to get group of chunks chunkId via Resource Hint plugin prefetch/preload hook.
122
+ only will be activate when `resourceHints` => `allowPrefetchingMultipleChunks` as `true`
123
+ - added support for glob pattern for custom chunks split logic.
124
+ - added options to split chunks base config in the key `app` => `customChunksBaseConfig` as object
111
125
 
112
126
  **Change:-**
113
- - Refactor defaultConfigValues.js to include cli options for enableRTLSplit
127
+ - i18n name not generated issue fix.
128
+ - public path not correctly set issue fix.
129
+ - changing plugin hook stages in i18nRuntimePlugin and sourceMapPlugin
130
+ ## v0.0.5 (6-08-2023)
131
+
132
+ **Changes:--**
133
+ - Typo fix in i18nRuntimeDealerPlugin.js
134
+ - fixing some bugs in resolvers.js file
135
+
136
+ ## v0.0.3 (1-08-2023)
137
+
138
+ **Changes:--**
139
+ - `devtool` default value changed from `hidden-cheap-source-map` to `source-map`
140
+ - unwanted files deleted from build
141
+
142
+ **Issue Fix:--**
143
+ - The issue with the source map not being created in the build has been fixed."
144
+
145
+
146
+ ## v0.0.2 (28-04-2023)
147
+
148
+ **Features:-**
149
+
150
+ - `devModeContentHashAllowedTypes` support added for some project there will be a need for hash even though they run dev mode. for details [details](https://zgit.csez.zohocorpin.com/zohodesk/react-cli/-/blob/3.0.0/packages/client_build_tool/ConfigurationDocumentation.md#devModeContentHashAllowedTypes)
151
+ - `devLikeHash` support for disable content hash for file names in production mode. for details [details](https://zgit.csez.zohocorpin.com/zohodesk/react-cli/-/blob/3.0.0/packages/client_build_tool/ConfigurationDocumentation.md#devLikeHash)
152
+ - `disableReactDevWarning` disable react dev warning such as prop-type warnings will be removed in dev mode build or server. for details [details](https://zgit.csez.zohocorpin.com/zohodesk/react-cli/-/blob/3.0.0/packages/client_build_tool/ConfigurationDocumentation.md#disableReactDevWarning) can be enabled via `--disable_react_dev_warning` too.
153
+ - `statsLogConfig` support to customize default webpack log after build finished. for details [details](https://zgit.csez.zohocorpin.com/zohodesk/react-cli/-/blob/3.0.0/packages/client_build_tool/ConfigurationDocumentation.md#statsLogConfig) can be enabled via `--disable_react_dev_warning` too.
154
+ - `enableChunkHash` renamed as `enableFileNameHashing`
155
+
156
+ - `pre_processor` command to run the preprocessor.js file.preProcessor runs in build, start, buildEs, buildLib commands bu default. and we have watch mode support as well with the option (`-w`)
157
+ - `createSeparateSmap` flag `source_map_enable` renamed as `enable_smap`
158
+ - `removeAttribute` option changes as `babelCustomizations.removeAttribute`
159
+ - `removePropTypes` support for remove the prop types package in the output build.
160
+ - `devConsoleExclude` support for remove the _console statements_ such as _console.log_, _console.warn_ in the output build.
161
+ - `manifestJson` default value set as false.
162
+ - `customAttributes` support for add attributes to html, link , script tag in the output build.
163
+
164
+
165
+ ## v0.0.1 (18-04-2023)
166
+
167
+ First Release
168
+ **Features:-**
169
+
170
+ - 'start' command to run react app
171
+ - 'build' command to create build for react app
172
+ - 'build:lib' command to create lib for react library
173
+ - 'build:es' command to create es for react library
174
+ - 'templates' command to create es for react library
175
+ # Changelog and Release Notes
114
176
 
115
177
 
116
178
 
package/README_backup.md CHANGED
@@ -98,3 +98,77 @@ fixes :-
98
98
 
99
99
  - preload plc undefined url fixed
100
100
 
101
+ # Changelog and Release Notes
102
+
103
+
104
+
105
+ **Feature:-**
106
+ - externals was added to Prevent bundling of certain imported packages and retrieve these external dependencies at runtime.
107
+ - to use externals, we use the following pattern in `app > externals` :
108
+
109
+ For example
110
+ ```
111
+ externals: {
112
+ <key> : <value>
113
+ }
114
+ ```
115
+
116
+ ## v0.0.6 (4-09-2023)
117
+
118
+ **Feature:-**
119
+ - Generating bundle integrity report 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`.
120
+ - Added Resource Cleanup plugin to cleanup resource retained by build tool. this plugin is controlled by efc flag resourcecleanup flag.
121
+ - added support for using regex expression to get group of chunks chunkId via Resource Hint plugin prefetch/preload hook.
122
+ only will be activate when `resourceHints` => `allowPrefetchingMultipleChunks` as `true`
123
+ - added support for glob pattern for custom chunks split logic.
124
+ - added options to split chunks base config in the key `app` => `customChunksBaseConfig` as object
125
+
126
+ **Change:-**
127
+ - i18n name not generated issue fix.
128
+ - public path not correctly set issue fix.
129
+ - changing plugin hook stages in i18nRuntimePlugin and sourceMapPlugin
130
+ ## v0.0.5 (6-08-2023)
131
+
132
+ **Changes:--**
133
+ - Typo fix in i18nRuntimeDealerPlugin.js
134
+ - fixing some bugs in resolvers.js file
135
+
136
+ ## v0.0.3 (1-08-2023)
137
+
138
+ **Changes:--**
139
+ - `devtool` default value changed from `hidden-cheap-source-map` to `source-map`
140
+ - unwanted files deleted from build
141
+
142
+ **Issue Fix:--**
143
+ - The issue with the source map not being created in the build has been fixed."
144
+
145
+
146
+ ## v0.0.2 (28-04-2023)
147
+
148
+ **Features:-**
149
+
150
+ - `devModeContentHashAllowedTypes` support added for some project there will be a need for hash even though they run dev mode. for details [details](https://zgit.csez.zohocorpin.com/zohodesk/react-cli/-/blob/3.0.0/packages/client_build_tool/ConfigurationDocumentation.md#devModeContentHashAllowedTypes)
151
+ - `devLikeHash` support for disable content hash for file names in production mode. for details [details](https://zgit.csez.zohocorpin.com/zohodesk/react-cli/-/blob/3.0.0/packages/client_build_tool/ConfigurationDocumentation.md#devLikeHash)
152
+ - `disableReactDevWarning` disable react dev warning such as prop-type warnings will be removed in dev mode build or server. for details [details](https://zgit.csez.zohocorpin.com/zohodesk/react-cli/-/blob/3.0.0/packages/client_build_tool/ConfigurationDocumentation.md#disableReactDevWarning) can be enabled via `--disable_react_dev_warning` too.
153
+ - `statsLogConfig` support to customize default webpack log after build finished. for details [details](https://zgit.csez.zohocorpin.com/zohodesk/react-cli/-/blob/3.0.0/packages/client_build_tool/ConfigurationDocumentation.md#statsLogConfig) can be enabled via `--disable_react_dev_warning` too.
154
+ - `enableChunkHash` renamed as `enableFileNameHashing`
155
+
156
+ - `pre_processor` command to run the preprocessor.js file.preProcessor runs in build, start, buildEs, buildLib commands bu default. and we have watch mode support as well with the option (`-w`)
157
+ - `createSeparateSmap` flag `source_map_enable` renamed as `enable_smap`
158
+ - `removeAttribute` option changes as `babelCustomizations.removeAttribute`
159
+ - `removePropTypes` support for remove the prop types package in the output build.
160
+ - `devConsoleExclude` support for remove the _console statements_ such as _console.log_, _console.warn_ in the output build.
161
+ - `manifestJson` default value set as false.
162
+ - `customAttributes` support for add attributes to html, link , script tag in the output build.
163
+
164
+
165
+ ## v0.0.1 (18-04-2023)
166
+
167
+ First Release
168
+ **Features:-**
169
+
170
+ - 'start' command to run react app
171
+ - 'build' command to create build for react app
172
+ - 'build:lib' command to create lib for react library
173
+ - 'build:es' command to create es for react library
174
+ - 'templates' command to create es for react library
@@ -115,10 +115,7 @@ var _default = {
115
115
  // Name Suggestions `customizations` this will be easier then `plugin` to understand for developers
116
116
  plugins: {
117
117
  rtlSplit: {
118
- enableRTLSplit: {
119
- value: false,
120
- cli: 'enable_rtl_split'
121
- },
118
+ enableRTLSplit: false,
122
119
  templateLabel: '{{--dir}}',
123
120
  disableMinifySelector: false,
124
121
  dirVarName: 'document.dir'
@@ -176,6 +173,47 @@ var _default = {
176
173
  jsResource: null,
177
174
  propertiesFolder: null
178
175
  },
176
+ i18nIndexing: {
177
+ enable: {
178
+ value: false,
179
+ cli: 'i18n_idx_enable'
180
+ },
181
+ disableDefaultMerge: {
182
+ value: false,
183
+ cli: 'i18n_idx_disable_default_merge'
184
+ },
185
+ htmlTemplateLabel: {
186
+ value: '{{--user-locale}}',
187
+ cli: 'i18n_idx_html_template_label'
188
+ },
189
+ localeVarName: {
190
+ value: 'window.userLangCode',
191
+ cli: 'i18n_idx_locale_var_name'
192
+ },
193
+ jsResourcePath: {
194
+ value: './deskapp/properties/JSResources.properties',
195
+ cli: 'i18n_idx_js_resource_path'
196
+ },
197
+ propertiesFolderPath: {
198
+ value: './deskapp/properties',
199
+ cli: 'i18n_idx_properties_folder_path'
200
+ },
201
+ propertiesPattern: {
202
+ value: ''
203
+ },
204
+ numericMapPath: {
205
+ value: './deskapp/properties/i18n-numeric-map.json',
206
+ cli: 'i18n_idx_numeric_map_path'
207
+ },
208
+ jsonpFunc: {
209
+ value: 'window.loadI18nData',
210
+ cli: 'i18n_idx_jsonp_func'
211
+ },
212
+ fallbackToHash: {
213
+ value: true,
214
+ cli: 'i18n_idx_fallback_to_hash'
215
+ }
216
+ },
179
217
  publicFolders: ['...'],
180
218
  app: {
181
219
  entryFile: {
@@ -96,6 +96,19 @@ var _default = {
96
96
  jsResource: null,
97
97
  propertiesFolder: null
98
98
  },
99
+ i18nIndexing: {
100
+ enable: false,
101
+ disableDefaultMerge: false,
102
+ htmlTemplateLabel: '{{--user-locale}}',
103
+ localeVarName: 'window.userLangCode',
104
+ jsResourcePath: './deskapp/properties/JSResources.properties',
105
+ propertiesFolderPath: './deskapp/properties',
106
+ propertiesPattern: '',
107
+ numericMapPath: './deskapp/properties/i18n-numeric-map.json',
108
+ numericJsonpFunc: 'window.loadI18nChunk',
109
+ dynamicJsonpFunc: 'window.loadI18nChunk',
110
+ fallbackToHash: true
111
+ },
99
112
  publicFolders: ['...', {
100
113
  source: './deskapp/tp/',
101
114
  target: './tp/'
@@ -20,14 +20,7 @@ function getBabelPlugin(options) {
20
20
  const {
21
21
  mode
22
22
  } = options;
23
- const {
24
- alias
25
- } = options.resolve; // let customPlugins = [];
26
-
27
- let customPlugins = [[require.resolve('babel-plugin-module-resolver'), {
28
- root: ['./'],
29
- alias
30
- }]];
23
+ let customPlugins = [];
31
24
  const {
32
25
  babelCustomizations
33
26
  } = options;
@@ -39,4 +32,6 @@ function getBabelPlugin(options) {
39
32
  }
40
33
 
41
34
  return customPlugins.filter(Boolean);
42
- }
35
+ }
36
+
37
+ ;
@@ -25,6 +25,6 @@ function runBabelForTSFile({
25
25
  // const jsSourceCode = readFileSync(filename).toString();
26
26
  const babelConfig = (0, _babelWebConfig.babelWebConfig)(options, mode);
27
27
  const result = (0, _core.transformFileSync)(filename, babelConfig);
28
- (0, _copyFile.writeFile)(outputFile.replace('.tsx', '.js').replace('.ts', '.js'), result.code);
28
+ (0, _copyFile.writeFile)(outputFile.replace('.tsx', '.js'), result.code);
29
29
  }
30
30
  }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.generateShortHash = generateShortHash;
7
+
8
+ var _crypto = require("crypto");
9
+
10
+ function generateShortHash(str, length = 8) {
11
+ if (typeof str !== 'string' || str.length === 0) {
12
+ return '';
13
+ }
14
+
15
+ try {
16
+ return (0, _crypto.createHash)('md5').update(str).digest('hex').slice(0, length);
17
+ } catch (error) {
18
+ return '';
19
+ }
20
+ }
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
4
+
5
+ var {
6
+ urlConcat
7
+ } = require("../../../../server/urlConcat");
8
+
9
+ const pluginName = 'I18nNumericIndexHtmlInjectorPlugin';
10
+
11
+ class I18nNumericIndexHtmlInjectorPlugin {
12
+ constructor(options) {
13
+ this.options = options;
14
+ }
15
+
16
+ apply(compiler) {
17
+ compiler.hooks.thisCompilation.tap(pluginName, compilation => {
18
+ HtmlWebpackPlugin.getHooks(compilation).beforeAssetTagGeneration.tapAsync(pluginName, (hookData, cb) => {
19
+ const {
20
+ assets
21
+ } = hookData;
22
+ const {
23
+ i18nAssetsPublicPathPrefix = ''
24
+ } = this.options;
25
+ const DEFAULT_LOCALE = '{{--user-locale}}';
26
+ const NUMERIC_FILENAME = `i18n-chunks/${DEFAULT_LOCALE}/numeric.i18n.js`;
27
+ const DYNAMIC_FILENAME = `i18n-chunks/${DEFAULT_LOCALE}/dynamic.i18n.js`;
28
+ const newI18nAssetUrlsToAdd = [];
29
+ const numericAssetUrl = urlConcat('', NUMERIC_FILENAME);
30
+ newI18nAssetUrlsToAdd.push(numericAssetUrl);
31
+ const dynamicAssetUrl = urlConcat('', DYNAMIC_FILENAME);
32
+ newI18nAssetUrlsToAdd.push(dynamicAssetUrl);
33
+
34
+ if (newI18nAssetUrlsToAdd.length > 0) {
35
+ assets.js = [...newI18nAssetUrlsToAdd, ...assets.js];
36
+ }
37
+
38
+ cb(null, hookData);
39
+ });
40
+ });
41
+ }
42
+
43
+ }
44
+
45
+ module.exports = {
46
+ I18nNumericIndexHtmlInjectorPlugin
47
+ };
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+
3
+ const fs = require('fs');
4
+
5
+ const path = require('path');
6
+
7
+ const {
8
+ sources,
9
+ Compilation
10
+ } = require('webpack');
11
+
12
+ const {
13
+ createHash
14
+ } = require("../I18nSplitPlugin/createHash");
15
+
16
+ const {
17
+ RawSource
18
+ } = sources;
19
+ const pluginName = 'I18nNumericIndexPlugin';
20
+
21
+ class I18nNumericIndexPlugin {
22
+ constructor(options) {
23
+ this.options = options;
24
+ this.numericMap = null;
25
+ this.numericMapPath = options.numericMapPath;
26
+ }
27
+
28
+ loadNumericMapOnce(compilation) {
29
+ if (this.numericMap) {
30
+ return this.numericMap;
31
+ }
32
+
33
+ try {
34
+ if (this.numericMapPath && fs.existsSync(this.numericMapPath)) {
35
+ const fileContent = fs.readFileSync(this.numericMapPath, 'utf-8');
36
+ const parsedData = JSON.parse(fileContent);
37
+
38
+ if (parsedData && parsedData.sortedOriginalKeys && parsedData.totalKeys !== undefined) {
39
+ this.numericMap = {
40
+ sortedOriginalKeys: parsedData.sortedOriginalKeys,
41
+ totalKeys: parsedData.totalKeys
42
+ };
43
+ compilation.logger.info(`${pluginName}: Loaded numeric map from ${this.numericMapPath}.`);
44
+ return this.numericMap;
45
+ } else {
46
+ compilation.logger.error(`${pluginName}: Invalid format in numeric map file at ${this.numericMapPath}.`);
47
+ this.numericMap = {
48
+ sortedOriginalKeys: [],
49
+ totalKeys: 0
50
+ };
51
+ }
52
+ } else {
53
+ compilation.logger.warn(`${pluginName}: Numeric map path not provided or file not found at ${this.numericMapPath}.`);
54
+ this.numericMap = {
55
+ sortedOriginalKeys: [],
56
+ totalKeys: 0
57
+ };
58
+ }
59
+ } catch (err) {
60
+ compilation.logger.error(`${pluginName}: Error loading numeric map from ${this.numericMapPath}: ${err.message}`);
61
+ this.numericMap = {
62
+ sortedOriginalKeys: [],
63
+ totalKeys: 0
64
+ };
65
+ }
66
+
67
+ return this.numericMap;
68
+ }
69
+
70
+ emitFile(compilation, baseFilenameTemplate, locale, fileContentData, jsonpFunc, typeSuffix = '') {
71
+ const fileContent = `${jsonpFunc}(${JSON.stringify(fileContentData)});`;
72
+ const source = new RawSource(fileContent);
73
+ const actualContentHash = createHash({
74
+ //
75
+ outputOptions: compilation.outputOptions,
76
+ content: fileContent
77
+ });
78
+ let processedFilenameTemplate = baseFilenameTemplate.replace(/\[locale\]/g, locale).replace(/\[name\]/g, locale).replace(/\[id\]/g, locale);
79
+ const finalFileName = compilation.getAssetPath(processedFilenameTemplate, {
80
+ locale: locale,
81
+ contentHash: actualContentHash,
82
+ hash: compilation.hash,
83
+ chunk: {
84
+ id: `i18n-${typeSuffix || 'data'}-${locale}`,
85
+ name: `${typeSuffix || 'data'}-${locale}`,
86
+ hash: actualContentHash,
87
+ contentHash: {
88
+ [this.options.moduleType || 'i18n/mini-extract']: actualContentHash
89
+ }
90
+ },
91
+ contentHashType: this.options.moduleType || 'i18n/mini-extract'
92
+ });
93
+ compilation.emitAsset(finalFileName, source);
94
+ compilation.logger.info(`${pluginName}: Emitted ${typeSuffix} i18n file for locale ${locale} to ${finalFileName}`);
95
+ }
96
+
97
+ apply(compiler) {
98
+ compiler.hooks.thisCompilation.tap(pluginName, compilation => {
99
+ compilation.hooks.processAssets.tapAsync({
100
+ name: pluginName,
101
+ stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
102
+ }, (assets, callback) => {
103
+ const {
104
+ sortedOriginalKeys,
105
+ totalKeys
106
+ } = this.loadNumericMapOnce(compilation);
107
+
108
+ if (totalKeys === 0 && (!sortedOriginalKeys || sortedOriginalKeys.length === 0)) {
109
+ compilation.logger.info(`${pluginName}: No numeric keys to process. Skipping numeric file emission.`);
110
+ }
111
+
112
+ const globallyUsedLiteralKeys = new Set();
113
+ const globallyUsedCommentKeys = new Set();
114
+
115
+ for (const module of compilation.modules) {
116
+ if (module.buildInfo) {
117
+ if (Array.isArray(module.buildInfo.loaderIdentifiedLiteralI18nKeys)) {
118
+ module.buildInfo.loaderIdentifiedLiteralI18nKeys.forEach(key => globallyUsedLiteralKeys.add(key));
119
+ }
120
+
121
+ if (Array.isArray(module.buildInfo.loaderIdentifiedCommentI18nKeys)) {
122
+ module.buildInfo.loaderIdentifiedCommentI18nKeys.forEach(key => globallyUsedCommentKeys.add(key));
123
+ }
124
+ }
125
+ }
126
+
127
+ compilation.logger.info(`${pluginName}: Globally identified Literal Keys: ${globallyUsedLiteralKeys.size}, Comment Keys: ${globallyUsedCommentKeys.size}`);
128
+ const {
129
+ locales,
130
+ allI18nObject,
131
+ numericFilenameTemplate,
132
+ dynamicFilenameTemplate,
133
+ numericJsonpFunc,
134
+ dynamicJsonpFunc
135
+ } = this.options;
136
+
137
+ if (!locales || !allI18nObject || !numericFilenameTemplate || !dynamicFilenameTemplate || !numericJsonpFunc || !dynamicJsonpFunc) {
138
+ compilation.errors.push(new Error(`${pluginName}: Missing some required options (locales, allI18nObject, filename templates, jsonp funcs).`));
139
+ return callback();
140
+ }
141
+
142
+ if (totalKeys > 0 && sortedOriginalKeys && sortedOriginalKeys.length > 0) {
143
+ for (const locale of locales) {
144
+ const localeTranslations = allI18nObject[locale] || {};
145
+ const orderedNumericTranslations = new Array(totalKeys);
146
+
147
+ for (let i = 0; i < totalKeys; i++) {
148
+ const originalKey = sortedOriginalKeys[i];
149
+
150
+ if (globallyUsedLiteralKeys.has(originalKey)) {
151
+ orderedNumericTranslations[i] = localeTranslations[originalKey] !== undefined ? localeTranslations[originalKey] : 0; // Use 0 or null as placeholder for missing keys
152
+ } else {
153
+ orderedNumericTranslations[i] = 0; // Placeholder for keys not identified as literals or not used
154
+ }
155
+ }
156
+
157
+ this.emitFile(compilation, numericFilenameTemplate, locale, orderedNumericTranslations, numericJsonpFunc, 'numeric');
158
+ }
159
+ }
160
+
161
+ if (globallyUsedCommentKeys.size > 0) {
162
+ for (const locale of locales) {
163
+ const localeTranslations = allI18nObject[locale] || {};
164
+ const dynamicKeyTranslations = {};
165
+ globallyUsedCommentKeys.forEach(originalKey => {
166
+ if (localeTranslations[originalKey] !== undefined) {
167
+ dynamicKeyTranslations[originalKey] = localeTranslations[originalKey];
168
+ } else {
169
+ dynamicKeyTranslations[originalKey] = null;
170
+ }
171
+ });
172
+
173
+ if (Object.keys(dynamicKeyTranslations).length > 0) {
174
+ this.emitFile(compilation, dynamicFilenameTemplate, locale, dynamicKeyTranslations, dynamicJsonpFunc, 'dynamic');
175
+ }
176
+ }
177
+ } else {
178
+ compilation.logger.info(`${pluginName}: No globally used comment keys found. Skipping dynamic file emission.`);
179
+ }
180
+
181
+ callback();
182
+ });
183
+ });
184
+ }
185
+
186
+ }
187
+
188
+ module.exports = {
189
+ I18nNumericIndexPlugin
190
+ };
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+
3
+ const {
4
+ walk
5
+ } = require('estree-walker');
6
+
7
+ const PREFIX_I18N_COMMENT = 'I18N';
8
+ const PREFIX_I18N_COMMENT_DYNAMIC = 'dynamic-i18n-key';
9
+
10
+ function getI18nKeysFromSingleComment(commentNode, validKeysSet, isDebug = false) {
11
+ const functionName = '[getI18nKeysFromSingleComment]';
12
+ const foundKeysInComment = [];
13
+
14
+ if (!commentNode || typeof commentNode.value !== 'string') {
15
+ return foundKeysInComment;
16
+ }
17
+
18
+ const commentString = commentNode.value.trim();
19
+ let i18nKeyStr;
20
+
21
+ if (commentString.startsWith(PREFIX_I18N_COMMENT)) {
22
+ i18nKeyStr = commentString.slice(PREFIX_I18N_COMMENT.length).trim();
23
+ } else if (commentString.startsWith(PREFIX_I18N_COMMENT_DYNAMIC)) {
24
+ i18nKeyStr = commentString.slice(PREFIX_I18N_COMMENT_DYNAMIC.length).trim();
25
+ }
26
+
27
+ if (!i18nKeyStr) {
28
+ return foundKeysInComment;
29
+ }
30
+
31
+ const potentialKeys = i18nKeyStr.split(',').map(key => key.trim()).filter(key => key);
32
+ potentialKeys.forEach(key => {
33
+ if (validKeysSet.has(key)) {
34
+ foundKeysInComment.push(key);
35
+ }
36
+ });
37
+ return foundKeysInComment;
38
+ }
39
+ /**
40
+ * Traverses an AST and its comments to collect and categorize i18n keys.
41
+ *
42
+ * @param {object} astProgramNode - The Program node of the AST.
43
+ * @param {object[]} commentsArray - An array of comment nodes from the AST.
44
+ * @param {object} allI18nKeysMasterMap - Object map of all valid i18n keys (from JSResources).
45
+ * @param {boolean} [isDebug=false] - Flag for verbose logging.
46
+ * @returns {{literalKeys: Set<string>, commentKeys: Set<string>}}
47
+ * literalKeys: Set of valid i18n keys found as string literals.
48
+ * commentKeys: Set of valid i18n keys found in comments.
49
+ */
50
+
51
+
52
+ function collectAndCategorizeUsedI18nKeys(astProgramNode, commentsArray, allI18nKeysMasterMap, isDebug = false) {
53
+ const functionName = '[collectAndCategorizeUsedI18nKeys]';
54
+ const foundLiteralKeys = new Set();
55
+ const foundCommentKeys = new Set();
56
+ const validKeysSet = new Set(Object.keys(allI18nKeysMasterMap || {}));
57
+
58
+ if (validKeysSet.size === 0 && isDebug) {
59
+ console.warn(`${functionName} allI18nKeysMasterMap is empty. No keys can be collected.`);
60
+ } // 1. Collect keys from AST string literals
61
+
62
+
63
+ if (astProgramNode) {
64
+ try {
65
+ walk(astProgramNode, {
66
+ enter(node) {
67
+ if ((node.type === 'Literal' || node.type === 'StringLiteral') && typeof node.value === 'string') {
68
+ if (validKeysSet.has(node.value)) {
69
+ foundLiteralKeys.add(node.value);
70
+ }
71
+ }
72
+ }
73
+
74
+ });
75
+ } catch (error) {
76
+ console.error(`${functionName} Error during AST walk:`, error);
77
+ }
78
+ } // 2. Collect keys from comments
79
+
80
+
81
+ if (commentsArray && Array.isArray(commentsArray)) {
82
+ commentsArray.forEach(commentNode => {
83
+ const keysFromComment = getI18nKeysFromSingleComment(commentNode, validKeysSet, isDebug);
84
+ keysFromComment.forEach(key => {
85
+ foundCommentKeys.add(key);
86
+ });
87
+ });
88
+ }
89
+
90
+ return {
91
+ literalKeys: foundLiteralKeys,
92
+ commentKeys: foundCommentKeys
93
+ };
94
+ }
95
+
96
+ module.exports = {
97
+ collectAndCategorizeUsedI18nKeys: collectAndCategorizeUsedI18nKeys
98
+ };
@@ -7,11 +7,24 @@ exports.jsLoaders = jsLoaders;
7
7
 
8
8
  var _babelLoaderConfig = require("./loaderConfigs/babelLoaderConfig");
9
9
 
10
+ var {
11
+ i18nIdReplaceLoaderConfig
12
+ } = require("./loaderConfigs/i18nIdReplaceLoaderConfig");
13
+
10
14
  function jsLoaders(options) {
15
+ const useLoaders = [(0, _babelLoaderConfig.babelLoaderConfig)(options)];
16
+
17
+ if (options.i18nIndexing && options.i18nIndexing.enable) {
18
+ const i18nLoader = i18nIdReplaceLoaderConfig(options);
19
+
20
+ if (i18nLoader) {
21
+ useLoaders.push(i18nLoader);
22
+ }
23
+ }
24
+
11
25
  return [{
12
26
  test: /\.js$/,
13
27
  exclude: /node_modules/,
14
- use: [(0, _babelLoaderConfig.babelLoaderConfig)(options)] // include: path.join(appPath, folder)
15
-
28
+ use: useLoaders
16
29
  }];
17
30
  }