@zohodesk/react-cli 1.1.29-exp.1 → 1.1.29-exp.2
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/lib/babel/babel-option-utils/babel-preset-react-option.js +0 -3
- package/lib/babel/cmjs-plugins-presets.js +1 -8
- package/lib/babel/es-plugins-presets.js +1 -8
- package/lib/common/buildEs.js +1 -0
- package/lib/common/getEntries.js +2 -13
- package/lib/common/getPublicPathConfig.js +0 -6
- package/lib/common/index.js +1 -6
- package/lib/common/runPreProcess.js +6 -15
- package/lib/common/splitChunks.js +2 -21
- package/lib/common/sslcertUpdater.js +7 -18
- package/lib/common/templateParameters.js +0 -2
- package/lib/common/testPattern.js +10 -21
- package/lib/common/valueReplacer.js +1 -16
- package/lib/configs/jest.config.js +1 -10
- package/lib/configs/libAlias.js +8 -14
- package/lib/configs/resolvers.js +4 -14
- package/lib/configs/webpack.component.umd.config.js +1 -6
- package/lib/configs/webpack.css.umd.config.js +6 -14
- package/lib/configs/webpack.dev.config.js +1 -14
- package/lib/configs/webpack.docs.config.js +1 -9
- package/lib/configs/webpack.impact.config.js +1 -8
- package/lib/configs/webpack.prod.config.js +4 -17
- package/lib/constants.js +9 -18
- package/lib/deprecationLogger.js +0 -7
- package/lib/hooks/docsProptypeHook.js +4 -8
- package/lib/jest/commitedFilesResult.js +4 -46
- package/lib/jest/coverageCollector.js +1 -12
- package/lib/jest/jsonMaker.js +0 -6
- package/lib/jest/preProcessors/cssPreprocessor.js +1 -9
- package/lib/jest/preProcessors/jsPreprocessor.js +1 -6
- package/lib/jest/preProcessors/otherFilesPreprocessor.js +1 -4
- package/lib/jest/result.js +1 -23
- package/lib/jest/run.js +7 -18
- package/lib/jest/setup.js +8 -60
- package/lib/loaderUtils/configsAssetsLoaders.js +2 -12
- package/lib/loaderUtils/getCSSLoaders.js +10 -22
- package/lib/loaderUtils/getDevJsLoaders.js +4 -13
- package/lib/loaderUtils/index.js +1 -4
- package/lib/loaderUtils/tests/windowsModification.test.js +0 -1
- package/lib/loaderUtils/windowsModification.js +2 -3
- package/lib/loaders/__test__/markdownLoader.spec.js +0 -1
- package/lib/loaders/composeLoader.js +13 -37
- package/lib/loaders/docsLoader.js +1 -12
- package/lib/loaders/docsPropsLoader.js +4 -8
- package/lib/loaders/enhancedReactLiveConverter.js +2 -23
- package/lib/loaders/fileBountryLoader.js +1 -3
- package/lib/loaders/fileLoader.js +12 -23
- package/lib/loaders/markdownLoader.js +14 -19
- package/lib/loaders/reactLiveConvertor.js +5 -15
- package/lib/loaders/scriptInstrumentLoader.js +7 -16
- package/lib/loaders/selectorMappingLoader.js +7 -26
- package/lib/loaders/workerLoader.js +9 -24
- package/lib/logger.js +0 -4
- package/lib/middlewares/HMRMiddleware.js +13 -27
- package/lib/middlewares/SSTMiddleware.js +1 -5
- package/lib/pluginUtils/configHtmlWebpackPlugins.js +1 -24
- package/lib/pluginUtils/getDevPlugins.js +9 -42
- package/lib/pluginUtils/getDocsPlugins.js +3 -13
- package/lib/pluginUtils/getLibraryImactPlugins.js +5 -6
- package/lib/pluginUtils/getLibraryPlugins.js +2 -8
- package/lib/pluginUtils/getProdPlugins.js +8 -47
- package/lib/pluginUtils/getServerPlugins.js +2 -8
- package/lib/pluginUtils/getUMDCSSPlugins.js +2 -10
- package/lib/pluginUtils/getUMDComponentPlugins.js +2 -10
- package/lib/pluginUtils/index.js +1 -9
- package/lib/plugins/CdnChangePlugin.js +2 -18
- package/lib/plugins/CleanupStatsPlugin.js +0 -5
- package/lib/plugins/CssOrderControlPlugin.js +3 -6
- package/lib/plugins/CustomAttributePlugin.js +14 -19
- package/lib/plugins/CustomScriptLoadingStrategyPlugin.js +3 -23
- package/lib/plugins/EFCPlugin.js +20 -34
- package/lib/plugins/EFCTemplatePlugin.js +19 -30
- package/lib/plugins/EfcResourceCleanupPlugin.js +0 -3
- package/lib/plugins/EventsHandlingPlugin.js +2 -4
- package/lib/plugins/I18NInjectIntoIndexPlugin.js +11 -37
- package/lib/plugins/I18nSplitPlugin/I18nDebugPlugin.js +10 -15
- package/lib/plugins/I18nSplitPlugin/I18nDependency.js +4 -10
- package/lib/plugins/I18nSplitPlugin/I18nDownlodLogic.js +12 -25
- package/lib/plugins/I18nSplitPlugin/I18nFilesEmitter.js +55 -133
- package/lib/plugins/I18nSplitPlugin/I18nKeysIdentifer.js +12 -23
- package/lib/plugins/I18nSplitPlugin/index.js +13 -24
- package/lib/plugins/I18nSplitPlugin/utils/applyMetaManifest.js +64 -58
- package/lib/plugins/I18nSplitPlugin/utils/collectI18nKeys.js +2 -12
- package/lib/plugins/I18nSplitPlugin/utils/createMetaManifest.js +10 -29
- package/lib/plugins/I18nSplitPlugin/utils/createRegularManifest.js +8 -19
- package/lib/plugins/I18nSplitPlugin/utils/getI18nFileUrlPathTemplate.js +0 -1
- package/lib/plugins/I18nSplitPlugin/utils/getI18nKeysFormModules.js +0 -5
- package/lib/plugins/I18nSplitPlugin/utils/hashUtils.js +1 -8
- package/lib/plugins/I18nSplitPlugin/utils/index.js +0 -4
- package/lib/plugins/I18nSplitPlugin/utils/propertiesUtils.js +0 -20
- package/lib/plugins/I18nSplitPlugin/utils/unicodeConversion.js +0 -1
- package/lib/plugins/ManifestPlugin.js +1 -18
- package/lib/plugins/MinifyPlugin.js +1 -10
- package/lib/plugins/ModuleStatsPlugin.js +1 -24
- package/lib/plugins/OptimizeJSPlugin.js +2 -10
- package/lib/plugins/PublicPathCallbackPlugin.js +1 -12
- package/lib/plugins/PublicPathChangePlugin.js +6 -39
- package/lib/plugins/ReportGeneratePlugin.js +5 -32
- package/lib/plugins/RequireVariablePublicPlugin.js +1 -8
- package/lib/plugins/ResourceHintsPlugin.js +4 -13
- package/lib/plugins/RtlSplitPlugin/OverwriteCssPathForRTL.js +12 -17
- package/lib/plugins/RtlSplitPlugin/RtlCssPlugin.js +10 -17
- package/lib/plugins/RtlSplitPlugin/replaceCssDirTemplate.js +2 -5
- package/lib/plugins/ScriptInstrumentPlugin.js +1 -8
- package/lib/plugins/SelectorPlugin.js +6 -32
- package/lib/plugins/ServiceWorkerPlugin.js +5 -22
- package/lib/plugins/ShadowDOMSupportPlugin.js +4 -41
- package/lib/plugins/SourceMapHookPlugin.js +2 -12
- package/lib/plugins/StatsPlugin.js +0 -14
- package/lib/plugins/TPHashMappingPlugin.js +3 -18
- package/lib/plugins/UnusedFilesFindPlugin.js +4 -39
- package/lib/plugins/VariableConversionCollector.js +15 -42
- package/lib/plugins/index.js +1 -20
- package/lib/plugins/libraryImpactPlugin.js +1 -33
- package/lib/plugins/newi18nsplitplugin/18nPlugin1.js +306 -0
- package/lib/plugins/newi18nsplitplugin/18nPlugin2.js +363 -0
- package/lib/plugins/newi18nsplitplugin/18nPlugin3.js +694 -0
- package/lib/plugins/newi18nsplitplugin/18nPlugin_hashed.js +1258 -0
- package/lib/plugins/newi18nsplitplugin/18nPlugin_working.js +542 -0
- package/lib/plugins/newi18nsplitplugin/18nplugin.js +974 -0
- package/lib/plugins/newi18nsplitplugin/ChunkManager.js +131 -0
- package/lib/plugins/newi18nsplitplugin/GenerateModuleIdToKeysMapPlugin.js +59 -0
- package/lib/plugins/newi18nsplitplugin/I18nDiffPlugin.js +262 -0
- package/lib/plugins/newi18nsplitplugin/I18nDownloadLogic.js +166 -0
- package/lib/plugins/newi18nsplitplugin/I18nPropertiesPlugin.js +111 -0
- package/lib/plugins/newi18nsplitplugin/KeyCollector.js +163 -0
- package/lib/plugins/newi18nsplitplugin/ManifestGenerator.js +88 -0
- package/lib/plugins/newi18nsplitplugin/UnicodeConversionPlugin.js +101 -0
- package/lib/plugins/newi18nsplitplugin/constants.js +162 -0
- package/lib/plugins/newi18nsplitplugin/utils/I18nKeyHasher.js +78 -0
- package/lib/plugins/newi18nsplitplugin/utils/getJsResourceKeys.js +22 -0
- package/lib/plugins/newi18nsplitplugin/utils/i18nChunkUtils.js +18 -0
- package/lib/plugins/newi18nsplitplugin/utils/manifestGenerator.js +580 -0
- package/lib/plugins/newi18nsplitplugin/utils/propertiesUtils.js +54 -0
- package/lib/plugins/utils/classHandling.js +0 -6
- package/lib/plugins/utils/fileHandling.js +6 -15
- package/lib/plugins/utils/tests/fileHandling.test.js +0 -4
- package/lib/plugins/variableConvertorUtils.js +14 -29
- package/lib/plugins/webpackwatchrunplugin.js +0 -5
- package/lib/postcss-plugins/EmptyPlugin.js +3 -4
- package/lib/postcss-plugins/ExcludePlugin.js +1 -5
- package/lib/postcss-plugins/IncludePlugin.js +1 -5
- package/lib/postcss-plugins/RTLSplitPlugin.js +14 -27
- package/lib/postcss-plugins/SelectorReplace.js +1 -16
- package/lib/postcss-plugins/ValueReplacer.js +7 -6
- package/lib/postcss-plugins/__test__/hoverActivePlugin.spec.js +0 -3
- package/lib/postcss-plugins/__test__/selectorReplace.test.js +6 -3
- package/lib/postcss-plugins/__test__/valueReplacer.spec.js +2 -5
- package/lib/postcss-plugins/hoverActivePlugin.js +31 -67
- package/lib/postcss-plugins/variableModificationPlugin/ErrorHandler.js +0 -7
- package/lib/postcss-plugins/variableModificationPlugin/index.js +28 -49
- package/lib/schemas/index.js +3 -9
- package/lib/servers/clusterHubServer.js +1 -11
- package/lib/servers/devBuild.js +14 -26
- package/lib/servers/docsServer.js +1 -3
- package/lib/servers/docsServerCore.js +1 -22
- package/lib/servers/getCliPath.js +0 -9
- package/lib/servers/helpServer.js +1 -6
- package/lib/servers/httpsOptions.js +2 -8
- package/lib/servers/impactServer.js +3 -35
- package/lib/servers/mockserver.js +1 -10
- package/lib/servers/nowatchserver.js +12 -37
- package/lib/servers/requireLocalOrGlobal.js +6 -17
- package/lib/servers/scrServer.js +14 -21
- package/lib/servers/server.js +6 -36
- package/lib/servers/ssServer.js +1 -17
- package/lib/templates/CoverageScriptTemplate.js +0 -14
- package/lib/templates/WMSTemplate.js +7 -13
- package/lib/templates/linterConstant.js +2 -4
- package/lib/utils/babelPresets.js +3 -7
- package/lib/utils/clean.js +3 -9
- package/lib/utils/copy.js +1 -7
- package/lib/utils/copyTimezones.js +1 -9
- package/lib/utils/createEventStream.js +1 -6
- package/lib/utils/cssClassNameGenerate.js +10 -30
- package/lib/utils/cssURLReplacer.js +1 -22
- package/lib/utils/dependencyPostPublish.js +1 -10
- package/lib/utils/deprecationSupport.js +7 -32
- package/lib/utils/fileUtils.js +1 -28
- package/lib/utils/folderIterator.js +2 -13
- package/lib/utils/getComponents.js +0 -21
- package/lib/utils/getCurrentBranch.js +0 -5
- package/lib/utils/getDependenciesImpactList.js +1 -22
- package/lib/utils/getFileType.js +2 -10
- package/lib/utils/getHash.js +1 -8
- package/lib/utils/getIp.js +0 -2
- package/lib/utils/getOptions.js +16 -53
- package/lib/utils/getServerURL.js +1 -10
- package/lib/utils/index.js +4 -51
- package/lib/utils/init.js +0 -1
- package/lib/utils/initPreCommitHook.js +7 -30
- package/lib/utils/jsonHelper.js +3 -22
- package/lib/utils/libraryImpactConfig.js +2 -5
- package/lib/utils/lint/addScripts.js +2 -5
- package/lib/utils/lint/checkExistingConfig.js +3 -12
- package/lib/utils/lint/copyConfigs.js +0 -3
- package/lib/utils/lint/index.js +0 -9
- package/lib/utils/lint/lintScripts.js +0 -1
- package/lib/utils/lint/lintSetup.js +3 -4
- package/lib/utils/lint/lintStagedPreCommitHook.js +0 -1
- package/lib/utils/lint/question.js +0 -7
- package/lib/utils/lintReporter.js +0 -20
- package/lib/utils/log.js +0 -1
- package/lib/utils/mailSender.js +1 -8
- package/lib/utils/object-manipulation.js +1 -17
- package/lib/utils/pullOrigin.js +0 -4
- package/lib/utils/reinstallDependencies.js +1 -29
- package/lib/utils/removeAttributes.js +1 -8
- package/lib/utils/repoClone.js +3 -28
- package/lib/utils/request.js +0 -12
- package/lib/utils/rtl.js +5 -17
- package/lib/utils/selectorReplacer.js +10 -16
- package/lib/utils/setEnvVariables.js +0 -2
- package/lib/utils/ssTestHack.js +1 -11
- package/lib/utils/switchBranch.js +0 -5
- package/lib/utils/typeCheck.js +0 -1
- package/lib/utils/urlConcat.js +0 -4
- package/lib/utils/useExitCleanup.js +9 -10
- package/lib/utils/variableConverter.js +22 -31
- package/{npm-shrinkwrap.json → package-lock.json} +2098 -1999
- package/package.json +1 -1
@@ -0,0 +1,1258 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
// // const { getAllI18nGroupedBySection, getPropertiesAsJSON } = require('../I18nSplitPlugin/utils/propertiesUtils');
|
4
|
+
// // const { collectI18nKeysfromAST, collectI18nKeysfromComments } = require('../I18nSplitPlugin/utils/collectI18nKeys');
|
5
|
+
// // const NullFactory = require('webpack/lib/NullFactory');
|
6
|
+
// // const { I18nDependency, I18nDependencyTemplate } = require('../I18nSplitPlugin/I18nDependency');
|
7
|
+
// // const { RawSource } = require('webpack-sources');
|
8
|
+
// // const crypto = require('crypto');
|
9
|
+
// // const escodegen = require('escodegen');
|
10
|
+
// // const pluginName = 'I18nPlugin';
|
11
|
+
// // const esprima = require('esprima');
|
12
|
+
// // class I18nPlugin {
|
13
|
+
// // constructor(options = {}) {
|
14
|
+
// // const { jsResourcePath, mainChunkName, propertiesFolder, disableDefault, jsResource } = options;
|
15
|
+
// // if (!jsResourcePath) {
|
16
|
+
// // throw new Error('I18nPlugin: "jsResourcePath" option is required.');
|
17
|
+
// // }
|
18
|
+
// // if (!mainChunkName) {
|
19
|
+
// // throw new Error('I18nPlugin: "mainChunkName" option is required.');
|
20
|
+
// // }
|
21
|
+
// // this.jsResourcePath = jsResourcePath;
|
22
|
+
// // this.entryPointName = mainChunkName;
|
23
|
+
// // this.jsResourceI18nKeys = jsResource ? getPropertiesAsJSON(jsResource) : {};
|
24
|
+
// // // Use getAllI18nGroupedBySection to group keys by sections
|
25
|
+
// // this.allI18nKeys = getAllI18nGroupedBySection({
|
26
|
+
// // folderPath: propertiesFolder,
|
27
|
+
// // disableDefault,
|
28
|
+
// // jsResourceI18nKeys: this.jsResourceI18nKeys,
|
29
|
+
// // });
|
30
|
+
// // console.log('Locales found:', Object.keys(this.allI18nKeys));
|
31
|
+
// // // Build keyToSectionMap
|
32
|
+
// // this.keyToSectionMap = {};
|
33
|
+
// // const locales = Object.keys(this.allI18nKeys);
|
34
|
+
// // if (locales.length > 0) {
|
35
|
+
// // // Use the first locale to build keyToSectionMap
|
36
|
+
// // const firstLocale = locales[0];
|
37
|
+
// // const sections = this.allI18nKeys[firstLocale];
|
38
|
+
// // console.log(`Sections found in properties files: ${Object.keys(sections).join(', ')}`);
|
39
|
+
// // for (const sectionName of Object.keys(sections)) {
|
40
|
+
// // const keysInSection = sections[sectionName];
|
41
|
+
// // for (const key of Object.keys(keysInSection)) {
|
42
|
+
// // this.keyToSectionMap[key] = sectionName;
|
43
|
+
// // }
|
44
|
+
// // }
|
45
|
+
// // }
|
46
|
+
// // this.moduleToKeysMap = new Map();
|
47
|
+
// // this.keyToModulesMap = new Map();
|
48
|
+
// // this.keyToI18nChunkIdMap = {};
|
49
|
+
// // // Initialize keyToHashMap and getHash function
|
50
|
+
// // this.keyToHashMap = {};
|
51
|
+
// // this.getHash = (key) => {
|
52
|
+
// // if (!this.keyToHashMap[key]) {
|
53
|
+
// // const hash = crypto.createHash('md5').update(key).digest('hex').substring(0, 8);
|
54
|
+
// // this.keyToHashMap[key] = hash;
|
55
|
+
// // }
|
56
|
+
// // return this.keyToHashMap[key];
|
57
|
+
// // };
|
58
|
+
// // // Process allI18nKeys to replace keys with hashes
|
59
|
+
// // for (const locale of locales) {
|
60
|
+
// // const sections = this.allI18nKeys[locale];
|
61
|
+
// // for (const sectionName in sections) {
|
62
|
+
// // const section = sections[sectionName];
|
63
|
+
// // const newSection = {};
|
64
|
+
// // for (const key in section) {
|
65
|
+
// // const hash = this.getHash(key);
|
66
|
+
// // newSection[hash] = section[key];
|
67
|
+
// // }
|
68
|
+
// // sections[sectionName] = newSection;
|
69
|
+
// // }
|
70
|
+
// // }
|
71
|
+
// // }
|
72
|
+
// // defineI18nDependency(compilation) {
|
73
|
+
// // compilation.dependencyFactories.set(I18nDependency, new NullFactory());
|
74
|
+
// // compilation.dependencyTemplates.set(I18nDependency, new I18nDependencyTemplate());
|
75
|
+
// // }
|
76
|
+
// // apply(compiler) {
|
77
|
+
// // compiler.hooks.thisCompilation.tap(pluginName, (compilation, params) => {
|
78
|
+
// // this.defineI18nDependency(compilation);
|
79
|
+
// // // Handler for parser
|
80
|
+
// // const handler = parser => {
|
81
|
+
// // parser.hooks.program.tap(pluginName, (ast, comments) => {
|
82
|
+
// // const { module } = parser.state;
|
83
|
+
// // if (!(module && /\.jsx?$/.test(module.resource))) {
|
84
|
+
// // return;
|
85
|
+
// // }
|
86
|
+
// // // Collect and replace i18n keys
|
87
|
+
// // let i18nKeys = collectI18nKeysfromAST(ast, this.jsResourceI18nKeys, this.getHash);
|
88
|
+
// // // let commentKeys = collectI18nKeysfromComments(comments, this.jsResourceI18nKeys);
|
89
|
+
// // // i18nKeys = i18nKeys.concat(commentKeys);
|
90
|
+
// // if (i18nKeys.length) {
|
91
|
+
// // try {
|
92
|
+
// // const code = escodegen.generate(ast, { comment: true });
|
93
|
+
// // // Update the module's source code
|
94
|
+
// // module._source._value = code;
|
95
|
+
// // } catch (error) {
|
96
|
+
// // console.error(`Syntax error in generated code for module ${module.resource}:`, error);
|
97
|
+
// // }
|
98
|
+
// // // const code = escodegen.generate(ast, { comment: true });
|
99
|
+
// // // module._source._value = code;
|
100
|
+
// // // Store the hashed keys for this module
|
101
|
+
// // const hashedKeys = i18nKeys.map(key => this.getHash(key));
|
102
|
+
// // this.moduleToKeysMap.set(module.resource, hashedKeys);
|
103
|
+
// // // Map hashed keys to modules
|
104
|
+
// // for (const hash of hashedKeys) {
|
105
|
+
// // if (!this.keyToModulesMap.has(hash)) {
|
106
|
+
// // this.keyToModulesMap.set(hash, new Set());
|
107
|
+
// // }
|
108
|
+
// // this.keyToModulesMap.get(hash).add(module.resource);
|
109
|
+
// // }
|
110
|
+
// // }
|
111
|
+
// // });
|
112
|
+
// // };
|
113
|
+
// // const factory = params.normalModuleFactory;
|
114
|
+
// // factory.hooks.parser.for('javascript/auto').tap(pluginName, handler);
|
115
|
+
// // factory.hooks.parser.for('javascript/dynamic').tap(pluginName, handler);
|
116
|
+
// // compilation.hooks.afterOptimizeChunks.tap(pluginName, () => {
|
117
|
+
// // this.processCollectedKeys(compilation);
|
118
|
+
// // });
|
119
|
+
// // });
|
120
|
+
// // }
|
121
|
+
// // processCollectedKeys(compilation) {
|
122
|
+
// // // Map to store chunkId to required sections
|
123
|
+
// // this.chunkIdToSectionsMap = {};
|
124
|
+
// // this.moduleChunkIdToModulesMap = {};
|
125
|
+
// // // Map module resource to chunk IDs
|
126
|
+
// // this.moduleResourceToChunkIds = new Map();
|
127
|
+
// // // Collect modules for the entry point
|
128
|
+
// // const entryPointChunk = compilation.namedChunks.get(this.entryPointName);
|
129
|
+
// // const entryPointModules = new Set();
|
130
|
+
// // if (entryPointChunk) {
|
131
|
+
// // for (const module of entryPointChunk.getModules()) {
|
132
|
+
// // if (module.resource) {
|
133
|
+
// // entryPointModules.add(module.resource);
|
134
|
+
// // }
|
135
|
+
// // }
|
136
|
+
// // }
|
137
|
+
// // // Iterate over all chunks in the compilation
|
138
|
+
// // for (const chunk of compilation.chunks) {
|
139
|
+
// // const chunkId = chunk.name || chunk.id;
|
140
|
+
// // const chunkIdString = String(chunkId);
|
141
|
+
// // // Collect all modules in the chunk
|
142
|
+
// // const modules = chunk.getModules();
|
143
|
+
// // let requiredSections = new Set();
|
144
|
+
// // let moduleResources = [];
|
145
|
+
// // for (const module of modules) {
|
146
|
+
// // const moduleResource = module.resource;
|
147
|
+
// // if (moduleResource) {
|
148
|
+
// // moduleResources.push(moduleResource);
|
149
|
+
// // const keys = this.moduleToKeysMap.get(moduleResource);
|
150
|
+
// // if (keys) {
|
151
|
+
// // for (const key of keys) {
|
152
|
+
// // const section = this.keyToSectionMap[key];
|
153
|
+
// // if (section) {
|
154
|
+
// // requiredSections.add(section);
|
155
|
+
// // }
|
156
|
+
// // }
|
157
|
+
// // }
|
158
|
+
// // // Map module resource to chunk IDs
|
159
|
+
// // if (!this.moduleResourceToChunkIds.has(moduleResource)) {
|
160
|
+
// // this.moduleResourceToChunkIds.set(moduleResource, new Set());
|
161
|
+
// // }
|
162
|
+
// // this.moduleResourceToChunkIds.get(moduleResource).add(chunkIdString);
|
163
|
+
// // }
|
164
|
+
// // }
|
165
|
+
// // // Store in the map if there are required sections
|
166
|
+
// // if (requiredSections.size > 0) {
|
167
|
+
// // this.chunkIdToSectionsMap[chunkIdString] = Array.from(requiredSections);
|
168
|
+
// // }
|
169
|
+
// // // Map chunkId to module resources
|
170
|
+
// // if (moduleResources.length > 0) {
|
171
|
+
// // this.moduleChunkIdToModulesMap[chunkIdString] = moduleResources;
|
172
|
+
// // }
|
173
|
+
// // }
|
174
|
+
// // // Collect all used keys
|
175
|
+
// // this.allUsedKeys = new Set();
|
176
|
+
// // for (const keys of this.moduleToKeysMap.values()) {
|
177
|
+
// // for (const key of keys) {
|
178
|
+
// // this.allUsedKeys.add(key);
|
179
|
+
// // }
|
180
|
+
// // }
|
181
|
+
// // // Collect entry point keys
|
182
|
+
// // this.entryPointKeys = new Set();
|
183
|
+
// // for (const moduleResource of entryPointModules) {
|
184
|
+
// // const keys = this.moduleToKeysMap.get(moduleResource);
|
185
|
+
// // if (keys) {
|
186
|
+
// // for (const key of keys) {
|
187
|
+
// // this.entryPointKeys.add(key);
|
188
|
+
// // }
|
189
|
+
// // }
|
190
|
+
// // }
|
191
|
+
// // // Collect unused keys
|
192
|
+
// // this.allKeysInProperties = new Set();
|
193
|
+
// // const firstLocale = Object.keys(this.allI18nKeys)[0];
|
194
|
+
// // const sections = this.allI18nKeys[firstLocale];
|
195
|
+
// // for (const section of Object.values(sections)) {
|
196
|
+
// // for (const key of Object.keys(section)) {
|
197
|
+
// // this.allKeysInProperties.add(key);
|
198
|
+
// // }
|
199
|
+
// // }
|
200
|
+
// // this.unusedKeys = new Set([...this.allKeysInProperties].filter(key => !this.allUsedKeys.has(key)));
|
201
|
+
// // // Remove entry point keys from allUsedKeys
|
202
|
+
// // this.remainingKeys = new Set([...this.allUsedKeys].filter(key => !this.entryPointKeys.has(key)));
|
203
|
+
// // // Emit the i18n chunks
|
204
|
+
// // this.emitI18nChunks(compilation);
|
205
|
+
// // }
|
206
|
+
// // getValueForKeyInLocale(key, locale) {
|
207
|
+
// // const sections = this.allI18nKeys[locale];
|
208
|
+
// // for (const sectionName in sections) {
|
209
|
+
// // const section = sections[sectionName];
|
210
|
+
// // if (key in section) {
|
211
|
+
// // return section[key];
|
212
|
+
// // }
|
213
|
+
// // }
|
214
|
+
// // return undefined;
|
215
|
+
// // }
|
216
|
+
// // emitI18nChunks(compilation) {
|
217
|
+
// // const manifest = {
|
218
|
+
// // moduleToI18nChunkMap: {},
|
219
|
+
// // locales: {},
|
220
|
+
// // };
|
221
|
+
// // // Get the list of locales
|
222
|
+
// // const locales = Object.keys(this.allI18nKeys);
|
223
|
+
// // const firstLocale = locales[0];
|
224
|
+
// // // Map from i18nChunkId to keys
|
225
|
+
// // const i18nChunkIdToKeysMap = {};
|
226
|
+
// // let i18nChunkIdCounter = 0;
|
227
|
+
// // // **Chunk 0**: Entry Point Keys
|
228
|
+
// // const entryPointChunkId = i18nChunkIdCounter++;
|
229
|
+
// // i18nChunkIdToKeysMap[entryPointChunkId] = Array.from(this.entryPointKeys);
|
230
|
+
// // for (const key of this.entryPointKeys) {
|
231
|
+
// // this.keyToI18nChunkIdMap[key] = entryPointChunkId;
|
232
|
+
// // }
|
233
|
+
// // // **Last Chunk**: Unused Keys
|
234
|
+
// // const unusedKeysChunkId = 'unused'; // Using a string to make it distinct
|
235
|
+
// // i18nChunkIdToKeysMap[unusedKeysChunkId] = Array.from(this.unusedKeys);
|
236
|
+
// // // Remaining Keys: Group into chunks of ~30KB
|
237
|
+
// // let currentChunkKeys = [];
|
238
|
+
// // let currentChunkSize = 0;
|
239
|
+
// // const desiredChunkSize = 100* 1024; // 30KB
|
240
|
+
// // for (const key of this.remainingKeys) {
|
241
|
+
// // const value = this.getValueForKeyInLocale(key, firstLocale);
|
242
|
+
// // const keySize = Buffer.byteLength(key, 'utf8') + Buffer.byteLength(value || '', 'utf8');
|
243
|
+
// // if (currentChunkSize + keySize > desiredChunkSize) {
|
244
|
+
// // // Assign current chunk
|
245
|
+
// // const i18nChunkId = i18nChunkIdCounter++;
|
246
|
+
// // i18nChunkIdToKeysMap[i18nChunkId] = currentChunkKeys;
|
247
|
+
// // // Map keys to i18nChunkId
|
248
|
+
// // for (const chunkKey of currentChunkKeys) {
|
249
|
+
// // this.keyToI18nChunkIdMap[chunkKey] = i18nChunkId;
|
250
|
+
// // }
|
251
|
+
// // // Start a new chunk
|
252
|
+
// // currentChunkKeys = [];
|
253
|
+
// // currentChunkSize = 0;
|
254
|
+
// // }
|
255
|
+
// // currentChunkKeys.push(key);
|
256
|
+
// // currentChunkSize += keySize;
|
257
|
+
// // }
|
258
|
+
// // // Assign the remaining keys
|
259
|
+
// // if (currentChunkKeys.length > 0) {
|
260
|
+
// // const i18nChunkId = i18nChunkIdCounter++;
|
261
|
+
// // i18nChunkIdToKeysMap[i18nChunkId] = currentChunkKeys;
|
262
|
+
// // // Map keys to i18nChunkId
|
263
|
+
// // for (const chunkKey of currentChunkKeys) {
|
264
|
+
// // this.keyToI18nChunkIdMap[chunkKey] = i18nChunkId;
|
265
|
+
// // }
|
266
|
+
// // }
|
267
|
+
// // // Now, generate the i18n chunks for each locale
|
268
|
+
// // for (const locale of locales) {
|
269
|
+
// // manifest.locales[locale] = manifest.locales[locale] || {};
|
270
|
+
// // for (const [i18nChunkId, keys] of Object.entries(i18nChunkIdToKeysMap)) {
|
271
|
+
// // const i18nData = {};
|
272
|
+
// // for (const key of keys) {
|
273
|
+
// // const value = this.getValueForKeyInLocale(key, locale);
|
274
|
+
// // if (value !== undefined) {
|
275
|
+
// // i18nData[key] = value;
|
276
|
+
// // }
|
277
|
+
// // }
|
278
|
+
// // if (Object.keys(i18nData).length > 0) {
|
279
|
+
// // const moduleSource = `window.loadI18nChunk(${JSON.stringify(i18nData, null, 2)});`;
|
280
|
+
// // const filename = `i18n-chunks/${locale}/chunk-${i18nChunkId}.js`;
|
281
|
+
// // compilation.emitAsset(filename, new RawSource(moduleSource));
|
282
|
+
// // manifest.locales[locale][i18nChunkId] = filename;
|
283
|
+
// // console.log(`Emitted i18n chunk: ${filename}`);
|
284
|
+
// // }
|
285
|
+
// // }
|
286
|
+
// // }
|
287
|
+
// // // Now, create moduleToI18nChunkMap
|
288
|
+
// // for (const [moduleChunkId, moduleResources] of Object.entries(this.moduleChunkIdToModulesMap)) {
|
289
|
+
// // const requiredI18nChunkIds = new Set();
|
290
|
+
// // for (const moduleResource of moduleResources) {
|
291
|
+
// // const keys = this.moduleToKeysMap.get(moduleResource);
|
292
|
+
// // if (keys) {
|
293
|
+
// // for (const key of keys) {
|
294
|
+
// // const i18nChunkId = this.keyToI18nChunkIdMap[key];
|
295
|
+
// // if (i18nChunkId !== undefined) {
|
296
|
+
// // requiredI18nChunkIds.add(i18nChunkId);
|
297
|
+
// // }
|
298
|
+
// // }
|
299
|
+
// // }
|
300
|
+
// // }
|
301
|
+
// // if (requiredI18nChunkIds.size > 0) {
|
302
|
+
// // manifest.moduleToI18nChunkMap[moduleChunkId] = Array.from(requiredI18nChunkIds);
|
303
|
+
// // } else {
|
304
|
+
// // console.log(`No required i18n chunks for module chunk ID ${moduleChunkId}`);
|
305
|
+
// // }
|
306
|
+
// // }
|
307
|
+
// // // Ensure that the main chunk always requires chunk zero
|
308
|
+
// // manifest.moduleToI18nChunkMap[this.entryPointName] = manifest.moduleToI18nChunkMap[this.entryPointName] || [];
|
309
|
+
// // if (!manifest.moduleToI18nChunkMap[this.entryPointName].includes(entryPointChunkId)) {
|
310
|
+
// // manifest.moduleToI18nChunkMap[this.entryPointName].unshift(entryPointChunkId);
|
311
|
+
// // }
|
312
|
+
// // // Emit the manifest file
|
313
|
+
// // const manifestSource = new RawSource(
|
314
|
+
// // `window.i18n = window.i18n || {}; window.i18n.manifest = ${JSON.stringify(manifest, null, 2)};`
|
315
|
+
// // );
|
316
|
+
// // const manifestFilename = 'i18n-chunks/manifest.js';
|
317
|
+
// // compilation.emitAsset(manifestFilename, manifestSource);
|
318
|
+
// // console.log(`Emitted i18n manifest: ${manifestFilename}`);
|
319
|
+
// // }
|
320
|
+
// // }
|
321
|
+
// // module.exports = I18nPlugin;
|
322
|
+
// const { getAllI18nGroupedBySection, getPropertiesAsJSON } = require('../I18nSplitPlugin/utils/propertiesUtils');
|
323
|
+
// const { collectI18nKeysfromAST, collectI18nKeysfromComments } = require('../I18nSplitPlugin/utils/collectI18nKeys');
|
324
|
+
// const { I18nDependency, I18nDependencyTemplate } = require('../I18nSplitPlugin/I18nDependency');
|
325
|
+
// const { RawSource } = require('webpack-sources');
|
326
|
+
// const crypto = require('crypto');
|
327
|
+
// const escodegen = require('escodegen');
|
328
|
+
// const esprima = require('esprima');
|
329
|
+
// const NullFactory = require('webpack/lib/NullFactory');
|
330
|
+
// const { walk } = require('estree-walker');
|
331
|
+
// // const pluginName = 'I18nPlugin';
|
332
|
+
// // class I18nPlugin {
|
333
|
+
// // constructor(options = {}) {
|
334
|
+
// // const { jsResourcePath, mainChunkName, propertiesFolder, disableDefault, jsResource } = options;
|
335
|
+
// // if (!jsResourcePath) {
|
336
|
+
// // throw new Error('I18nPlugin: "jsResourcePath" option is required.');
|
337
|
+
// // }
|
338
|
+
// // if (!mainChunkName) {
|
339
|
+
// // throw new Error('I18nPlugin: "mainChunkName" option is required.');
|
340
|
+
// // }
|
341
|
+
// // this.jsResourcePath = jsResourcePath;
|
342
|
+
// // this.entryPointName = mainChunkName;
|
343
|
+
// // this.jsResourceI18nKeys = jsResource || {};
|
344
|
+
// // // Initialize collection maps
|
345
|
+
// // this.moduleToKeysMap = new Map();
|
346
|
+
// // this.keyToModulesMap = new Map();
|
347
|
+
// // this.keyToI18nChunkIdMap = {};
|
348
|
+
// // this.keyToHashMap = {};
|
349
|
+
// // // Initialize hash function
|
350
|
+
// // this.getHash = (key) => {
|
351
|
+
// // if (!this.keyToHashMap[key]) {
|
352
|
+
// // const hash = crypto.createHash('md5').update(key).digest('hex').substring(0, 8);
|
353
|
+
// // this.keyToHashMap[key] = hash;
|
354
|
+
// // }
|
355
|
+
// // return this.keyToHashMap[key];
|
356
|
+
// // };
|
357
|
+
// // }
|
358
|
+
// // // Process source code and collect i18n keys
|
359
|
+
// // processModule(module) {
|
360
|
+
// // if (!module.resource || !module.resource.endsWith('.js')) {
|
361
|
+
// // return [];
|
362
|
+
// // }
|
363
|
+
// // try {
|
364
|
+
// // const source = module._source._value;
|
365
|
+
// // // Parse the source code
|
366
|
+
// // const ast = esprima.parse(source, {
|
367
|
+
// // comment: true,
|
368
|
+
// // tokens: true,
|
369
|
+
// // range: true,
|
370
|
+
// // loc: true
|
371
|
+
// // });
|
372
|
+
// // const i18nKeys = new Set();
|
373
|
+
// // // Process the AST
|
374
|
+
// // walk(ast, {
|
375
|
+
// // enter: (node) => {
|
376
|
+
// // if (node.type === 'Literal' && typeof node.value === 'string') {
|
377
|
+
// // const key = node.value;
|
378
|
+
// // if (Object.prototype.hasOwnProperty.call(this.jsResourceI18nKeys, key)) {
|
379
|
+
// // i18nKeys.add(key);
|
380
|
+
// // const hash = this.getHash(key);
|
381
|
+
// // node.value = hash;
|
382
|
+
// // node.raw = `'${hash}'`;
|
383
|
+
// // }
|
384
|
+
// // }
|
385
|
+
// // }
|
386
|
+
// // });
|
387
|
+
// // // Generate modified code if keys were found
|
388
|
+
// // if (i18nKeys.size > 0) {
|
389
|
+
// // try {
|
390
|
+
// // const modifiedCode = escodegen.generate(ast, {
|
391
|
+
// // comment: true,
|
392
|
+
// // format: {
|
393
|
+
// // indent: {
|
394
|
+
// // style: ' ',
|
395
|
+
// // base: 0
|
396
|
+
// // },
|
397
|
+
// // preserveBlankLines: true
|
398
|
+
// // }
|
399
|
+
// // });
|
400
|
+
// // module._source._value = modifiedCode;
|
401
|
+
// // } catch (error) {
|
402
|
+
// // console.error(`Error generating code for ${module.resource}:`, error);
|
403
|
+
// // }
|
404
|
+
// // }
|
405
|
+
// // return Array.from(i18nKeys);
|
406
|
+
// // } catch (error) {
|
407
|
+
// // console.error(`Error processing module ${module.resource}:`, error);
|
408
|
+
// // return [];
|
409
|
+
// // }
|
410
|
+
// // }
|
411
|
+
// // apply(compiler) {
|
412
|
+
// // // Process modules during compilation
|
413
|
+
// // compiler.hooks.compilation.tap('I18nPlugin', (compilation) => {
|
414
|
+
// // // Process modules after they are loaded
|
415
|
+
// // compilation.hooks.optimizeModules.tap('I18nPlugin', (modules) => {
|
416
|
+
// // modules.forEach(module => {
|
417
|
+
// // const keys = this.processModule(module);
|
418
|
+
// // if (keys.length > 0) {
|
419
|
+
// // // Update module to keys mapping
|
420
|
+
// // this.moduleToKeysMap.set(module.resource, keys);
|
421
|
+
// // // Update keys to modules mapping
|
422
|
+
// // keys.forEach(key => {
|
423
|
+
// // if (!this.keyToModulesMap.has(key)) {
|
424
|
+
// // this.keyToModulesMap.set(key, new Set());
|
425
|
+
// // }
|
426
|
+
// // this.keyToModulesMap.get(key).add(module.resource);
|
427
|
+
// // });
|
428
|
+
// // }
|
429
|
+
// // });
|
430
|
+
// // });
|
431
|
+
// // // Process chunks after optimization
|
432
|
+
// // compilation.hooks.afterOptimizeChunks.tap('I18nPlugin', () => {
|
433
|
+
// // this.processCollectedKeys(compilation);
|
434
|
+
// // });
|
435
|
+
// // });
|
436
|
+
// // }
|
437
|
+
// // processCollectedKeys(compilation) {
|
438
|
+
// // // Map chunk IDs to sections and modules
|
439
|
+
// // this.chunkIdToSectionsMap = {};
|
440
|
+
// // this.moduleChunkIdToModulesMap = {};
|
441
|
+
// // this.moduleResourceToChunkIds = new Map();
|
442
|
+
// // // Process entry point modules
|
443
|
+
// // const entryPointChunk = compilation.namedChunks.get(this.entryPointName);
|
444
|
+
// // const entryPointModules = new Set();
|
445
|
+
// // if (entryPointChunk) {
|
446
|
+
// // for (const module of entryPointChunk.getModules()) {
|
447
|
+
// // if (module.resource) {
|
448
|
+
// // entryPointModules.add(module.resource);
|
449
|
+
// // }
|
450
|
+
// // }
|
451
|
+
// // }
|
452
|
+
// // // Process each chunk
|
453
|
+
// // for (const chunk of compilation.chunks) {
|
454
|
+
// // const chunkId = chunk.name || chunk.id;
|
455
|
+
// // const chunkIdString = String(chunkId);
|
456
|
+
// // const moduleResources = [];
|
457
|
+
// // // Collect modules for this chunk
|
458
|
+
// // for (const module of chunk.getModules()) {
|
459
|
+
// // if (module.resource) {
|
460
|
+
// // moduleResources.push(module.resource);
|
461
|
+
// // // Map module resource to chunk IDs
|
462
|
+
// // if (!this.moduleResourceToChunkIds.has(module.resource)) {
|
463
|
+
// // this.moduleResourceToChunkIds.set(module.resource, new Set());
|
464
|
+
// // }
|
465
|
+
// // this.moduleResourceToChunkIds.get(module.resource).add(chunkIdString);
|
466
|
+
// // }
|
467
|
+
// // }
|
468
|
+
// // // Store module resources for this chunk
|
469
|
+
// // if (moduleResources.length > 0) {
|
470
|
+
// // this.moduleChunkIdToModulesMap[chunkIdString] = moduleResources;
|
471
|
+
// // }
|
472
|
+
// // }
|
473
|
+
// // // Collect used and unused keys
|
474
|
+
// // this.collectKeyStats(entryPointModules);
|
475
|
+
// // // Emit the i18n chunks
|
476
|
+
// // this.emitI18nChunks(compilation);
|
477
|
+
// // }
|
478
|
+
// // collectKeyStats(entryPointModules) {
|
479
|
+
// // // Collect all used keys
|
480
|
+
// // this.allUsedKeys = new Set();
|
481
|
+
// // for (const keys of this.moduleToKeysMap.values()) {
|
482
|
+
// // for (const key of keys) {
|
483
|
+
// // this.allUsedKeys.add(key);
|
484
|
+
// // }
|
485
|
+
// // }
|
486
|
+
// // // Collect entry point keys
|
487
|
+
// // this.entryPointKeys = new Set();
|
488
|
+
// // for (const moduleResource of entryPointModules) {
|
489
|
+
// // const keys = this.moduleToKeysMap.get(moduleResource);
|
490
|
+
// // if (keys) {
|
491
|
+
// // for (const key of keys) {
|
492
|
+
// // this.entryPointKeys.add(key);
|
493
|
+
// // }
|
494
|
+
// // }
|
495
|
+
// // }
|
496
|
+
// // // Calculate remaining and unused keys
|
497
|
+
// // this.allKeysInProperties = new Set(Object.keys(this.jsResourceI18nKeys));
|
498
|
+
// // this.unusedKeys = new Set(
|
499
|
+
// // [...this.allKeysInProperties].filter(key => !this.allUsedKeys.has(key))
|
500
|
+
// // );
|
501
|
+
// // this.remainingKeys = new Set(
|
502
|
+
// // [...this.allUsedKeys].filter(key => !this.entryPointKeys.has(key))
|
503
|
+
// // );
|
504
|
+
// // }
|
505
|
+
// // emitI18nChunks(compilation) {
|
506
|
+
// // const manifest = {
|
507
|
+
// // moduleToI18nChunkMap: {},
|
508
|
+
// // locales: { default: {} }
|
509
|
+
// // };
|
510
|
+
// // // Map from i18nChunkId to keys
|
511
|
+
// // const i18nChunkIdToKeysMap = {};
|
512
|
+
// // let i18nChunkIdCounter = 0;
|
513
|
+
// // // Entry Point Keys (Chunk 0)
|
514
|
+
// // const entryPointChunkId = i18nChunkIdCounter++;
|
515
|
+
// // i18nChunkIdToKeysMap[entryPointChunkId] = Array.from(this.entryPointKeys);
|
516
|
+
// // for (const key of this.entryPointKeys) {
|
517
|
+
// // this.keyToI18nChunkIdMap[key] = entryPointChunkId;
|
518
|
+
// // }
|
519
|
+
// // // Unused Keys
|
520
|
+
// // const unusedKeysChunkId = 'unused';
|
521
|
+
// // i18nChunkIdToKeysMap[unusedKeysChunkId] = Array.from(this.unusedKeys);
|
522
|
+
// // // Process remaining keys into chunks
|
523
|
+
// // const chunkSize = 100 * 1024; // 100KB chunks
|
524
|
+
// // let currentChunk = [];
|
525
|
+
// // let currentSize = 0;
|
526
|
+
// // for (const key of this.remainingKeys) {
|
527
|
+
// // const keySize = Buffer.byteLength(key, 'utf8') +
|
528
|
+
// // Buffer.byteLength(this.jsResourceI18nKeys[key] || '', 'utf8');
|
529
|
+
// // if (currentSize + keySize > chunkSize && currentChunk.length > 0) {
|
530
|
+
// // // Save current chunk
|
531
|
+
// // const chunkId = i18nChunkIdCounter++;
|
532
|
+
// // i18nChunkIdToKeysMap[chunkId] = currentChunk;
|
533
|
+
// // currentChunk.forEach(k => this.keyToI18nChunkIdMap[k] = chunkId);
|
534
|
+
// // // Start new chunk
|
535
|
+
// // currentChunk = [];
|
536
|
+
// // currentSize = 0;
|
537
|
+
// // }
|
538
|
+
// // currentChunk.push(key);
|
539
|
+
// // currentSize += keySize;
|
540
|
+
// // }
|
541
|
+
// // // Save last chunk if not empty
|
542
|
+
// // if (currentChunk.length > 0) {
|
543
|
+
// // const chunkId = i18nChunkIdCounter++;
|
544
|
+
// // i18nChunkIdToKeysMap[chunkId] = currentChunk;
|
545
|
+
// // currentChunk.forEach(k => this.keyToI18nChunkIdMap[k] = chunkId);
|
546
|
+
// // }
|
547
|
+
// // // Generate chunks
|
548
|
+
// // for (const [i18nChunkId, keys] of Object.entries(i18nChunkIdToKeysMap)) {
|
549
|
+
// // const i18nData = {};
|
550
|
+
// // for (const key of keys) {
|
551
|
+
// // const value = this.jsResourceI18nKeys[key];
|
552
|
+
// // if (value !== undefined) {
|
553
|
+
// // i18nData[this.getHash(key)] = value;
|
554
|
+
// // }
|
555
|
+
// // }
|
556
|
+
// // if (Object.keys(i18nData).length > 0) {
|
557
|
+
// // const chunkContent = `window.loadI18nChunk(${JSON.stringify(i18nData, null, 2)});`;
|
558
|
+
// // const filename = `i18n-chunks/default/chunk-${i18nChunkId}.js`;
|
559
|
+
// // compilation.emitAsset(filename, new RawSource(chunkContent));
|
560
|
+
// // manifest.locales.default[i18nChunkId] = filename;
|
561
|
+
// // }
|
562
|
+
// // }
|
563
|
+
// // // Build module to chunk mapping
|
564
|
+
// // for (const [moduleChunkId, moduleResources] of Object.entries(this.moduleChunkIdToModulesMap)) {
|
565
|
+
// // const requiredI18nChunkIds = new Set();
|
566
|
+
// // for (const moduleResource of moduleResources) {
|
567
|
+
// // const keys = this.moduleToKeysMap.get(moduleResource);
|
568
|
+
// // if (keys) {
|
569
|
+
// // for (const key of keys) {
|
570
|
+
// // const i18nChunkId = this.keyToI18nChunkIdMap[key];
|
571
|
+
// // if (i18nChunkId !== undefined) {
|
572
|
+
// // requiredI18nChunkIds.add(i18nChunkId);
|
573
|
+
// // }
|
574
|
+
// // }
|
575
|
+
// // }
|
576
|
+
// // }
|
577
|
+
// // if (requiredI18nChunkIds.size > 0) {
|
578
|
+
// // manifest.moduleToI18nChunkMap[moduleChunkId] = Array.from(requiredI18nChunkIds);
|
579
|
+
// // }
|
580
|
+
// // }
|
581
|
+
// // // Ensure entry point has chunk zero
|
582
|
+
// // manifest.moduleToI18nChunkMap[this.entryPointName] =
|
583
|
+
// // manifest.moduleToI18nChunkMap[this.entryPointName] || [];
|
584
|
+
// // if (!manifest.moduleToI18nChunkMap[this.entryPointName].includes(entryPointChunkId)) {
|
585
|
+
// // manifest.moduleToI18nChunkMap[this.entryPointName].unshift(entryPointChunkId);
|
586
|
+
// // }
|
587
|
+
// // // Emit manifest
|
588
|
+
// // const manifestContent =
|
589
|
+
// // `window.i18n = window.i18n || {}; window.i18n.manifest = ${JSON.stringify(manifest, null, 2)};`;
|
590
|
+
// // compilation.emitAsset('i18n-chunks/manifest.js', new RawSource(manifestContent));
|
591
|
+
// // }
|
592
|
+
// // }
|
593
|
+
// // module.exports = I18nPlugin;
|
594
|
+
// const NullFactory = require('webpack/lib/NullFactory');
|
595
|
+
// const { RawSource } = require('webpack-sources');
|
596
|
+
// const crypto = require('crypto');
|
597
|
+
// const { walk } = require('estree-walker');
|
598
|
+
// const parser = require('@babel/parser');
|
599
|
+
// const generate = require('@babel/generator').default;
|
600
|
+
// class I18nPlugin {
|
601
|
+
// constructor(options = {}) {
|
602
|
+
// const { jsResourcePath, mainChunkName, propertiesFolder, disableDefault, jsResource } = options;
|
603
|
+
// if (!jsResourcePath) {
|
604
|
+
// throw new Error('I18nPlugin: "jsResourcePath" option is required.');
|
605
|
+
// }
|
606
|
+
// if (!mainChunkName) {
|
607
|
+
// throw new Error('I18nPlugin: "mainChunkName" option is required.');
|
608
|
+
// }
|
609
|
+
// this.jsResourcePath = jsResourcePath;
|
610
|
+
// this.entryPointName = mainChunkName;
|
611
|
+
// this.jsResourceI18nKeys = jsResource || {};
|
612
|
+
// // Initialize collection maps
|
613
|
+
// this.moduleToKeysMap = new Map();
|
614
|
+
// this.keyToModulesMap = new Map();
|
615
|
+
// this.keyToI18nChunkIdMap = {};
|
616
|
+
// this.keyToHashMap = {};
|
617
|
+
// // Initialize hash function
|
618
|
+
// this.getHash = (key) => {
|
619
|
+
// if (!this.keyToHashMap[key]) {
|
620
|
+
// const hash = crypto.createHash('md5').update(key).digest('hex').substring(0, 8);
|
621
|
+
// this.keyToHashMap[key] = hash;
|
622
|
+
// }
|
623
|
+
// return this.keyToHashMap[key];
|
624
|
+
// };
|
625
|
+
// }
|
626
|
+
// shouldProcessModule(module) {
|
627
|
+
// if (!module.resource) return false;
|
628
|
+
// // Skip node_modules except for specific ones we want to process
|
629
|
+
// if (module.resource.includes('node_modules')) {
|
630
|
+
// const allowedModules = [
|
631
|
+
// '@zohodesk'
|
632
|
+
// // Add other allowed module prefixes here
|
633
|
+
// ];
|
634
|
+
// return allowedModules.some(prefix =>
|
635
|
+
// module.resource.includes(`node_modules/${prefix}`)
|
636
|
+
// );
|
637
|
+
// }
|
638
|
+
// // Process .js and .jsx files
|
639
|
+
// return /\.(js|jsx)$/.test(module.resource);
|
640
|
+
// }
|
641
|
+
// processModule(module) {
|
642
|
+
// if (!this.shouldProcessModule(module)) {
|
643
|
+
// return [];
|
644
|
+
// }
|
645
|
+
// try {
|
646
|
+
// const source = module._source._value;
|
647
|
+
// // Parse with @babel/parser which handles modern JS better
|
648
|
+
// const ast = parser.parse(source, {
|
649
|
+
// sourceType: 'module',
|
650
|
+
// plugins: [
|
651
|
+
// 'jsx',
|
652
|
+
// 'typescript',
|
653
|
+
// 'classProperties',
|
654
|
+
// 'decorators-legacy',
|
655
|
+
// 'exportDefaultFrom',
|
656
|
+
// 'exportNamespaceFrom',
|
657
|
+
// 'objectRestSpread',
|
658
|
+
// 'dynamicImport'
|
659
|
+
// ]
|
660
|
+
// });
|
661
|
+
// const i18nKeys = new Set();
|
662
|
+
// // Process the AST
|
663
|
+
// walk(ast, {
|
664
|
+
// enter: (node) => {
|
665
|
+
// if (node.type === 'StringLiteral' &&
|
666
|
+
// Object.prototype.hasOwnProperty.call(this.jsResourceI18nKeys, node.value)) {
|
667
|
+
// const key = node.value;
|
668
|
+
// i18nKeys.add(key);
|
669
|
+
// const hash = this.getHash(key);
|
670
|
+
// node.value = hash;
|
671
|
+
// if (node.extra && node.extra.raw) {
|
672
|
+
// node.extra.raw = `'${hash}'`;
|
673
|
+
// }
|
674
|
+
// }
|
675
|
+
// }
|
676
|
+
// });
|
677
|
+
// // Generate modified code if keys were found
|
678
|
+
// if (i18nKeys.size > 0) {
|
679
|
+
// try {
|
680
|
+
// const output = generate(ast, {
|
681
|
+
// retainLines: true,
|
682
|
+
// compact: false,
|
683
|
+
// jsescOption: {
|
684
|
+
// quotes: 'single'
|
685
|
+
// }
|
686
|
+
// });
|
687
|
+
// module._source._value = output.code;
|
688
|
+
// } catch (error) {
|
689
|
+
// console.error(`Error generating code for ${module.resource}:`, error);
|
690
|
+
// }
|
691
|
+
// }
|
692
|
+
// return Array.from(i18nKeys);
|
693
|
+
// } catch (error) {
|
694
|
+
// console.error(`Error processing module ${module.resource}:`, error);
|
695
|
+
// return [];
|
696
|
+
// }
|
697
|
+
// }
|
698
|
+
// apply(compiler) {
|
699
|
+
// compiler.hooks.compilation.tap('I18nPlugin', (compilation) => {
|
700
|
+
// // Process modules during compilation
|
701
|
+
// compilation.hooks.optimizeModules.tap('I18nPlugin', (modules) => {
|
702
|
+
// modules.forEach(module => {
|
703
|
+
// const keys = this.processModule(module);
|
704
|
+
// if (keys.length > 0) {
|
705
|
+
// // Update module to keys mapping
|
706
|
+
// this.moduleToKeysMap.set(module.resource, keys);
|
707
|
+
// // Update keys to modules mapping
|
708
|
+
// keys.forEach(key => {
|
709
|
+
// if (!this.keyToModulesMap.has(key)) {
|
710
|
+
// this.keyToModulesMap.set(key, new Set());
|
711
|
+
// }
|
712
|
+
// this.keyToModulesMap.get(key).add(module.resource);
|
713
|
+
// });
|
714
|
+
// }
|
715
|
+
// });
|
716
|
+
// });
|
717
|
+
// // Process chunks after optimization
|
718
|
+
// compilation.hooks.afterOptimizeChunks.tap('I18nPlugin', () => {
|
719
|
+
// this.processCollectedKeys(compilation);
|
720
|
+
// });
|
721
|
+
// });
|
722
|
+
// }
|
723
|
+
// processCollectedKeys(compilation) {
|
724
|
+
// // Map chunk IDs to sections and modules
|
725
|
+
// this.chunkIdToSectionsMap = {};
|
726
|
+
// this.moduleChunkIdToModulesMap = {};
|
727
|
+
// this.moduleResourceToChunkIds = new Map();
|
728
|
+
// // Process entry point modules
|
729
|
+
// const entryPointChunk = compilation.namedChunks.get(this.entryPointName);
|
730
|
+
// const entryPointModules = new Set();
|
731
|
+
// if (entryPointChunk) {
|
732
|
+
// for (const module of entryPointChunk.getModules()) {
|
733
|
+
// if (module.resource) {
|
734
|
+
// entryPointModules.add(module.resource);
|
735
|
+
// }
|
736
|
+
// }
|
737
|
+
// }
|
738
|
+
// // Process each chunk
|
739
|
+
// for (const chunk of compilation.chunks) {
|
740
|
+
// const chunkId = chunk.name || chunk.id;
|
741
|
+
// const chunkIdString = String(chunkId);
|
742
|
+
// const moduleResources = [];
|
743
|
+
// // Collect modules for this chunk
|
744
|
+
// for (const module of chunk.getModules()) {
|
745
|
+
// if (module.resource) {
|
746
|
+
// moduleResources.push(module.resource);
|
747
|
+
// // Map module resource to chunk IDs
|
748
|
+
// if (!this.moduleResourceToChunkIds.has(module.resource)) {
|
749
|
+
// this.moduleResourceToChunkIds.set(module.resource, new Set());
|
750
|
+
// }
|
751
|
+
// this.moduleResourceToChunkIds.get(module.resource).add(chunkIdString);
|
752
|
+
// }
|
753
|
+
// }
|
754
|
+
// // Store module resources for this chunk
|
755
|
+
// if (moduleResources.length > 0) {
|
756
|
+
// this.moduleChunkIdToModulesMap[chunkIdString] = moduleResources;
|
757
|
+
// }
|
758
|
+
// }
|
759
|
+
// // Collect used and unused keys
|
760
|
+
// this.collectKeyStats(entryPointModules);
|
761
|
+
// // Emit the i18n chunks
|
762
|
+
// //this.emitI18nChunks(compilation);
|
763
|
+
// }
|
764
|
+
// collectKeyStats(entryPointModules) {
|
765
|
+
// // Collect all used keys
|
766
|
+
// this.allUsedKeys = new Set();
|
767
|
+
// for (const keys of this.moduleToKeysMap.values()) {
|
768
|
+
// for (const key of keys) {
|
769
|
+
// this.allUsedKeys.add(key);
|
770
|
+
// }
|
771
|
+
// }
|
772
|
+
// // Collect entry point keys
|
773
|
+
// this.entryPointKeys = new Set();
|
774
|
+
// for (const moduleResource of entryPointModules) {
|
775
|
+
// const keys = this.moduleToKeysMap.get(moduleResource);
|
776
|
+
// if (keys) {
|
777
|
+
// for (const key of keys) {
|
778
|
+
// this.entryPointKeys.add(key);
|
779
|
+
// }
|
780
|
+
// }
|
781
|
+
// }
|
782
|
+
// // Calculate remaining and unused keys
|
783
|
+
// this.allKeysInProperties = new Set(Object.keys(this.jsResourceI18nKeys));
|
784
|
+
// this.unusedKeys = new Set(
|
785
|
+
// [...this.allKeysInProperties].filter(key => !this.allUsedKeys.has(key))
|
786
|
+
// );
|
787
|
+
// this.remainingKeys = new Set(
|
788
|
+
// [...this.allUsedKeys].filter(key => !this.entryPointKeys.has(key))
|
789
|
+
// );
|
790
|
+
// }
|
791
|
+
// emitI18nChunks(compilation) {
|
792
|
+
// const manifest = {
|
793
|
+
// moduleToI18nChunkMap: {},
|
794
|
+
// locales: { default: {} }
|
795
|
+
// };
|
796
|
+
// // Map from i18nChunkId to keys
|
797
|
+
// const i18nChunkIdToKeysMap = {};
|
798
|
+
// let i18nChunkIdCounter = 0;
|
799
|
+
// // Entry Point Keys (Chunk 0)
|
800
|
+
// const entryPointChunkId = i18nChunkIdCounter++;
|
801
|
+
// i18nChunkIdToKeysMap[entryPointChunkId] = Array.from(this.entryPointKeys);
|
802
|
+
// for (const key of this.entryPointKeys) {
|
803
|
+
// this.keyToI18nChunkIdMap[key] = entryPointChunkId;
|
804
|
+
// }
|
805
|
+
// // Unused Keys
|
806
|
+
// const unusedKeysChunkId = 'unused';
|
807
|
+
// i18nChunkIdToKeysMap[unusedKeysChunkId] = Array.from(this.unusedKeys);
|
808
|
+
// // Process remaining keys into chunks
|
809
|
+
// const chunkSize = 100 * 1024; // 100KB chunks
|
810
|
+
// let currentChunk = [];
|
811
|
+
// let currentSize = 0;
|
812
|
+
// for (const key of this.remainingKeys) {
|
813
|
+
// const keySize = Buffer.byteLength(key, 'utf8') +
|
814
|
+
// Buffer.byteLength(this.jsResourceI18nKeys[key] || '', 'utf8');
|
815
|
+
// if (currentSize + keySize > chunkSize && currentChunk.length > 0) {
|
816
|
+
// // Save current chunk
|
817
|
+
// const chunkId = i18nChunkIdCounter++;
|
818
|
+
// i18nChunkIdToKeysMap[chunkId] = currentChunk;
|
819
|
+
// currentChunk.forEach(k => this.keyToI18nChunkIdMap[k] = chunkId);
|
820
|
+
// // Start new chunk
|
821
|
+
// currentChunk = [];
|
822
|
+
// currentSize = 0;
|
823
|
+
// }
|
824
|
+
// currentChunk.push(key);
|
825
|
+
// currentSize += keySize;
|
826
|
+
// }
|
827
|
+
// // Save last chunk if not empty
|
828
|
+
// if (currentChunk.length > 0) {
|
829
|
+
// const chunkId = i18nChunkIdCounter++;
|
830
|
+
// i18nChunkIdToKeysMap[chunkId] = currentChunk;
|
831
|
+
// currentChunk.forEach(k => this.keyToI18nChunkIdMap[k] = chunkId);
|
832
|
+
// }
|
833
|
+
// // Generate chunks
|
834
|
+
// for (const [i18nChunkId, keys] of Object.entries(i18nChunkIdToKeysMap)) {
|
835
|
+
// const i18nData = {};
|
836
|
+
// for (const key of keys) {
|
837
|
+
// const value = this.jsResourceI18nKeys[key];
|
838
|
+
// if (value !== undefined) {
|
839
|
+
// i18nData[this.getHash(key)] = value;
|
840
|
+
// }
|
841
|
+
// }
|
842
|
+
// if (Object.keys(i18nData).length > 0) {
|
843
|
+
// const chunkContent = `window.loadI18nChunk(${JSON.stringify(i18nData, null, 2)});`;
|
844
|
+
// const filename = `i18n-chunks/default/chunk-${i18nChunkId}.js`;
|
845
|
+
// compilation.emitAsset(filename, new RawSource(chunkContent));
|
846
|
+
// manifest.locales.default[i18nChunkId] = filename;
|
847
|
+
// }
|
848
|
+
// }
|
849
|
+
// // Build module to chunk mapping
|
850
|
+
// for (const [moduleChunkId, moduleResources] of Object.entries(this.moduleChunkIdToModulesMap)) {
|
851
|
+
// const requiredI18nChunkIds = new Set();
|
852
|
+
// for (const moduleResource of moduleResources) {
|
853
|
+
// const keys = this.moduleToKeysMap.get(moduleResource);
|
854
|
+
// if (keys) {
|
855
|
+
// for (const key of keys) {
|
856
|
+
// const i18nChunkId = this.keyToI18nChunkIdMap[key];
|
857
|
+
// if (i18nChunkId !== undefined) {
|
858
|
+
// requiredI18nChunkIds.add(i18nChunkId);
|
859
|
+
// }
|
860
|
+
// }
|
861
|
+
// }
|
862
|
+
// }
|
863
|
+
// if (requiredI18nChunkIds.size > 0) {
|
864
|
+
// manifest.moduleToI18nChunkMap[moduleChunkId] = Array.from(requiredI18nChunkIds);
|
865
|
+
// }
|
866
|
+
// }
|
867
|
+
// // Ensure entry point has chunk zero
|
868
|
+
// manifest.moduleToI18nChunkMap[this.entryPointName] =
|
869
|
+
// manifest.moduleToI18nChunkMap[this.entryPointName] || [];
|
870
|
+
// if (!manifest.moduleToI18nChunkMap[this.entryPointName].includes(entryPointChunkId)) {
|
871
|
+
// manifest.moduleToI18nChunkMap[this.entryPointName].unshift(entryPointChunkId);
|
872
|
+
// }
|
873
|
+
// // Emit manifest
|
874
|
+
// const manifestContent =
|
875
|
+
// `window.i18n = window.i18n || {}; window.i18n.manifest = ${JSON.stringify(manifest, null, 2)};`;
|
876
|
+
// compilation.emitAsset('i18n-chunks/manifest.js', new RawSource(manifestContent));
|
877
|
+
// }
|
878
|
+
// }
|
879
|
+
// module.exports = I18nPlugin;
|
880
|
+
// const { RawSource } = require('webpack-sources');
|
881
|
+
// const { getAllI18nGroupedBySection, getPropertiesAsJSON, jsonToString } = require('../I18nSplitPlugin/utils/propertiesUtils');
|
882
|
+
// const { collectI18nKeysfromAST, collectI18nKeysfromComments,processModule } = require('../I18nSplitPlugin/utils/collectI18nKeys');
|
883
|
+
// const NullFactory = require('webpack/lib/NullFactory');
|
884
|
+
// const { I18nDependency, I18nDependencyTemplate } = require('../I18nSplitPlugin/I18nDependency');
|
885
|
+
// const I18nKeyHasher = require('./utils/I18nKeyHasher');
|
886
|
+
// const crypto = require('crypto');
|
887
|
+
// const pluginName = 'I18nSplitPlugin';
|
888
|
+
// const MODULE_TYPE = 'json/i18n';
|
889
|
+
// class I18nSplitPlugin {
|
890
|
+
// constructor(options = {}) {
|
891
|
+
// const {
|
892
|
+
// jsResource,
|
893
|
+
// localeVarName = 'document.documentElement.lang',
|
894
|
+
// jsonpFunc = 'window.loadI18nChunk',
|
895
|
+
// propertiesFolder,
|
896
|
+
// disableDefault = false,
|
897
|
+
// filenameTemplate = 'i18n-chunk/[locale]/[name].[chunkhash].i18n.js',
|
898
|
+
// i18nManifestFileName = 'i18n-manifest.json',
|
899
|
+
// mainChunkName = 'main'
|
900
|
+
// } = options;
|
901
|
+
// this.options = {
|
902
|
+
// localeVarName,
|
903
|
+
// jsonpFunc,
|
904
|
+
// filenameTemplate,
|
905
|
+
// i18nManifestFileName,
|
906
|
+
// mainChunkName
|
907
|
+
// };
|
908
|
+
// // Load and initialize i18n data
|
909
|
+
// this.jsResourceI18nKeys = jsResource ? getPropertiesAsJSON(jsResource) : {};
|
910
|
+
// this.allI18nData = getAllI18nGroupedBySection({
|
911
|
+
// folderPath: propertiesFolder,
|
912
|
+
// disableDefault,
|
913
|
+
// jsResourceI18nKeys: this.jsResourceI18nKeys
|
914
|
+
// });
|
915
|
+
// // Initialize key hasher
|
916
|
+
// this.keyHasher = new I18nKeyHasher();
|
917
|
+
// // Maps and tracking
|
918
|
+
// this.moduleToKeysMap = new Map();
|
919
|
+
// this.sectionToKeysMap = new Map();
|
920
|
+
// this.keyToSectionMap = new Map();
|
921
|
+
// this.sectionToChunkIdMap = new Map();
|
922
|
+
// this.chunkToSectionsMap = new Map();
|
923
|
+
// // Initialize sections and hashes
|
924
|
+
// this.initializeMaps();
|
925
|
+
// this.initializeHashes();
|
926
|
+
// console.log('Locales found:', Object.keys(this.allI18nData));
|
927
|
+
// }
|
928
|
+
// initializeMaps() {
|
929
|
+
// const firstLocale = Object.keys(this.allI18nData)[0];
|
930
|
+
// if (!firstLocale) return;
|
931
|
+
// const sections = this.allI18nData[firstLocale];
|
932
|
+
// console.log(`Sections found: ${Object.keys(sections).join(', ')}`);
|
933
|
+
// for (const [sectionName, sectionData] of Object.entries(sections)) {
|
934
|
+
// const keys = Object.keys(sectionData);
|
935
|
+
// this.sectionToKeysMap.set(sectionName, new Set(keys));
|
936
|
+
// keys.forEach(key => this.keyToSectionMap.set(key, sectionName));
|
937
|
+
// }
|
938
|
+
// }
|
939
|
+
// initializeHashes() {
|
940
|
+
// const allKeys = new Set();
|
941
|
+
// Object.values(this.allI18nData).forEach(localeData => {
|
942
|
+
// Object.values(localeData).forEach(sectionData => {
|
943
|
+
// Object.keys(sectionData).forEach(key => allKeys.add(key));
|
944
|
+
// });
|
945
|
+
// });
|
946
|
+
// allKeys.forEach(key => {
|
947
|
+
// this.keyHasher.hashKey(key);
|
948
|
+
// });
|
949
|
+
// }
|
950
|
+
// apply(compiler) {
|
951
|
+
// compiler.hooks.thisCompilation.tap(pluginName, (compilation, params) => {
|
952
|
+
// // Set up dependencies
|
953
|
+
// this.defineI18nDependency(compilation);
|
954
|
+
// // Set up parsing
|
955
|
+
// this.setupModuleParsing(compilation, params.normalModuleFactory);
|
956
|
+
// // Process chunks after optimization
|
957
|
+
// compilation.hooks.afterOptimizeChunks.tap(pluginName, () => {
|
958
|
+
// this.processChunks(compilation);
|
959
|
+
// });
|
960
|
+
// // Emit assets
|
961
|
+
// compiler.hooks.emit.tap(pluginName, () => {
|
962
|
+
// this.emitAssets(compilation);
|
963
|
+
// });
|
964
|
+
// });
|
965
|
+
// }
|
966
|
+
// defineI18nDependency(compilation) {
|
967
|
+
// compilation.dependencyFactories.set(I18nDependency, new NullFactory());
|
968
|
+
// compilation.dependencyTemplates.set(I18nDependency, new I18nDependencyTemplate());
|
969
|
+
// }
|
970
|
+
// setupModuleParsing(compilation, factory) {
|
971
|
+
// const handler = parser => {
|
972
|
+
// parser.hooks.program.tap(pluginName, (ast, comments) => {
|
973
|
+
// const { module } = parser.state;
|
974
|
+
// if (!(module && /\.jsx?$/.test(module.resource))) return;
|
975
|
+
// // Process the module and collect keys
|
976
|
+
// const moduleKeys = processModule(module, this.jsResourceI18nKeys, this.keyHasher);
|
977
|
+
// if (moduleKeys.length) {
|
978
|
+
// // Store keys for chunk generation
|
979
|
+
// this.moduleToKeysMap.set(module.resource, moduleKeys);
|
980
|
+
// // Add dependency
|
981
|
+
// this.addI18nDependency(module, moduleKeys);
|
982
|
+
// }
|
983
|
+
// });
|
984
|
+
// };
|
985
|
+
// factory.hooks.parser
|
986
|
+
// .for('javascript/auto')
|
987
|
+
// .tap(pluginName, handler);
|
988
|
+
// factory.hooks.parser
|
989
|
+
// .for('javascript/dynamic')
|
990
|
+
// .tap(pluginName, handler);
|
991
|
+
// }
|
992
|
+
// addI18nDependency(module, keys) {
|
993
|
+
// const dep = new I18nDependency({
|
994
|
+
// identifier: `i18n ${module.resource}`,
|
995
|
+
// i18nKeys: keys
|
996
|
+
// }, module.context);
|
997
|
+
// module.addDependency(dep);
|
998
|
+
// }
|
999
|
+
// processChunks(compilation) {
|
1000
|
+
// let chunkIdCounter = 0;
|
1001
|
+
// // Process entry point chunk
|
1002
|
+
// const entryChunk = compilation.namedChunks.get(this.options.mainChunkName);
|
1003
|
+
// if (entryChunk) {
|
1004
|
+
// const entryModules = Array.from(entryChunk.modulesIterable)
|
1005
|
+
// .filter(m => m.resource)
|
1006
|
+
// .map(m => m.resource);
|
1007
|
+
// // Collect entry point sections
|
1008
|
+
// const entrySections = new Set();
|
1009
|
+
// entryModules.forEach(moduleResource => {
|
1010
|
+
// const keys = this.moduleToKeysMap.get(moduleResource) || [];
|
1011
|
+
// keys.forEach(key => {
|
1012
|
+
// const section = this.keyToSectionMap.get(key);
|
1013
|
+
// if (section) entrySections.add(section);
|
1014
|
+
// });
|
1015
|
+
// });
|
1016
|
+
// // Assign chunk IDs to entry sections
|
1017
|
+
// entrySections.forEach(section => {
|
1018
|
+
// this.sectionToChunkIdMap.set(section, `section_${chunkIdCounter++}`);
|
1019
|
+
// });
|
1020
|
+
// }
|
1021
|
+
// // Process other chunks
|
1022
|
+
// for (const chunk of compilation.chunks) {
|
1023
|
+
// if (chunk === entryChunk) continue;
|
1024
|
+
// const modules = Array.from(chunk.modulesIterable)
|
1025
|
+
// .filter(m => m.resource);
|
1026
|
+
// const sectionsInChunk = new Set();
|
1027
|
+
// modules.forEach(module => {
|
1028
|
+
// const keys = this.moduleToKeysMap.get(module.resource) || [];
|
1029
|
+
// keys.forEach(key => {
|
1030
|
+
// const section = this.keyToSectionMap.get(key);
|
1031
|
+
// if (section) sectionsInChunk.add(section);
|
1032
|
+
// });
|
1033
|
+
// });
|
1034
|
+
// if (sectionsInChunk.size > 0) {
|
1035
|
+
// // Assign chunk IDs to new sections
|
1036
|
+
// sectionsInChunk.forEach(section => {
|
1037
|
+
// if (!this.sectionToChunkIdMap.has(section)) {
|
1038
|
+
// this.sectionToChunkIdMap.set(section, `section_${chunkIdCounter++}`);
|
1039
|
+
// }
|
1040
|
+
// });
|
1041
|
+
// this.chunkToSectionsMap.set(chunk, Array.from(sectionsInChunk));
|
1042
|
+
// }
|
1043
|
+
// }
|
1044
|
+
// }
|
1045
|
+
// emitAssets(compilation) {
|
1046
|
+
// const manifest = {
|
1047
|
+
// moduleToChunks: {},
|
1048
|
+
// hashMap: Object.fromEntries(this.keyHasher.keyHashMap),
|
1049
|
+
// locales: {}
|
1050
|
+
// };
|
1051
|
+
// // Generate chunks for each locale
|
1052
|
+
// for (const locale of Object.keys(this.allI18nData)) {
|
1053
|
+
// manifest.locales[locale] = {};
|
1054
|
+
// // Generate section chunks
|
1055
|
+
// for (const [section, chunkId] of this.sectionToChunkIdMap.entries()) {
|
1056
|
+
// const keys = this.sectionToKeysMap.get(section) || new Set();
|
1057
|
+
// const i18nData = {};
|
1058
|
+
// // Use hashed keys in chunks
|
1059
|
+
// keys.forEach(key => {
|
1060
|
+
// const hash = this.keyHasher.hashKey(key);
|
1061
|
+
// const value = this.allI18nData[locale][section]?.[key];
|
1062
|
+
// if (value) i18nData[hash] = value;
|
1063
|
+
// });
|
1064
|
+
// if (Object.keys(i18nData).length > 0) {
|
1065
|
+
// const chunkContent = `${this.options.jsonpFunc}(${jsonToString(i18nData)});`;
|
1066
|
+
// const fileName = this.getChunkFileName(chunkId, locale);
|
1067
|
+
// compilation.emitAsset(fileName, new RawSource(chunkContent));
|
1068
|
+
// manifest.locales[locale][chunkId] = fileName;
|
1069
|
+
// }
|
1070
|
+
// }
|
1071
|
+
// }
|
1072
|
+
// // Map modules to their required chunks
|
1073
|
+
// for (const [moduleResource, keys] of this.moduleToKeysMap.entries()) {
|
1074
|
+
// const requiredChunks = new Set();
|
1075
|
+
// keys.forEach(key => {
|
1076
|
+
// const section = this.keyToSectionMap.get(key);
|
1077
|
+
// if (section) {
|
1078
|
+
// const chunkId = this.sectionToChunkIdMap.get(section);
|
1079
|
+
// if (chunkId) requiredChunks.add(chunkId);
|
1080
|
+
// }
|
1081
|
+
// });
|
1082
|
+
// if (requiredChunks.size > 0) {
|
1083
|
+
// manifest.moduleToChunks[moduleResource] = Array.from(requiredChunks);
|
1084
|
+
// }
|
1085
|
+
// }
|
1086
|
+
// // Emit manifest
|
1087
|
+
// compilation.emitAsset(
|
1088
|
+
// this.options.i18nManifestFileName,
|
1089
|
+
// new RawSource(JSON.stringify(manifest, null, 2))
|
1090
|
+
// );
|
1091
|
+
// console.log(`Emitted manifest: ${this.options.i18nManifestFileName}`);
|
1092
|
+
// }
|
1093
|
+
// getChunkFileName(chunkId, locale) {
|
1094
|
+
// return this.options.filenameTemplate
|
1095
|
+
// .replace('[locale]', locale)
|
1096
|
+
// .replace('[name]', chunkId)
|
1097
|
+
// .replace('[chunkhash]', this.getContentHash(chunkId, locale));
|
1098
|
+
// }
|
1099
|
+
// getContentHash(chunkId, locale) {
|
1100
|
+
// return crypto
|
1101
|
+
// .createHash('md5')
|
1102
|
+
// .update(`${chunkId}_${locale}`)
|
1103
|
+
// .digest('hex')
|
1104
|
+
// .slice(0, 8);
|
1105
|
+
// }
|
1106
|
+
// }
|
1107
|
+
// module.exports = I18nSplitPlugin;
|
1108
|
+
//const { getAllI18nGroupedBySection, getPropertiesAsJSON } = require('');
|
1109
|
+
const {
|
1110
|
+
RawSource
|
1111
|
+
} = require('webpack-sources');
|
1112
|
+
const {
|
1113
|
+
getPropertiesAsJSON,
|
1114
|
+
jsonToString
|
1115
|
+
} = require('../I18nSplitPlugin/utils/propertiesUtils');
|
1116
|
+
const path = require('path');
|
1117
|
+
const crypto = require('crypto');
|
1118
|
+
const NullFactory = require('webpack/lib/NullFactory');
|
1119
|
+
const {
|
1120
|
+
I18nDependency,
|
1121
|
+
I18nDependencyTemplate
|
1122
|
+
} = require('../I18nSplitPlugin/I18nDependency');
|
1123
|
+
class I18nPlugin {
|
1124
|
+
constructor(options = {}) {
|
1125
|
+
const {
|
1126
|
+
jsResource,
|
1127
|
+
localeVarName = 'document.documentElement.lang',
|
1128
|
+
jsonpFunc = 'window.loadI18nChunk',
|
1129
|
+
propertiesFolder,
|
1130
|
+
disableDefault = false,
|
1131
|
+
filenameTemplate = 'i18n-chunk/[locale]/[name].i18n.js',
|
1132
|
+
i18nManifestFileName = 'i18n-manifest.json',
|
1133
|
+
mainChunkName = 'main'
|
1134
|
+
} = options;
|
1135
|
+
this.options = {
|
1136
|
+
localeVarName,
|
1137
|
+
jsonpFunc,
|
1138
|
+
filenameTemplate,
|
1139
|
+
i18nManifestFileName,
|
1140
|
+
mainChunkName
|
1141
|
+
}; // Load i18n data
|
1142
|
+
|
1143
|
+
this.jsResourceI18nKeys = jsResource ? getPropertiesAsJSON(jsResource) : {};
|
1144
|
+
this.propertiesFolder = propertiesFolder;
|
1145
|
+
this.disableDefault = disableDefault; // Track keys and chunks
|
1146
|
+
|
1147
|
+
this.moduleKeys = new Map();
|
1148
|
+
this.chunkKeys = new Map();
|
1149
|
+
this.prevHashes = {};
|
1150
|
+
}
|
1151
|
+
apply(compiler) {
|
1152
|
+
// Main compilation hook
|
1153
|
+
compiler.hooks.thisCompilation.tap('I18nPlugin', compilation => {
|
1154
|
+
// Setup dependency handling
|
1155
|
+
compilation.dependencyFactories.set(I18nDependency, new NullFactory());
|
1156
|
+
compilation.dependencyTemplates.set(I18nDependency, new I18nDependencyTemplate()); // Parse modules for i18n keys
|
1157
|
+
|
1158
|
+
const handler = parser => {
|
1159
|
+
parser.hooks.program.tap('I18nPlugin', (ast, comments) => {
|
1160
|
+
const {
|
1161
|
+
module
|
1162
|
+
} = parser.state; // Only process JS files
|
1163
|
+
|
1164
|
+
if (!(module && /\.jsx?$/.test(module.resource))) {
|
1165
|
+
return;
|
1166
|
+
} // Collect keys from source
|
1167
|
+
|
1168
|
+
const keys = this.collectKeys(ast, comments);
|
1169
|
+
if (keys.length) {
|
1170
|
+
this.moduleKeys.set(module, keys);
|
1171
|
+
this.addDependency(module, keys);
|
1172
|
+
}
|
1173
|
+
});
|
1174
|
+
}; // Register parser hooks
|
1175
|
+
|
1176
|
+
compilation.normalModuleFactory.hooks.parser.for('javascript/auto').tap('I18nPlugin', handler);
|
1177
|
+
compilation.normalModuleFactory.hooks.parser.for('javascript/dynamic').tap('I18nPlugin', handler);
|
1178
|
+
}); // Emit hook for generating files
|
1179
|
+
|
1180
|
+
compiler.hooks.emit.tap('I18nPlugin', compilation => {
|
1181
|
+
this.emitFiles(compilation);
|
1182
|
+
});
|
1183
|
+
}
|
1184
|
+
collectKeys(ast, comments) {
|
1185
|
+
const keys = new Set(); // Walk AST
|
1186
|
+
|
1187
|
+
if (ast && ast.body) {
|
1188
|
+
const walk = node => {
|
1189
|
+
if (node.type === 'Literal' && typeof node.value === 'string') {
|
1190
|
+
if (this.jsResourceI18nKeys[node.value]) {
|
1191
|
+
keys.add(node.value);
|
1192
|
+
}
|
1193
|
+
}
|
1194
|
+
for (const key in node) {
|
1195
|
+
if (node[key] && typeof node[key] === 'object') {
|
1196
|
+
walk(node[key]);
|
1197
|
+
}
|
1198
|
+
}
|
1199
|
+
};
|
1200
|
+
ast.body.forEach(walk);
|
1201
|
+
} // Check comments
|
1202
|
+
|
1203
|
+
if (comments) {
|
1204
|
+
comments.forEach(comment => {
|
1205
|
+
if (comment.value.includes('I18N:')) {
|
1206
|
+
const key = comment.value.split('I18N:')[1].trim();
|
1207
|
+
if (this.jsResourceI18nKeys[key]) {
|
1208
|
+
keys.add(key);
|
1209
|
+
}
|
1210
|
+
}
|
1211
|
+
});
|
1212
|
+
}
|
1213
|
+
return Array.from(keys);
|
1214
|
+
}
|
1215
|
+
addDependency(module, keys) {
|
1216
|
+
const dep = new I18nDependency({
|
1217
|
+
identifier: `i18n-${module.id}`,
|
1218
|
+
i18nKeys: keys
|
1219
|
+
}, module.context);
|
1220
|
+
module.addDependency(dep);
|
1221
|
+
}
|
1222
|
+
emitFiles(compilation) {
|
1223
|
+
// Generate manifest
|
1224
|
+
const manifest = {}; // Process chunks
|
1225
|
+
|
1226
|
+
compilation.chunks.forEach(chunk => {
|
1227
|
+
const chunkKeys = new Set(); // Collect keys from chunk modules
|
1228
|
+
|
1229
|
+
Array.from(chunk.modulesIterable).forEach(module => {
|
1230
|
+
const keys = this.moduleKeys.get(module) || [];
|
1231
|
+
keys.forEach(key => chunkKeys.add(key));
|
1232
|
+
});
|
1233
|
+
if (chunkKeys.size) {
|
1234
|
+
// Generate i18n files for each locale
|
1235
|
+
const locales = fs.readdirSync(this.propertiesFolder).filter(f => f.includes('_') && f.endsWith('.properties')).map(f => f.split('_')[1].split('.')[0]);
|
1236
|
+
locales.forEach(locale => {
|
1237
|
+
const i18nData = {};
|
1238
|
+
chunkKeys.forEach(key => {
|
1239
|
+
i18nData[key] = this.jsResourceI18nKeys[key];
|
1240
|
+
});
|
1241
|
+
const source = `${this.options.jsonpFunc}(${jsonToString(i18nData)});`;
|
1242
|
+
const filename = this.getFilename(chunk, locale);
|
1243
|
+
compilation.assets[filename] = new RawSource(source);
|
1244
|
+
if (!manifest[chunk.id]) {
|
1245
|
+
manifest[chunk.id] = {};
|
1246
|
+
}
|
1247
|
+
manifest[chunk.id][locale] = filename;
|
1248
|
+
});
|
1249
|
+
}
|
1250
|
+
}); // Emit manifest
|
1251
|
+
|
1252
|
+
compilation.assets[this.options.i18nManifestFileName] = new RawSource(JSON.stringify(manifest, null, 2));
|
1253
|
+
}
|
1254
|
+
getFilename(chunk, locale) {
|
1255
|
+
return this.options.filenameTemplate.replace('[locale]', locale).replace('[name]', chunk.name || chunk.id).replace('[chunkhash]', chunk.contentHash['javascript']);
|
1256
|
+
}
|
1257
|
+
}
|
1258
|
+
module.exports = I18nPlugin;
|