@zohodesk/client_build_tool 0.0.19 → 0.0.20-experimental.1
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/.claude/settings.local.json +43 -0
- package/README.md +214 -0
- package/README_backup.md +214 -0
- package/lib/schemas/defaultConfigValues.js +21 -0
- package/lib/schemas/defaultConfigValuesOnly.js +18 -0
- package/lib/shared/bundler/webpack/custom_plugins/I18nNumericIndexPlugin/I18nNumericIndexPlugin.js +213 -0
- package/lib/shared/bundler/webpack/custom_plugins/I18nNumericIndexPlugin/utils/i18nDataLoader.js +114 -0
- package/lib/shared/bundler/webpack/custom_plugins/I18nSplitPlugin/utils/propertiesUtils.js +5 -0
- package/lib/shared/bundler/webpack/jsLoaders.js +11 -3
- package/lib/shared/bundler/webpack/loaderConfigs/i18nIdReplaceLoaderConfig.js +55 -0
- package/lib/shared/bundler/webpack/loaders/i18nIdReplaceLoader.js +116 -0
- package/lib/shared/bundler/webpack/pluginConfigs/configI18nNumericIndexPlugin.js +26 -0
- package/lib/shared/bundler/webpack/plugins.js +3 -2
- package/lib/shared/bundler/webpack/tsLoaders.js +10 -2
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(rg:*)",
|
|
5
|
+
"WebFetch(domain:json.schemastore.org)",
|
|
6
|
+
"Bash(npm run devMode:*)",
|
|
7
|
+
"Bash(npm run build:prod:*)",
|
|
8
|
+
"Bash(nvm use:*)",
|
|
9
|
+
"Bash(npm --version)",
|
|
10
|
+
"Bash([ -s \"$NVM_DIR/nvm.sh\" ])",
|
|
11
|
+
"Bash(. \"$NVM_DIR/nvm.sh\")",
|
|
12
|
+
"Bash(npm config:*)",
|
|
13
|
+
"Bash(head:*)",
|
|
14
|
+
"Bash(# Get all unconverted string keys from build grep -ohE ''getI18NValue\\\\\\(\"\"[a-z][a-z0-9._]*\"\"'' /Users/ramaraj-14019/zoho/frontend/zohoim_client/jsapps/imclient/build/js/*.js /Users/ramaraj-14019/zoho/frontend/zohoim_client/jsapps/imclient/build/js-chunks/*.js)",
|
|
15
|
+
"Bash(# Check if i18n file has string keys mixed with numeric grep -oE ''\"\"[a-z][a-z0-9._]+\"\":'' /Users/ramaraj-14019/zoho/frontend/zohoim_client/jsapps/imclient/build/i18n/en_US.*.js)",
|
|
16
|
+
"Bash(# Extract all string keys from i18n file grep -oE ''\"\"[a-z][a-z0-9._]+\"\":'' /Users/ramaraj-14019/zoho/frontend/zohoim_client/jsapps/imclient/build/i18n/en_US.*.js)",
|
|
17
|
+
"Bash(while read key)",
|
|
18
|
+
"Bash(do if grep -q \"\"\"$key\"\"\" /Users/ramaraj-14019/zoho/frontend/zohoim_client/jsapps/imclient/numericMap.json)",
|
|
19
|
+
"Bash(then echo \" $key\" fi done echo \"\" echo \"3. Keys NOT in numericMap at all \\(6\\):\" grep '^zohoim\\\\.' /tmp/missing_keys.txt)",
|
|
20
|
+
"Bash(do if ! grep -q \"\"\"$key\"\"\" /Users/ramaraj-14019/zoho/frontend/zohoim_client/jsapps/imclient/numericMap.json)",
|
|
21
|
+
"Bash(then echo \" $key\" fi done echo \"\" echo \"4. Other missing \\(im.*, zia.*, misc\\):\" grep -E '^\\(im\\\\.|zia\\\\.|disable|new|support\\)' /tmp/missing_keys.txt)",
|
|
22
|
+
"Bash(__NEW_LINE_aff12bec9130f971__ echo \"\")",
|
|
23
|
+
"Bash(__NEW_LINE_55bddaeb070e251c__ echo \"\")",
|
|
24
|
+
"Bash(__NEW_LINE_d6c1f298250ec871__ echo \"\")",
|
|
25
|
+
"Bash(__NEW_LINE_6e6c120ff051d365__ echo \"\")",
|
|
26
|
+
"Bash(__NEW_LINE_31e36a9433e3d870__ echo \"\")",
|
|
27
|
+
"Bash(git -C /Users/ramaraj-14019/zoho/cbt/react-cli log --oneline -10 -- \"**/propertiesUtils.js\")",
|
|
28
|
+
"Bash(__NEW_LINE_b6ceba0cc1f59a2f__ echo \"\")",
|
|
29
|
+
"Bash(git -C /Users/ramaraj-14019/zoho/cbt/react-cli branch --show-current)",
|
|
30
|
+
"Bash(__NEW_LINE_762abdafcf3471ad__ echo \"\")",
|
|
31
|
+
"Bash(__NEW_LINE_1f000228d7679059__ echo \"\")",
|
|
32
|
+
"Bash(__NEW_LINE_61a2347ad71ab24a__ echo \"\")",
|
|
33
|
+
"Bash(__NEW_LINE_2de3b16379c6b5a9__ echo \"\")",
|
|
34
|
+
"Bash(tee:*)",
|
|
35
|
+
"Bash(for key in \"zohoim.approval.empty.title\" \"zohoim.button.submit\" \"zohoim.calendar.nextmonth\" \"zohoim.label.cancel\")",
|
|
36
|
+
"Bash(do)",
|
|
37
|
+
"Bash(if grep -q \"\"\"$key\"\"\" /Users/ramaraj-14019/zoho/frontend/zohoim_client/jsapps/imclient/build/i18n/en_US.*.js)",
|
|
38
|
+
"Bash(then)",
|
|
39
|
+
"Bash(else)",
|
|
40
|
+
"Bash(fi)"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
}
|
package/README.md
CHANGED
|
@@ -677,6 +677,220 @@ For example
|
|
|
677
677
|
- `customAttributes` support for add attributes to html, link , script tag in the output build.
|
|
678
678
|
|
|
679
679
|
|
|
680
|
+
## v0.0.1 (18-04-2023)
|
|
681
|
+
|
|
682
|
+
First Release
|
|
683
|
+
**Features:-**
|
|
684
|
+
|
|
685
|
+
- 'start' command to run react app
|
|
686
|
+
- 'build' command to create build for react app
|
|
687
|
+
- 'build:lib' command to create lib for react library
|
|
688
|
+
- 'build:es' command to create es for react library
|
|
689
|
+
- 'templates' command to create es for react library
|
|
690
|
+
# Changelog and Release Notes
|
|
691
|
+
|
|
692
|
+
# v0.0.19 (06-01-2026)
|
|
693
|
+
|
|
694
|
+
**Feature:-**
|
|
695
|
+
- During class name generation, when the template included the file name, it was converted to lowercase by default. Support has now been added to include the file name as class names in a case-insensitive manner.
|
|
696
|
+
|
|
697
|
+
```
|
|
698
|
+
css: {
|
|
699
|
+
classNameOptions: {
|
|
700
|
+
caseOnlyFilename: true
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
**Adjustments:-**
|
|
707
|
+
- issue in CssCustomOrderPlugin has been fixed
|
|
708
|
+
- customChunks default pattern for styles is removed (important)
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
# v0.0.18 (23-12-2025)(issue in CssCustomOrderPlugin)
|
|
712
|
+
|
|
713
|
+
**Adjustments:-**
|
|
714
|
+
- remove the unwanted console in the previous version
|
|
715
|
+
- html not creation issue due to the generate html option fixed
|
|
716
|
+
|
|
717
|
+
# v0.0.17 (22-12-2025) (html not creation issue) (issue in CssCustomOrderPlugin)
|
|
718
|
+
|
|
719
|
+
**revert:-**
|
|
720
|
+
- InjectChunkGraphPlugin and the pfc and plc functions were reverted due to UAT issues unrelated to our tool. Consequently, the plugin could not be included in this version. we rewriting the plc and pfc in resource hints plugins recently, it will function correctly when the new plugin is enabled,so revert this changes from this version
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
**Feature:-**
|
|
724
|
+
- `alias` support for `build:es` and `build:lib`
|
|
725
|
+
- Add babel-plugin-module-resolver dependencies for library only
|
|
726
|
+
- Modify getBabelPlugin to include module resolver with aliases
|
|
727
|
+
- An additional entry point support has been added.
|
|
728
|
+
- An option for HTML generation has been provided.
|
|
729
|
+
- Support for CssCustomOrderPlugin has been added.
|
|
730
|
+
|
|
731
|
+
**Adjustments:-**
|
|
732
|
+
- ChunkHierarchyPlugin.js – modified and rewrite the plugin to get the proper output (this is the stable version of this plugin).
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
# v0.0.16 (05-11-2025) (deprecated)
|
|
736
|
+
|
|
737
|
+
**Adjustments:-**
|
|
738
|
+
- ChunkHierarchyPlugin.js – Added support for ConcatenatedModule modules.
|
|
739
|
+
- InjectChunkGraphPlugin.js – Changed the template name from {{--preload-chunk-graph-object}} to __PRELOAD_CHUNK_GRAPH__ to resolve minification issues.
|
|
740
|
+
- Disabled CSS source map generation – CSS source maps were being created when RTL split was disabled and sourceMap was enabled, causing issues. Hence, CSS source map creation has been disabled
|
|
741
|
+
- Source map path correction – The resolving paths in source map files appeared as zohodesk-react/./src, which was incompatible with the Murphy tool. Updated it to zohodesk-react/src by adding a function to devtoolModuleFilenameTemplate in the output configuration.
|
|
742
|
+
- ChunkHierarchyPlugin – Made it active in development mode as well by removing the “run only in production” condition.
|
|
743
|
+
|
|
744
|
+
# v0.0.15 (11-10-2025) (deprecated)
|
|
745
|
+
|
|
746
|
+
**Feature:-**
|
|
747
|
+
- Chunk Dependency Mapping: Added a new feature that generates a JSON file listing all chunk dependencies in the Webpack build
|
|
748
|
+
For example, if main.js is a chunk, the generated JSON will include all of its direct imports (dependencies).
|
|
749
|
+
- Purpose:
|
|
750
|
+
To provide clear visibility into chunk relationships and dependencies for debugging, optimization, and performance analysis.
|
|
751
|
+
|
|
752
|
+
```
|
|
753
|
+
chunkGraph:{
|
|
754
|
+
enable: { value: true },
|
|
755
|
+
fileName: ''
|
|
756
|
+
}
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
- Preload Chunk Split Visualization
|
|
760
|
+
Enhanced the Preload Chunk (PLC) mechanism to identify and list the sub-chunks generated from a preloaded parent chunk.
|
|
761
|
+
When a chunk is configured for preloading (e.g., ticket.js), the system now traces and records all the split chunks associated with it
|
|
762
|
+
|
|
763
|
+
rewrite the plc and pfc fucntion in resourceHints plugin and created a new plugin to inject the sub chunks of the preloaded chunks in runtime file
|
|
764
|
+
|
|
765
|
+
if resourceHints not enabled plc , pfc and custom function related to this are not created
|
|
766
|
+
|
|
767
|
+
```
|
|
768
|
+
resourceHints: {
|
|
769
|
+
enable: true,
|
|
770
|
+
PreloadChunkNames: [//name of chunks to be preload//]
|
|
771
|
+
},
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
# v0.0.14 (06-10-2025)
|
|
776
|
+
|
|
777
|
+
**Feature:-**
|
|
778
|
+
- Added integrity and crossorigin attributes for all the js and css files in index.html
|
|
779
|
+
|
|
780
|
+
```enableSubResourceIntegrity: true
|
|
781
|
+
```
|
|
782
|
+
**Adjustments:-**
|
|
783
|
+
- add ts-loader to parse tsx and ts files
|
|
784
|
+
|
|
785
|
+
# v0.0.13 (02-09-2025)
|
|
786
|
+
|
|
787
|
+
**Adjustments:-**
|
|
788
|
+
- Source map files are created in the smap/ folder by default. However, they are also being created in the js/ folder to resolve the issue where Murphy was unable to locate them.
|
|
789
|
+
|
|
790
|
+
**Feature:-**
|
|
791
|
+
- Added support for Murphy to be built as a separate chunk and injected as the top script in the initial HTML.
|
|
792
|
+
- To enable this support , add this in your configuration
|
|
793
|
+
|
|
794
|
+
```murphyBootstrapHtml{
|
|
795
|
+
enable: true,
|
|
796
|
+
chunkName: '',
|
|
797
|
+
filePath: ''
|
|
798
|
+
}```
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
# v0.0.12 (14-08-2025)
|
|
803
|
+
|
|
804
|
+
- Fixed the initial i18n loading issue caused by using the same function in both the i18nRuntimeDealer plugin and decidePublicPath
|
|
805
|
+
|
|
806
|
+
# v0.0.11 (07-08-2025) (had an issue while enable i18n chunk split plugin)
|
|
807
|
+
- remove babel-plugin-module-resolver dependencies
|
|
808
|
+
|
|
809
|
+
**Adjustments:-**
|
|
810
|
+
- Public Folder configuration is separated for development and production
|
|
811
|
+
|
|
812
|
+
**Bug Fix:-**
|
|
813
|
+
- Fixed the issue where the build log was not visible when `stats (bundle integrity)` was enabled. The problem was resolved by adding an error check in the `bundleIntegrity plugin`.
|
|
814
|
+
- Removed the babel-plugin-module-resolver dependency to resolve the alias resolution issue in the application.
|
|
815
|
+
- Fixed the issue where a space in the variable name causes it to return an undefined value.
|
|
816
|
+
- Fixed the URL path generation issue that occurred while using context in the development setup.
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
# v0.0.10 (12-05-2025)
|
|
820
|
+
**Feature:-**
|
|
821
|
+
- `alias` support for `build:es` and `build:lib`
|
|
822
|
+
- Add babel-plugin-module-resolver dependencies
|
|
823
|
+
- Modify getBabelPlugin to include module resolver with aliases
|
|
824
|
+
|
|
825
|
+
**Bug Fix:-**
|
|
826
|
+
- Enhance runBabelForTSFile to handle both .tsx and .ts file extensions
|
|
827
|
+
- Update mockApiHandler to ensure mock function is called correctly
|
|
828
|
+
|
|
829
|
+
**Change:-**
|
|
830
|
+
- Refactor defaultConfigValues.js to include cli options for enableRTLSplit
|
|
831
|
+
|
|
832
|
+
## v0.0.9
|
|
833
|
+
|
|
834
|
+
**Feature:-**
|
|
835
|
+
- externals was added to Prevent bundling of certain imported packages and retrieve these external dependencies at runtime.
|
|
836
|
+
- to use externals, we use the following pattern in `app > externals` :
|
|
837
|
+
|
|
838
|
+
For example
|
|
839
|
+
```
|
|
840
|
+
externals: {
|
|
841
|
+
<key> : <value>
|
|
842
|
+
}
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
## v0.0.6 (4-09-2023)
|
|
846
|
+
|
|
847
|
+
**Feature:-**
|
|
848
|
+
- 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`.
|
|
849
|
+
- Added Resource Cleanup plugin to cleanup resource retained by build tool. this plugin is controlled by efc flag resourcecleanup flag.
|
|
850
|
+
- added support for using regex expression to get group of chunks chunkId via Resource Hint plugin prefetch/preload hook.
|
|
851
|
+
only will be activate when `resourceHints` => `allowPrefetchingMultipleChunks` as `true`
|
|
852
|
+
- added support for glob pattern for custom chunks split logic.
|
|
853
|
+
- added options to split chunks base config in the key `app` => `customChunksBaseConfig` as object
|
|
854
|
+
|
|
855
|
+
**Change:-**
|
|
856
|
+
- i18n name not generated issue fix.
|
|
857
|
+
- public path not correctly set issue fix.
|
|
858
|
+
- changing plugin hook stages in i18nRuntimePlugin and sourceMapPlugin
|
|
859
|
+
## v0.0.5 (6-08-2023)
|
|
860
|
+
|
|
861
|
+
**Changes:--**
|
|
862
|
+
- Typo fix in i18nRuntimeDealerPlugin.js
|
|
863
|
+
- fixing some bugs in resolvers.js file
|
|
864
|
+
|
|
865
|
+
## v0.0.3 (1-08-2023)
|
|
866
|
+
|
|
867
|
+
**Changes:--**
|
|
868
|
+
- `devtool` default value changed from `hidden-cheap-source-map` to `source-map`
|
|
869
|
+
- unwanted files deleted from build
|
|
870
|
+
|
|
871
|
+
**Issue Fix:--**
|
|
872
|
+
- The issue with the source map not being created in the build has been fixed."
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
## v0.0.2 (28-04-2023)
|
|
876
|
+
|
|
877
|
+
**Features:-**
|
|
878
|
+
|
|
879
|
+
- `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)
|
|
880
|
+
- `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)
|
|
881
|
+
- `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.
|
|
882
|
+
- `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.
|
|
883
|
+
- `enableChunkHash` renamed as `enableFileNameHashing`
|
|
884
|
+
|
|
885
|
+
- `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`)
|
|
886
|
+
- `createSeparateSmap` flag `source_map_enable` renamed as `enable_smap`
|
|
887
|
+
- `removeAttribute` option changes as `babelCustomizations.removeAttribute`
|
|
888
|
+
- `removePropTypes` support for remove the prop types package in the output build.
|
|
889
|
+
- `devConsoleExclude` support for remove the _console statements_ such as _console.log_, _console.warn_ in the output build.
|
|
890
|
+
- `manifestJson` default value set as false.
|
|
891
|
+
- `customAttributes` support for add attributes to html, link , script tag in the output build.
|
|
892
|
+
|
|
893
|
+
|
|
680
894
|
## v0.0.1 (18-04-2023)
|
|
681
895
|
|
|
682
896
|
First Release
|
package/README_backup.md
CHANGED
|
@@ -463,6 +463,220 @@ For example
|
|
|
463
463
|
- `customAttributes` support for add attributes to html, link , script tag in the output build.
|
|
464
464
|
|
|
465
465
|
|
|
466
|
+
## v0.0.1 (18-04-2023)
|
|
467
|
+
|
|
468
|
+
First Release
|
|
469
|
+
**Features:-**
|
|
470
|
+
|
|
471
|
+
- 'start' command to run react app
|
|
472
|
+
- 'build' command to create build for react app
|
|
473
|
+
- 'build:lib' command to create lib for react library
|
|
474
|
+
- 'build:es' command to create es for react library
|
|
475
|
+
- 'templates' command to create es for react library
|
|
476
|
+
# Changelog and Release Notes
|
|
477
|
+
|
|
478
|
+
# v0.0.19 (06-01-2026)
|
|
479
|
+
|
|
480
|
+
**Feature:-**
|
|
481
|
+
- During class name generation, when the template included the file name, it was converted to lowercase by default. Support has now been added to include the file name as class names in a case-insensitive manner.
|
|
482
|
+
|
|
483
|
+
```
|
|
484
|
+
css: {
|
|
485
|
+
classNameOptions: {
|
|
486
|
+
caseOnlyFilename: true
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
**Adjustments:-**
|
|
493
|
+
- issue in CssCustomOrderPlugin has been fixed
|
|
494
|
+
- customChunks default pattern for styles is removed (important)
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
# v0.0.18 (23-12-2025)(issue in CssCustomOrderPlugin)
|
|
498
|
+
|
|
499
|
+
**Adjustments:-**
|
|
500
|
+
- remove the unwanted console in the previous version
|
|
501
|
+
- html not creation issue due to the generate html option fixed
|
|
502
|
+
|
|
503
|
+
# v0.0.17 (22-12-2025) (html not creation issue) (issue in CssCustomOrderPlugin)
|
|
504
|
+
|
|
505
|
+
**revert:-**
|
|
506
|
+
- InjectChunkGraphPlugin and the pfc and plc functions were reverted due to UAT issues unrelated to our tool. Consequently, the plugin could not be included in this version. we rewriting the plc and pfc in resource hints plugins recently, it will function correctly when the new plugin is enabled,so revert this changes from this version
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
**Feature:-**
|
|
510
|
+
- `alias` support for `build:es` and `build:lib`
|
|
511
|
+
- Add babel-plugin-module-resolver dependencies for library only
|
|
512
|
+
- Modify getBabelPlugin to include module resolver with aliases
|
|
513
|
+
- An additional entry point support has been added.
|
|
514
|
+
- An option for HTML generation has been provided.
|
|
515
|
+
- Support for CssCustomOrderPlugin has been added.
|
|
516
|
+
|
|
517
|
+
**Adjustments:-**
|
|
518
|
+
- ChunkHierarchyPlugin.js – modified and rewrite the plugin to get the proper output (this is the stable version of this plugin).
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
# v0.0.16 (05-11-2025) (deprecated)
|
|
522
|
+
|
|
523
|
+
**Adjustments:-**
|
|
524
|
+
- ChunkHierarchyPlugin.js – Added support for ConcatenatedModule modules.
|
|
525
|
+
- InjectChunkGraphPlugin.js – Changed the template name from {{--preload-chunk-graph-object}} to __PRELOAD_CHUNK_GRAPH__ to resolve minification issues.
|
|
526
|
+
- Disabled CSS source map generation – CSS source maps were being created when RTL split was disabled and sourceMap was enabled, causing issues. Hence, CSS source map creation has been disabled
|
|
527
|
+
- Source map path correction – The resolving paths in source map files appeared as zohodesk-react/./src, which was incompatible with the Murphy tool. Updated it to zohodesk-react/src by adding a function to devtoolModuleFilenameTemplate in the output configuration.
|
|
528
|
+
- ChunkHierarchyPlugin – Made it active in development mode as well by removing the “run only in production” condition.
|
|
529
|
+
|
|
530
|
+
# v0.0.15 (11-10-2025) (deprecated)
|
|
531
|
+
|
|
532
|
+
**Feature:-**
|
|
533
|
+
- Chunk Dependency Mapping: Added a new feature that generates a JSON file listing all chunk dependencies in the Webpack build
|
|
534
|
+
For example, if main.js is a chunk, the generated JSON will include all of its direct imports (dependencies).
|
|
535
|
+
- Purpose:
|
|
536
|
+
To provide clear visibility into chunk relationships and dependencies for debugging, optimization, and performance analysis.
|
|
537
|
+
|
|
538
|
+
```
|
|
539
|
+
chunkGraph:{
|
|
540
|
+
enable: { value: true },
|
|
541
|
+
fileName: ''
|
|
542
|
+
}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
- Preload Chunk Split Visualization
|
|
546
|
+
Enhanced the Preload Chunk (PLC) mechanism to identify and list the sub-chunks generated from a preloaded parent chunk.
|
|
547
|
+
When a chunk is configured for preloading (e.g., ticket.js), the system now traces and records all the split chunks associated with it
|
|
548
|
+
|
|
549
|
+
rewrite the plc and pfc fucntion in resourceHints plugin and created a new plugin to inject the sub chunks of the preloaded chunks in runtime file
|
|
550
|
+
|
|
551
|
+
if resourceHints not enabled plc , pfc and custom function related to this are not created
|
|
552
|
+
|
|
553
|
+
```
|
|
554
|
+
resourceHints: {
|
|
555
|
+
enable: true,
|
|
556
|
+
PreloadChunkNames: [//name of chunks to be preload//]
|
|
557
|
+
},
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
# v0.0.14 (06-10-2025)
|
|
562
|
+
|
|
563
|
+
**Feature:-**
|
|
564
|
+
- Added integrity and crossorigin attributes for all the js and css files in index.html
|
|
565
|
+
|
|
566
|
+
```enableSubResourceIntegrity: true
|
|
567
|
+
```
|
|
568
|
+
**Adjustments:-**
|
|
569
|
+
- add ts-loader to parse tsx and ts files
|
|
570
|
+
|
|
571
|
+
# v0.0.13 (02-09-2025)
|
|
572
|
+
|
|
573
|
+
**Adjustments:-**
|
|
574
|
+
- Source map files are created in the smap/ folder by default. However, they are also being created in the js/ folder to resolve the issue where Murphy was unable to locate them.
|
|
575
|
+
|
|
576
|
+
**Feature:-**
|
|
577
|
+
- Added support for Murphy to be built as a separate chunk and injected as the top script in the initial HTML.
|
|
578
|
+
- To enable this support , add this in your configuration
|
|
579
|
+
|
|
580
|
+
```murphyBootstrapHtml{
|
|
581
|
+
enable: true,
|
|
582
|
+
chunkName: '',
|
|
583
|
+
filePath: ''
|
|
584
|
+
}```
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
# v0.0.12 (14-08-2025)
|
|
589
|
+
|
|
590
|
+
- Fixed the initial i18n loading issue caused by using the same function in both the i18nRuntimeDealer plugin and decidePublicPath
|
|
591
|
+
|
|
592
|
+
# v0.0.11 (07-08-2025) (had an issue while enable i18n chunk split plugin)
|
|
593
|
+
- remove babel-plugin-module-resolver dependencies
|
|
594
|
+
|
|
595
|
+
**Adjustments:-**
|
|
596
|
+
- Public Folder configuration is separated for development and production
|
|
597
|
+
|
|
598
|
+
**Bug Fix:-**
|
|
599
|
+
- Fixed the issue where the build log was not visible when `stats (bundle integrity)` was enabled. The problem was resolved by adding an error check in the `bundleIntegrity plugin`.
|
|
600
|
+
- Removed the babel-plugin-module-resolver dependency to resolve the alias resolution issue in the application.
|
|
601
|
+
- Fixed the issue where a space in the variable name causes it to return an undefined value.
|
|
602
|
+
- Fixed the URL path generation issue that occurred while using context in the development setup.
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
# v0.0.10 (12-05-2025)
|
|
606
|
+
**Feature:-**
|
|
607
|
+
- `alias` support for `build:es` and `build:lib`
|
|
608
|
+
- Add babel-plugin-module-resolver dependencies
|
|
609
|
+
- Modify getBabelPlugin to include module resolver with aliases
|
|
610
|
+
|
|
611
|
+
**Bug Fix:-**
|
|
612
|
+
- Enhance runBabelForTSFile to handle both .tsx and .ts file extensions
|
|
613
|
+
- Update mockApiHandler to ensure mock function is called correctly
|
|
614
|
+
|
|
615
|
+
**Change:-**
|
|
616
|
+
- Refactor defaultConfigValues.js to include cli options for enableRTLSplit
|
|
617
|
+
|
|
618
|
+
## v0.0.9
|
|
619
|
+
|
|
620
|
+
**Feature:-**
|
|
621
|
+
- externals was added to Prevent bundling of certain imported packages and retrieve these external dependencies at runtime.
|
|
622
|
+
- to use externals, we use the following pattern in `app > externals` :
|
|
623
|
+
|
|
624
|
+
For example
|
|
625
|
+
```
|
|
626
|
+
externals: {
|
|
627
|
+
<key> : <value>
|
|
628
|
+
}
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
## v0.0.6 (4-09-2023)
|
|
632
|
+
|
|
633
|
+
**Feature:-**
|
|
634
|
+
- 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`.
|
|
635
|
+
- Added Resource Cleanup plugin to cleanup resource retained by build tool. this plugin is controlled by efc flag resourcecleanup flag.
|
|
636
|
+
- added support for using regex expression to get group of chunks chunkId via Resource Hint plugin prefetch/preload hook.
|
|
637
|
+
only will be activate when `resourceHints` => `allowPrefetchingMultipleChunks` as `true`
|
|
638
|
+
- added support for glob pattern for custom chunks split logic.
|
|
639
|
+
- added options to split chunks base config in the key `app` => `customChunksBaseConfig` as object
|
|
640
|
+
|
|
641
|
+
**Change:-**
|
|
642
|
+
- i18n name not generated issue fix.
|
|
643
|
+
- public path not correctly set issue fix.
|
|
644
|
+
- changing plugin hook stages in i18nRuntimePlugin and sourceMapPlugin
|
|
645
|
+
## v0.0.5 (6-08-2023)
|
|
646
|
+
|
|
647
|
+
**Changes:--**
|
|
648
|
+
- Typo fix in i18nRuntimeDealerPlugin.js
|
|
649
|
+
- fixing some bugs in resolvers.js file
|
|
650
|
+
|
|
651
|
+
## v0.0.3 (1-08-2023)
|
|
652
|
+
|
|
653
|
+
**Changes:--**
|
|
654
|
+
- `devtool` default value changed from `hidden-cheap-source-map` to `source-map`
|
|
655
|
+
- unwanted files deleted from build
|
|
656
|
+
|
|
657
|
+
**Issue Fix:--**
|
|
658
|
+
- The issue with the source map not being created in the build has been fixed."
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
## v0.0.2 (28-04-2023)
|
|
662
|
+
|
|
663
|
+
**Features:-**
|
|
664
|
+
|
|
665
|
+
- `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)
|
|
666
|
+
- `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)
|
|
667
|
+
- `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.
|
|
668
|
+
- `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.
|
|
669
|
+
- `enableChunkHash` renamed as `enableFileNameHashing`
|
|
670
|
+
|
|
671
|
+
- `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`)
|
|
672
|
+
- `createSeparateSmap` flag `source_map_enable` renamed as `enable_smap`
|
|
673
|
+
- `removeAttribute` option changes as `babelCustomizations.removeAttribute`
|
|
674
|
+
- `removePropTypes` support for remove the prop types package in the output build.
|
|
675
|
+
- `devConsoleExclude` support for remove the _console statements_ such as _console.log_, _console.warn_ in the output build.
|
|
676
|
+
- `manifestJson` default value set as false.
|
|
677
|
+
- `customAttributes` support for add attributes to html, link , script tag in the output build.
|
|
678
|
+
|
|
679
|
+
|
|
466
680
|
## v0.0.1 (18-04-2023)
|
|
467
681
|
|
|
468
682
|
First Release
|
|
@@ -180,6 +180,27 @@ var _default = {
|
|
|
180
180
|
jsResource: null,
|
|
181
181
|
propertiesFolder: null
|
|
182
182
|
},
|
|
183
|
+
i18nIndexing: {
|
|
184
|
+
enable: {
|
|
185
|
+
value: false,
|
|
186
|
+
cli: 'i18n_indexing'
|
|
187
|
+
},
|
|
188
|
+
jsResourcePath: null,
|
|
189
|
+
propertiesFolderPath: null,
|
|
190
|
+
numericMapPath: null,
|
|
191
|
+
outputFolder: 'i18n-chunk',
|
|
192
|
+
numericFilenameTemplate: 'i18n-chunk/[locale]/numeric.i18n.js',
|
|
193
|
+
dynamicFilenameTemplate: 'i18n-chunk/[locale]/dynamic.i18n.js',
|
|
194
|
+
singleFile: false,
|
|
195
|
+
singleFileTemplate: '[locale].js',
|
|
196
|
+
jsonpFunc: 'window.loadI18nChunk',
|
|
197
|
+
htmlTemplateLabel: '{{--user-locale}}',
|
|
198
|
+
localeVarName: 'window.userLangCode',
|
|
199
|
+
includeContentHash: false,
|
|
200
|
+
emitFiles: true,
|
|
201
|
+
generateManifest: false,
|
|
202
|
+
manifestPath: null
|
|
203
|
+
},
|
|
183
204
|
publicFolders: {
|
|
184
205
|
dev: ['...'],
|
|
185
206
|
prod: ['...']
|
|
@@ -96,6 +96,24 @@ var _default = {
|
|
|
96
96
|
jsResource: null,
|
|
97
97
|
propertiesFolder: null
|
|
98
98
|
},
|
|
99
|
+
i18nIndexing: {
|
|
100
|
+
enable: false,
|
|
101
|
+
jsResourcePath: null,
|
|
102
|
+
propertiesFolderPath: null,
|
|
103
|
+
numericMapPath: null,
|
|
104
|
+
outputFolder: 'i18n-chunk',
|
|
105
|
+
numericFilenameTemplate: 'i18n-chunk/[locale]/numeric.i18n.js',
|
|
106
|
+
dynamicFilenameTemplate: 'i18n-chunk/[locale]/dynamic.i18n.js',
|
|
107
|
+
singleFile: false,
|
|
108
|
+
singleFileTemplate: '[locale].js',
|
|
109
|
+
jsonpFunc: 'window.loadI18nChunk',
|
|
110
|
+
htmlTemplateLabel: '{{--user-locale}}',
|
|
111
|
+
localeVarName: 'window.userLangCode',
|
|
112
|
+
includeContentHash: false,
|
|
113
|
+
emitFiles: true,
|
|
114
|
+
generateManifest: false,
|
|
115
|
+
manifestPath: null
|
|
116
|
+
},
|
|
99
117
|
publicFolders: {
|
|
100
118
|
dev: ['...'],
|
|
101
119
|
prod: ['...']
|
package/lib/shared/bundler/webpack/custom_plugins/I18nNumericIndexPlugin/I18nNumericIndexPlugin.js
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
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
|
+
decodeUnicodeEscapes,
|
|
14
|
+
getPropertiesAsJSON
|
|
15
|
+
} = require('../I18nSplitPlugin/utils/propertiesUtils');
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
createHash
|
|
19
|
+
} = require('../I18nSplitPlugin/createHash');
|
|
20
|
+
|
|
21
|
+
const {
|
|
22
|
+
pathCreator
|
|
23
|
+
} = require('../I18nSplitPlugin/pathCreator');
|
|
24
|
+
|
|
25
|
+
const {
|
|
26
|
+
RawSource
|
|
27
|
+
} = sources;
|
|
28
|
+
const PLUGIN_NAME = 'I18nNumericIndexPlugin';
|
|
29
|
+
const DEFAULT_LOCALE = 'en_US';
|
|
30
|
+
const LOCALE_PATTERN = /_([a-z]{2}_[A-Z]{2})\.properties$/;
|
|
31
|
+
|
|
32
|
+
class I18nNumericIndexPlugin {
|
|
33
|
+
constructor(options) {
|
|
34
|
+
if (!options) {
|
|
35
|
+
throw new Error('[I18nNumericIndexPlugin] options is required');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
this.options = options;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
apply(compiler) {
|
|
42
|
+
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, compilation => {
|
|
43
|
+
compilation.hooks.processAssets.tapAsync({
|
|
44
|
+
name: PLUGIN_NAME,
|
|
45
|
+
stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
|
|
46
|
+
}, (_assets, callback) => {
|
|
47
|
+
if (!this.options.enable) {
|
|
48
|
+
callback();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
this.processI18nAssets(compilation);
|
|
54
|
+
} catch (err) {
|
|
55
|
+
compilation.errors.push(new Error(`[${PLUGIN_NAME}] ${err.message}`));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
callback();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
processI18nAssets(compilation) {
|
|
64
|
+
const {
|
|
65
|
+
numericMapPath,
|
|
66
|
+
jsResourcePath,
|
|
67
|
+
propertiesFolderPath
|
|
68
|
+
} = this.options;
|
|
69
|
+
const context = compilation.compiler.context;
|
|
70
|
+
const numericMapFullPath = path.resolve(context, numericMapPath);
|
|
71
|
+
const numericMapContent = JSON.parse(fs.readFileSync(numericMapFullPath, 'utf-8'));
|
|
72
|
+
const keyToNumericId = numericMapContent.originalKeyToNumericId;
|
|
73
|
+
const jsResourceFullPath = path.resolve(context, jsResourcePath);
|
|
74
|
+
const baseTranslations = getPropertiesAsJSON(jsResourceFullPath);
|
|
75
|
+
const baseKeys = Object.keys(baseTranslations);
|
|
76
|
+
|
|
77
|
+
if (baseKeys.length === 0) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const propertiesFolder = path.resolve(context, propertiesFolderPath);
|
|
82
|
+
const propertyFiles = fs.readdirSync(propertiesFolder).filter(f => f.endsWith('.properties'));
|
|
83
|
+
const manifest = {};
|
|
84
|
+
|
|
85
|
+
for (const file of propertyFiles) {
|
|
86
|
+
const locale = this.extractLocaleFromFilename(file);
|
|
87
|
+
|
|
88
|
+
if (!locale) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const localeTranslations = getPropertiesAsJSON(path.join(propertiesFolder, file));
|
|
93
|
+
const {
|
|
94
|
+
numericData,
|
|
95
|
+
dynamicData
|
|
96
|
+
} = this.buildLocaleData(baseKeys, baseTranslations, localeTranslations, keyToNumericId);
|
|
97
|
+
this.emitLocaleFiles(compilation, locale, numericData, dynamicData, manifest);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this.emitManifest(compilation, manifest);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
extractLocaleFromFilename(filename) {
|
|
104
|
+
// Base properties file (no locale suffix) defaults to en_US
|
|
105
|
+
if (!filename.includes('_')) {
|
|
106
|
+
return DEFAULT_LOCALE;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const match = filename.match(LOCALE_PATTERN);
|
|
110
|
+
return match ? match[1] : null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
buildLocaleData(baseKeys, baseTranslations, localeTranslations, keyToNumericId) {
|
|
114
|
+
const numericData = {};
|
|
115
|
+
const dynamicData = {};
|
|
116
|
+
|
|
117
|
+
for (const key of baseKeys) {
|
|
118
|
+
const value = localeTranslations[key] ?? baseTranslations[key];
|
|
119
|
+
|
|
120
|
+
if (key in keyToNumericId) {
|
|
121
|
+
numericData[keyToNumericId[key]] = value;
|
|
122
|
+
} else {
|
|
123
|
+
dynamicData[key] = value;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
numericData,
|
|
129
|
+
dynamicData
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
emitLocaleFiles(compilation, locale, numericData, dynamicData, manifest) {
|
|
134
|
+
const {
|
|
135
|
+
singleFile,
|
|
136
|
+
singleFileTemplate,
|
|
137
|
+
outputFolder,
|
|
138
|
+
numericFilenameTemplate,
|
|
139
|
+
dynamicFilenameTemplate
|
|
140
|
+
} = this.options;
|
|
141
|
+
|
|
142
|
+
if (singleFile) {
|
|
143
|
+
const combined = { ...numericData,
|
|
144
|
+
...dynamicData
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
if (Object.keys(combined).length > 0) {
|
|
148
|
+
const template = `${outputFolder}/${singleFileTemplate}`;
|
|
149
|
+
this.emitChunk(compilation, template, locale, combined, manifest);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (Object.keys(numericData).length > 0) {
|
|
156
|
+
this.emitChunk(compilation, numericFilenameTemplate, locale, numericData, manifest);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (Object.keys(dynamicData).length > 0) {
|
|
160
|
+
this.emitChunk(compilation, dynamicFilenameTemplate, locale, dynamicData, manifest);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
emitChunk(compilation, filenameTemplate, locale, data, manifest) {
|
|
165
|
+
const content = decodeUnicodeEscapes(JSON.stringify(data));
|
|
166
|
+
const fileContent = `${this.options.jsonpFunc}(${content});`;
|
|
167
|
+
const contentHash = createHash({
|
|
168
|
+
outputOptions: compilation.outputOptions,
|
|
169
|
+
content: fileContent
|
|
170
|
+
});
|
|
171
|
+
let outputPath = pathCreator(filenameTemplate, compilation, {
|
|
172
|
+
hash: compilation.hash,
|
|
173
|
+
locale,
|
|
174
|
+
chunkName: null,
|
|
175
|
+
chunkId: locale,
|
|
176
|
+
chunkHash: null,
|
|
177
|
+
contentHash
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
if (this.options.includeContentHash && !filenameTemplate.includes('[contenthash]')) {
|
|
181
|
+
outputPath = outputPath.replace(/\.js$/, `.${contentHash}.js`);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (this.options.generateManifest) {
|
|
185
|
+
const filename = outputPath.split('/').pop();
|
|
186
|
+
manifest[locale] = filename;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (this.options.emitFiles) {
|
|
190
|
+
compilation.emitAsset(outputPath, new RawSource(fileContent));
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return outputPath;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
emitManifest(compilation, manifest) {
|
|
197
|
+
const hasEntries = Object.keys(manifest).length > 0;
|
|
198
|
+
|
|
199
|
+
if (!this.options.generateManifest || !hasEntries) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (this.options.emitFiles) {
|
|
204
|
+
const manifestContent = JSON.stringify(manifest, null, 2);
|
|
205
|
+
compilation.emitAsset(this.options.manifestPath, new RawSource(manifestContent));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
module.exports = {
|
|
212
|
+
I18nNumericIndexPlugin
|
|
213
|
+
};
|
package/lib/shared/bundler/webpack/custom_plugins/I18nNumericIndexPlugin/utils/i18nDataLoader.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
getPropertiesAsJSON
|
|
9
|
+
} = require('../../I18nSplitPlugin/utils/propertiesUtils');
|
|
10
|
+
|
|
11
|
+
function loadPropertiesFile(filePath, compilation, description) {
|
|
12
|
+
if (!fs.existsSync(filePath)) {
|
|
13
|
+
if (compilation) {
|
|
14
|
+
compilation.errors.push(new Error(`I18nNumericIndexPlugin: Error loading ${description}: File not found: ${filePath}`));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return getPropertiesAsJSON(filePath);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function loadNumericMap(numericMapPath, compilation) {
|
|
24
|
+
try {
|
|
25
|
+
const fileContent = fs.readFileSync(numericMapPath, 'utf-8');
|
|
26
|
+
const parsedData = JSON.parse(fileContent);
|
|
27
|
+
const numericIds = Object.values(parsedData.originalKeyToNumericId);
|
|
28
|
+
const maxId = numericIds.length > 0 ? Math.max(...numericIds) : -1;
|
|
29
|
+
const totalKeys = maxId + 1;
|
|
30
|
+
const sortedKeys = new Array(totalKeys);
|
|
31
|
+
Object.entries(parsedData.originalKeyToNumericId).forEach(([key, id]) => {
|
|
32
|
+
sortedKeys[id] = key;
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
sortedKeys,
|
|
36
|
+
totalKeys
|
|
37
|
+
};
|
|
38
|
+
} catch (err) {
|
|
39
|
+
if (compilation) {
|
|
40
|
+
compilation.errors.push(new Error(`I18nNumericIndexPlugin: Error loading numeric map: ${err.message}`));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
sortedKeys: [],
|
|
45
|
+
totalKeys: 0
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function loadAllLocaleFiles(propertiesPath, baseFileName, compilation) {
|
|
51
|
+
const allI18n = {};
|
|
52
|
+
const locales = [];
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const files = fs.readdirSync(propertiesPath);
|
|
56
|
+
files.forEach(file => {
|
|
57
|
+
if (file === baseFileName + '.properties') {
|
|
58
|
+
const filePath = path.join(propertiesPath, file);
|
|
59
|
+
const baseData = loadPropertiesFile(filePath, compilation, 'JSResources base');
|
|
60
|
+
allI18n['en_US'] = baseData;
|
|
61
|
+
locales.push('en_US');
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
files.forEach(file => {
|
|
65
|
+
if (!file.endsWith('.properties')) return;
|
|
66
|
+
const match = file.match(/^ApplicationResources_([a-z]{2}_[A-Z]{2})\.properties$/);
|
|
67
|
+
|
|
68
|
+
if (match) {
|
|
69
|
+
const locale = match[1];
|
|
70
|
+
const filePath = path.join(propertiesPath, file);
|
|
71
|
+
const localeData = loadPropertiesFile(filePath, compilation, `locale ${locale}`);
|
|
72
|
+
allI18n[locale] = { ...allI18n['en_US'],
|
|
73
|
+
...localeData
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
if (!locales.includes(locale)) {
|
|
77
|
+
locales.push(locale);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
} catch (err) {
|
|
82
|
+
if (compilation) {
|
|
83
|
+
compilation.errors.push(new Error(`I18nNumericIndexPlugin: Error reading properties folder: ${err.message}`));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
allI18n,
|
|
89
|
+
locales
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function loadI18nData(options, compilation) {
|
|
94
|
+
const jsResourcePath = path.resolve(compilation.compiler.context, options.jsResourcePath);
|
|
95
|
+
const propertiesPath = path.resolve(compilation.compiler.context, options.propertiesFolderPath);
|
|
96
|
+
const baseFileName = path.basename(options.jsResourcePath, '.properties');
|
|
97
|
+
const jsResourceBase = loadPropertiesFile(jsResourcePath, compilation, 'JS resources');
|
|
98
|
+
const {
|
|
99
|
+
allI18n,
|
|
100
|
+
locales
|
|
101
|
+
} = loadAllLocaleFiles(propertiesPath, baseFileName, compilation);
|
|
102
|
+
return {
|
|
103
|
+
jsResourceBase,
|
|
104
|
+
allI18n,
|
|
105
|
+
locales
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
module.exports = {
|
|
110
|
+
loadPropertiesFile,
|
|
111
|
+
loadNumericMap,
|
|
112
|
+
loadAllLocaleFiles,
|
|
113
|
+
loadI18nData
|
|
114
|
+
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.decodeUnicodeEscapes = decodeUnicodeEscapes;
|
|
6
7
|
exports.getAllI18n = getAllI18n;
|
|
7
8
|
exports.getPropertiesAsJSON = getPropertiesAsJSON;
|
|
8
9
|
exports.jsonToString = jsonToString;
|
|
@@ -13,6 +14,10 @@ var _path = require("path");
|
|
|
13
14
|
|
|
14
15
|
var _constants = require("../../../../../constants");
|
|
15
16
|
|
|
17
|
+
function decodeUnicodeEscapes(str) {
|
|
18
|
+
return str.replace(/\\u([0-9A-Fa-f]{4})/g, (_, code) => String.fromCharCode(parseInt(code, 16)));
|
|
19
|
+
}
|
|
20
|
+
|
|
16
21
|
function isComment(line) {
|
|
17
22
|
return line[0] === '#';
|
|
18
23
|
}
|
|
@@ -5,13 +5,21 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.jsLoaders = jsLoaders;
|
|
7
7
|
|
|
8
|
-
var _babelLoaderConfig = require("./loaderConfigs/babelLoaderConfig");
|
|
8
|
+
var _babelLoaderConfig = require("./loaderConfigs/babelLoaderConfig.js");
|
|
9
|
+
|
|
10
|
+
var _i18nIdReplaceLoaderConfig = require("./loaderConfigs/i18nIdReplaceLoaderConfig.js");
|
|
9
11
|
|
|
10
12
|
function jsLoaders(options) {
|
|
13
|
+
const useLoaders = [(0, _babelLoaderConfig.babelLoaderConfig)(options)];
|
|
14
|
+
const shouldUseNumericIndexing = options.i18nIndexing.enable;
|
|
15
|
+
|
|
16
|
+
if (shouldUseNumericIndexing) {
|
|
17
|
+
useLoaders.push((0, _i18nIdReplaceLoaderConfig.i18nIdReplaceLoaderConfig)(options));
|
|
18
|
+
}
|
|
19
|
+
|
|
11
20
|
return [{
|
|
12
21
|
test: /\.js$/,
|
|
13
22
|
exclude: /node_modules/,
|
|
14
|
-
use:
|
|
15
|
-
|
|
23
|
+
use: useLoaders
|
|
16
24
|
}];
|
|
17
25
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.i18nIdReplaceLoaderConfig = i18nIdReplaceLoaderConfig;
|
|
7
|
+
|
|
8
|
+
var _propertiesUtils = require("../custom_plugins/I18nSplitPlugin/utils/propertiesUtils.js");
|
|
9
|
+
|
|
10
|
+
function getI18nConfig(options) {
|
|
11
|
+
if (!options.i18nIndexing?.enable) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
jsResourcePath: options.i18nIndexing.jsResourcePath,
|
|
17
|
+
numericMapPath: options.i18nIndexing.numericMapPath
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function loadJSResources(jsResourcePath) {
|
|
22
|
+
const i18nData = (0, _propertiesUtils.getPropertiesAsJSON)(jsResourcePath);
|
|
23
|
+
|
|
24
|
+
if (Object.keys(i18nData).length === 0) {
|
|
25
|
+
console.warn(`[i18nIdReplaceLoaderConfig] Warning: No i18n data found in JSResource file: ${jsResourcePath}`);
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return i18nData;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function i18nIdReplaceLoaderConfig(options) {
|
|
33
|
+
const config = getI18nConfig(options);
|
|
34
|
+
|
|
35
|
+
if (!config) {
|
|
36
|
+
throw new Error('i18nIdReplaceLoader requires i18nIndexing to be enabled');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!config.jsResourcePath) {
|
|
40
|
+
throw new Error('Missing required jsResourcePath in i18n options');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!config.numericMapPath) {
|
|
44
|
+
throw new Error('numericMapPath is required in i18nIndexing config');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
loader: require.resolve('../loaders/i18nIdReplaceLoader.js'),
|
|
49
|
+
options: {
|
|
50
|
+
allI18nData: loadJSResources(config.jsResourcePath),
|
|
51
|
+
numericMapPath: config.numericMapPath,
|
|
52
|
+
sourceMaps: false
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
|
|
5
|
+
const parser = require('@babel/parser');
|
|
6
|
+
|
|
7
|
+
const traverse = require('@babel/traverse').default;
|
|
8
|
+
|
|
9
|
+
const generator = require('@babel/generator').default;
|
|
10
|
+
|
|
11
|
+
const t = require('@babel/types');
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
getOptions
|
|
15
|
+
} = require('loader-utils');
|
|
16
|
+
|
|
17
|
+
function loadNumericMap(numericMapPath) {
|
|
18
|
+
if (!numericMapPath) {
|
|
19
|
+
console.warn('[i18nIdReplaceLoader] numericMapPath option is missing');
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (!fs.existsSync(numericMapPath)) {
|
|
24
|
+
console.warn(`[i18nIdReplaceLoader] Numeric map file not found: ${numericMapPath}`);
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const fileContent = fs.readFileSync(numericMapPath, 'utf-8');
|
|
30
|
+
const parsedData = JSON.parse(fileContent);
|
|
31
|
+
|
|
32
|
+
if (!parsedData?.originalKeyToNumericId) {
|
|
33
|
+
console.warn(`[i18nIdReplaceLoader] Invalid numeric map format: missing 'originalKeyToNumericId'`);
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return parsedData.originalKeyToNumericId;
|
|
38
|
+
} catch (err) {
|
|
39
|
+
console.warn(`[i18nIdReplaceLoader] Error reading numeric map: ${err.message}`);
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function transformSource(source, resourcePath, numericIdMap, allI18nData, options) {
|
|
45
|
+
const ast = parser.parse(source, {
|
|
46
|
+
sourceType: 'module',
|
|
47
|
+
plugins: ['jsx', 'typescript', 'classProperties', 'optionalChaining', 'nullishCoalescingOperator'],
|
|
48
|
+
sourceFilename: resourcePath
|
|
49
|
+
});
|
|
50
|
+
let hasTransformations = false;
|
|
51
|
+
traverse(ast, {
|
|
52
|
+
StringLiteral(path) {
|
|
53
|
+
const {
|
|
54
|
+
node
|
|
55
|
+
} = path;
|
|
56
|
+
|
|
57
|
+
if (!(node.value in allI18nData)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (node.value in numericIdMap) {
|
|
62
|
+
path.replaceWith(t.stringLiteral(String(numericIdMap[node.value])));
|
|
63
|
+
hasTransformations = true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
if (!hasTransformations) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return generator(ast, {
|
|
74
|
+
sourceMaps: !!options.sourceMaps,
|
|
75
|
+
sourceFileName: resourcePath,
|
|
76
|
+
retainLines: false,
|
|
77
|
+
comments: true
|
|
78
|
+
}, source);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = function i18nIdReplaceLoader(source, map) {
|
|
82
|
+
const resourcePath = this.resourcePath;
|
|
83
|
+
if (this.cacheable) this.cacheable();
|
|
84
|
+
const options = getOptions(this) || {};
|
|
85
|
+
const callback = this.async();
|
|
86
|
+
|
|
87
|
+
if (resourcePath.includes('node_modules') || !resourcePath.includes('src')) {
|
|
88
|
+
return callback(null, source, map);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!options.allI18nData) {
|
|
92
|
+
return callback(null, source, map);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (options.numericMapPath) {
|
|
96
|
+
this.addDependency(options.numericMapPath);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const numericIdMap = loadNumericMap(options.numericMapPath);
|
|
100
|
+
|
|
101
|
+
if (!numericIdMap) {
|
|
102
|
+
return callback(null, source, map);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
const output = transformSource(source, resourcePath, numericIdMap, options.allI18nData, options);
|
|
107
|
+
|
|
108
|
+
if (output) {
|
|
109
|
+
callback(null, output.code, output.map);
|
|
110
|
+
} else {
|
|
111
|
+
callback(null, source, map);
|
|
112
|
+
}
|
|
113
|
+
} catch (err) {
|
|
114
|
+
callback(err);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.configI18nNumericIndexPlugin = configI18nNumericIndexPlugin;
|
|
7
|
+
|
|
8
|
+
var _I18nNumericIndexPlugin = require("../custom_plugins/I18nNumericIndexPlugin/I18nNumericIndexPlugin.js");
|
|
9
|
+
|
|
10
|
+
const REQUIRED_OPTIONS = ['jsResourcePath', 'propertiesFolderPath', 'numericMapPath'];
|
|
11
|
+
|
|
12
|
+
function configI18nNumericIndexPlugin(options) {
|
|
13
|
+
const i18nOptions = options.i18nIndexing;
|
|
14
|
+
|
|
15
|
+
if (!i18nOptions.enable) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const missingOptions = REQUIRED_OPTIONS.filter(opt => !i18nOptions[opt]);
|
|
20
|
+
|
|
21
|
+
if (missingOptions.length > 0) {
|
|
22
|
+
throw new Error(`[I18nNumericIndexPlugin] Missing required: ${missingOptions.join(', ')}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return new _I18nNumericIndexPlugin.I18nNumericIndexPlugin(i18nOptions);
|
|
26
|
+
}
|
|
@@ -57,10 +57,11 @@ var _configInjectChunkGraphPlugin = require("./pluginConfigs/configInjectChunkGr
|
|
|
57
57
|
|
|
58
58
|
var _configCssCustomOrderPlugin = require("./pluginConfigs/configCssCustomOrderPlugin");
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
var _configI18nNumericIndexPlugin = require("./pluginConfigs/configI18nNumericIndexPlugin");
|
|
61
|
+
|
|
61
62
|
function plugins(options) {
|
|
62
63
|
const {
|
|
63
64
|
webpackPlugins
|
|
64
65
|
} = options;
|
|
65
|
-
return [(0, _configEnvVariables.configEnvVariables)(options), (0, _configCustomAttributesPlugin.configCustomAttributesPlugin)(options), (0, _configTPHashMappingPlugin.configTPHashMappingPlugin)(options), (0, _configCopyPublicFolders.configCopyPublicFolders)(options), (0, _configIgnorePlugin.configIgnorePlugin)(options), (0, _configMiniCSSExtractPlugin.configMiniCSSExtractPlugin)(options), (0, _configSelectorWeightPlugin.configSelectorWeightPlugin)(options), (0, _configVariableConversionPlugin.configVariableConversionPlugin)(options), (0, _configI18nSplitPlugin.configI18nSplitPlugin)(options), (0, _configRtlCssPlugin.configRtlCssPlugin)(options), (0, _configHtmlWebpackPlugin.configHtmlWebpackPlugin)(options), (0, _configCustomScriptLoadingStrategyPlugin.configCustomScriptLoadingStrategyPlugin)(options), (0, _configCdnChangePlugin.configCdnChangePlugin)(options), (0, _configServiceWorkerPlugin.configServiceWorkerPlugin)(options), (0, _configEFCTemplatePlugin.configEFCTemplatePlugin)(options), (0, _configResourceHintsPlugin.configResourceHintsPlugin)(options), (0, _configBundleAnalyzer.configBundleAnalyzer)(options), (0, _configManifestJsonPlugin.configManifestJsonPlugin)(options), (0, _configSourceMapPlugin.configSourceMapPlugin)(options), (0, _configProgressPlugin.configProgressPlugin)(options), (0, _configBundleIntegrityReport.configBundleIntegrityReport)(options), (0, _configRuntimeResourceCleanup.configRuntimeResourceCleanup)(options), (0, _configMurphyInjectorPlugin.configMurphyInjectorPlugin)(options), (0, _configCssCustomOrderPlugin.configCssCustomOrderPlugin)(options), (0, _configChunkHierarchyPlugin.configChunkHierarchyPlugin)(options), ...webpackPlugins].filter(Boolean);
|
|
66
|
+
return [(0, _configEnvVariables.configEnvVariables)(options), (0, _configCustomAttributesPlugin.configCustomAttributesPlugin)(options), (0, _configTPHashMappingPlugin.configTPHashMappingPlugin)(options), (0, _configCopyPublicFolders.configCopyPublicFolders)(options), (0, _configIgnorePlugin.configIgnorePlugin)(options), (0, _configMiniCSSExtractPlugin.configMiniCSSExtractPlugin)(options), (0, _configSelectorWeightPlugin.configSelectorWeightPlugin)(options), (0, _configVariableConversionPlugin.configVariableConversionPlugin)(options), (0, _configI18nSplitPlugin.configI18nSplitPlugin)(options), (0, _configRtlCssPlugin.configRtlCssPlugin)(options), (0, _configHtmlWebpackPlugin.configHtmlWebpackPlugin)(options), (0, _configI18nNumericIndexPlugin.configI18nNumericIndexPlugin)(options), (0, _configCustomScriptLoadingStrategyPlugin.configCustomScriptLoadingStrategyPlugin)(options), (0, _configCdnChangePlugin.configCdnChangePlugin)(options), (0, _configServiceWorkerPlugin.configServiceWorkerPlugin)(options), (0, _configEFCTemplatePlugin.configEFCTemplatePlugin)(options), (0, _configResourceHintsPlugin.configResourceHintsPlugin)(options), (0, _configBundleAnalyzer.configBundleAnalyzer)(options), (0, _configManifestJsonPlugin.configManifestJsonPlugin)(options), (0, _configSourceMapPlugin.configSourceMapPlugin)(options), (0, _configProgressPlugin.configProgressPlugin)(options), (0, _configBundleIntegrityReport.configBundleIntegrityReport)(options), (0, _configRuntimeResourceCleanup.configRuntimeResourceCleanup)(options), (0, _configMurphyInjectorPlugin.configMurphyInjectorPlugin)(options), (0, _configCssCustomOrderPlugin.configCssCustomOrderPlugin)(options), (0, _configChunkHierarchyPlugin.configChunkHierarchyPlugin)(options), ...webpackPlugins].filter(Boolean);
|
|
66
67
|
}
|
|
@@ -7,11 +7,19 @@ exports.tsLoaders = tsLoaders;
|
|
|
7
7
|
|
|
8
8
|
var _babelLoaderConfig = require("./loaderConfigs/babelLoaderConfig");
|
|
9
9
|
|
|
10
|
+
var _i18nIdReplaceLoaderConfig = require("./loaderConfigs/i18nIdReplaceLoaderConfig");
|
|
11
|
+
|
|
10
12
|
function tsLoaders(options) {
|
|
13
|
+
const useLoaders = ['ts-loader'];
|
|
14
|
+
const shouldUseNumericIndexing = options.i18nIndexing.enable;
|
|
15
|
+
|
|
16
|
+
if (shouldUseNumericIndexing) {
|
|
17
|
+
useLoaders.push((0, _i18nIdReplaceLoaderConfig.i18nIdReplaceLoaderConfig)(options));
|
|
18
|
+
}
|
|
19
|
+
|
|
11
20
|
return [{
|
|
12
21
|
test: /\.tsx?$/,
|
|
13
22
|
exclude: /node_modules/,
|
|
14
|
-
use:
|
|
15
|
-
|
|
23
|
+
use: useLoaders
|
|
16
24
|
}];
|
|
17
25
|
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zohodesk/client_build_tool",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20-experimental.0",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@zohodesk/client_build_tool",
|
|
9
|
-
"version": "0.0.
|
|
9
|
+
"version": "0.0.20-experimental.0",
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@babel/cli": "7.17.10",
|