@zohodesk/client_build_tool 0.0.11-exp.15 → 0.0.11-exp.15.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.
Files changed (28) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +28 -0
  3. package/docs/I18N_NUMERIC_INDEXING_PLUGIN.md +225 -0
  4. package/docs/client_build_tool_source_doc.md +390 -0
  5. package/lib/schemas/defaultConfigValues.js +17 -14
  6. package/lib/schemas/defaultConfigValuesOnly.js +4 -21
  7. package/lib/shared/babel/getBabelPlugin.js +3 -4
  8. package/lib/shared/babel/runBabelForTsFile.js +1 -1
  9. package/lib/shared/bundler/webpack/custom_plugins/BundleIntegrityReport/index.js +10 -0
  10. package/lib/shared/bundler/webpack/custom_plugins/I18nNumericIndexPlugin/I18nGroupRuntimeModule.js +124 -0
  11. package/lib/shared/bundler/webpack/custom_plugins/I18nNumericIndexPlugin/I18nNumericIndexPlugin.js +207 -145
  12. package/lib/shared/bundler/webpack/jsLoaders.js +2 -20
  13. package/lib/shared/bundler/webpack/pluginConfigs/configCopyPublicFolders.js +3 -2
  14. package/lib/shared/bundler/webpack/pluginConfigs/configI18nIndexingPlugin.js +42 -0
  15. package/lib/shared/bundler/webpack/pluginConfigs/configI18nNumericHtmlInjector.js +92 -0
  16. package/lib/shared/bundler/webpack/plugins.js +6 -2
  17. package/lib/shared/postcss/custom_postcss_plugins/VariableModificationPlugin/index.js +1 -1
  18. package/lib/shared/server/mockApiHandler.js +7 -0
  19. package/lib/shared/server/urlConcat.js +4 -3
  20. package/npm-shrinkwrap.json +354 -38
  21. package/package.json +6 -5
  22. package/lib/shared/bundler/webpack/custom_plugins/I18nNumericIndexPlugin/I18nNumericIndexHtmlInjectorPlugin.js +0 -49
  23. package/lib/shared/bundler/webpack/custom_plugins/I18nNumericIndexPlugin/utils/i18nDataLoader.js +0 -106
  24. package/lib/shared/bundler/webpack/custom_plugins/I18nSplitPlugin/utils/collectAstKeys.js +0 -96
  25. package/lib/shared/bundler/webpack/loaderConfigs/i18nIdReplaceLoaderConfig.js +0 -71
  26. package/lib/shared/bundler/webpack/loaders/i18nIdReplaceLoader.js +0 -106
  27. package/lib/shared/bundler/webpack/pluginConfigs/configI18nNumericIndexPlugin.js +0 -84
  28. package/lib/shared/bundler/webpack/utils/propertiesParser.js +0 -81
@@ -0,0 +1,390 @@
1
+ # Client Build Tool — Source Documentation
2
+
3
+ This document summarizes functionality, imports/exports, and key APIs for each source file in `packages/client_build_tool`, excluding `node_modules`, built `lib/dist/build` outputs, and OS/editor artifacts. It is maintained as a single, append-only reference. In addition, the first sections provide a narrative of the overall architecture and flows so you can answer “how does this work?” end-to-end.
4
+
5
+ ## Architecture Overview
6
+
7
+ - **Purpose:** A configurable client build tool and dev server wrapper that standardizes Webpack, Babel, and PostCSS setup for React apps, with advanced features such as i18n chunking/indexing, RTL splitting, CDN path customization, EFC SDK generation, and service worker support.
8
+ - **Execution model:**
9
+ - CLI entry `cli.js` resolves arguments and delegates to `src/commandsRouter.js`.
10
+ - Each command (`start`, `buildEs`, `buildLib`, `mockServer`, `pre_process`, `template`, `version`) lives under `src/commands/<name>` with a lifecycle of optional files: `optionsProcessor` → `deprecationHandler` → `preProcessor` → `commandExecutor` → `postProcessor`.
11
+ - Configuration is resolved once via `src/schemas/readOptions.js` from three sources: defaults (`defaultConfigValues.js`) + user config (package.json or `cbt.config.js`) + CLI/env (npm_config_*, `--key=value`).
12
+ - **Build pipeline:**
13
+ - For app builds: Webpack 5 configured via `src/shared/bundler/webpack/webpackConfig.js` (entry/output/loaders/plugins/stats/resolve/optimization/devtool).
14
+ - For library/ES transpiles: file-watcher pipeline (`watchRun.js`) dispatches to Babel/PostCSS/copy based on file extension.
15
+ - **Dev server:**
16
+ - Express app with permissive CORS, optional mock API proxy, and webpack-dev-middleware. HTTP and HTTPS listeners are started concurrently using computed publicPath/ports.
17
+ - Initial HTML is dynamically modified for mock/demo of locale/dir, and to normalize protocol.
18
+ - **i18n support:**
19
+ - Two modes:
20
+ - Chunk split at build-time (`I18nSplitPlugin`) to emit per-locale chunks and runtime loader glue.
21
+ - Numeric indexing (`I18nNumericIndexPlugin`) to emit numeric-keyed resources (optionally single-file mode) and inject initial assets tags into HTML.
22
+ - **CSS and RTL:**
23
+ - PostCSS pipeline with custom plugins (selector/value replacement, hover/active media split, variable modifications).
24
+ - Build-time RTL split emits `[dir]`-templated CSS names and rewrites paths in HTML/runtime where needed.
25
+ - **Extensibility:**
26
+ - Pluggable PostCSS plugins with per-file pattern filters.
27
+ - Webpack plugin config layer for toggling features via options.
28
+ - Custom loaders via `options.customLoaders` and module resolution override via `resolve.moduleResolvePath`.
29
+ - Quick Start: See `init/README.md` and `init/cbt.config.example.js` for installation, scripts, and a minimal configuration you can copy into your app.
30
+
31
+ ## End-to-End Flows
32
+
33
+ - **Start dev server (`cbt start`)**
34
+ - CLI → `route('start')` → `optionsProcessor` computes server extras (ports/URLs/https), publicPath, context folder.
35
+ - Optional `preProcessor` runs app-provided script under `nodemon` (e.g., generators/mocks).
36
+ - `commandExecutor` boots Express (`initExpressApp`) + CORS + mock API + webpack-dev-middleware with `webpackConfigCreator(options)`.
37
+ - Servers: `startHttpsServer` (if cert package available) and `startHttpServer`. `initialHTMLHandling` serves `index.html` with optional template token replacements for locale/dir.
38
+
39
+ - **Transpile to ES or lib (`cbt build:es` / `cbt build:lib`)**
40
+ - CLI → `route('buildEs'|'buildLib')` → parse `extraArgs` for `src` and `target` (defaults to `app/src` and `app/es|lib`).
41
+ - Optional pre-process runs once or in watch mode.
42
+ - `watchRun` performs a single pass (and optionally watches):
43
+ - `.js` → Babel (`runBabelForJSFile` with `babelWebConfig`)
44
+ - `.ts,.tsx` → Babel TS path with TS preset when `typeScript.enable` is true
45
+ - `.css` → PostCSS (`runPostCssForCssFile`) with plugins allowed by file patterns
46
+ - others → streamed copy
47
+
48
+ - **App build (via dev-middleware and plugin stack)**
49
+ - `webpackConfigCreator` composes:
50
+ - `entryConfig`: `main` plus optional EFC entry
51
+ - `outputConfig`: hashed name templates, `publicPath`, JSONP global
52
+ - loaders: `babel-loader`, TSX, CSS (MiniCssExtractPlugin + PostCSS), assets, workers, HTML templates
53
+ - plugins (order matters): env defines → attributes → TP hash mapping → copy public → ignore → CSS extract → selector weight → variable conversion → i18n split → RTL CSS → HTML → i18n numeric index → custom script loading → CDN mapping → SW → EFC SDK → resource hints → bundle analyzer → manifests → source maps → progress → integrity report → runtime cleanup → user `webpackPlugins`
54
+ - optimization: Terser/CSS minimizers, split-chunks (vendor/react + custom groups), runtime chunk naming (locale suffix when needed)
55
+
56
+ - **Mock API**
57
+ - If `mockServer.enable` and `separateSeverPort`: proxy `mockPrefix` (default `/api`) to the external mock server (you can run `cbt mock:server`).
58
+ - Otherwise, mount the app’s mock file path (resolved via `joinWithAppPath`) under the Express app.
59
+
60
+ - **i18n flows**
61
+ - Chunk split: Emit per-locale chunk files using templates from `nameTemplates('i18njs')`, a manifest, and runtime assembly for loading.
62
+ - Numeric index: Parse source `.properties` and JS resources, generate either per-locale numeric/dynamic files or a single-file bundle, optionally with contenthash and a manifest; inject initial assets in HTML.
63
+
64
+ - **CDN & runtime URL control**
65
+ - `CdnChangePlugin` can prefix JS/CSS/i18n URLs with template placeholders and patch Webpack runtime to use a global variable for chunk paths (e.g., SMAP variable). Works together with separate source maps if enabled.
66
+
67
+ ## Configuration Resolution & Validation
68
+
69
+ - **Sources & precedence:**
70
+ - Base schema: `src/schemas/defaultConfigValues.js` (supports nested keys and CLI aliases via `cli` field)
71
+ - User config: `package.json[react-cli]` or `cbt.config.js` (via `--config_file`)
72
+ - CLI args/env: `npm_config_*` and inline `--key=value` become camel/underscore keys per parser rules
73
+ - Merger: `applyValuesToSchema` recursively resolves each schema leaf, preferring CLI/env over user config over defaults
74
+ - **Compatibility shims:**
75
+ - `app_domain`, `app_port`, `app_host` CLI/env keys map to `domain`, `port`, `host`; `app_domain === 'kubernetes'` enables `server.k8s`
76
+ - `deprecatedOptionsHandler` mutates legacy keys and prints warnings
77
+ - **Validation:**
78
+ - `configValidator` exposes `validateConfig`/`validateConfigWithWarnings`, type guards, path checks, port ranges, and i18n-indexing cross-field constraints (e.g., templates must contain `[locale]`).
79
+
80
+ ## Extensibility & Customization
81
+
82
+ - **PostCSS:**
83
+ - Enable or disable built-ins in `options.css.plugins` and scope them by `patterns`.
84
+ - Add custom plugins via `options.css.customPlugins` (string module path or function) with per-file patterns.
85
+ - **Webpack:**
86
+ - Pass additional plugin instances in `options.webpackPlugins`.
87
+ - Add custom webpack loaders via `options.customLoaders`.
88
+ - Override module resolution root via `options.resolve.moduleResolvePath` (local/global resolver package), or prefer local node_modules first.
89
+ - **Paths & templates:**
90
+ - Control asset name templates and hashing via `nameTemplates`-related options (`enableFileNameHashing`, `devLikeHash`, etc.).
91
+ - Configure publicPath calculation and server URLs using `server` and `context` options.
92
+ - **EFC SDK:**
93
+ - Enable `options.efc.hasEFC` and `createSDkFile` to emit a templated SDK file with initial assets function and publicPath injection.
94
+
95
+ ## Operational Notes
96
+
97
+ - **Node support:** `doBasicRequirementCheck` enforces Node v14–v18.
98
+ - **Verbose logging:** Set `VERBOSE=true` to enable `verboseLogger` output (yellow-tagged logs).
99
+ - **HTTPS certs:** `server.httpsCerts` may refer to a local/global npm package exposing `{ httpsOptions }`. Defaults to `@zohodesk-private/client_dev_cert` if present globally.
100
+ - **Cross-origin & CSP:** `InitialHtmlPlugin` injects a nonce attribute placeholder into tags; `corsHandling` sets permissive headers for dev.
101
+ - **Kubernetes:** With `server.k8s=true`, server URL resolves to `https://<domain>/` without explicit port; otherwise dual-port scheme is used (HTTPS `port`, HTTP `port+1`).
102
+
103
+
104
+ ## CLI Entrypoint
105
+
106
+ ### cli.js
107
+ - Purpose: Executable entry; polyfills, prints version, parses CLI option/args, routes command.
108
+ - Imports: `./polyfillForOldNodeVersion`, `./lib/logger`, `./lib/commandsRouter`, `./lib/shared/commands-utils`, `./lib/shared/utils/versionPrint` (built outputs).
109
+ - Exports: none; runs on invoke.
110
+ - Flow: Calls `polyfillForOldNodeVersion()`, logs banner via `verboseLogger`, `versionPrint(verboseLogger)`, reads option/args, `doBasicRequirementCheck()`, then `route(option)`.
111
+
112
+ ### polyfillForOldNodeVersion.js
113
+ - Purpose: Adds `String.prototype.replaceAll` for older Node versions.
114
+ - Exports: `polyfillForOldNodeVersion()` (CommonJS `exports`).
115
+
116
+ ## Public API
117
+
118
+ ### src/index.js
119
+ - Purpose: Thin programmatic API for running commands.
120
+ - Imports: `runCommand` from `./commandsRouter`.
121
+ - Exports: `run(commandName, options)` → `runCommand`.
122
+
123
+ ## Command Router and Logging
124
+
125
+ ### src/commandsRouter.js
126
+ - Purpose: Dispatches a command through standard lifecycle steps.
127
+ - Imports: `fs.existsSync`, `path.join`, `allCommandsConfigs`, `{ errorLogger, verboseLogger, warnLogger }`, `getOptions`.
128
+ - Exports:
129
+ - `runCommand(commandName, options)`: Locates matching command config; dynamically requires and executes files in the command dir: `optionsProcessor`, `deprecationHandler`, `preProcessor`, `commandExecutor`, `postProcessor` (if present).
130
+ - `route(commandName)`: Builds `options` via `getOptions()` and calls `runCommand` with error logging.
131
+ - Internal: `findCommandConfig(option)` checks by `name` or `alias`.
132
+
133
+ ### src/logger.js
134
+ - Purpose: CLI logging helpers.
135
+ - Exports: `verboseLogger`, `warnLogger`, `messageLogger`, `debugLogger`, `errorLogger`.
136
+
137
+ ### src/allCommandsConfigs.js
138
+ - Purpose: Auto-discovers `src/commands/*/config.js` and aggregates default exports.
139
+ - Exports: default array of configs.
140
+
141
+ ## Commands
142
+
143
+ ### start (src/commands/start/*)
144
+ - config.js: Default export `{ name: 'start', alias: ['dstart','devSeverStart'], dirname }`.
145
+ - optionsProcessor.js:
146
+ - Computes `serverExtras` (ports, URLs, HTTPS options), `publicPath` (unless `noPublicPath`), `contextFolderPath` via `joinWithAppPath`, and normalizes `mode` to `dev|prod`.
147
+ - Exports: `optionsProcessor(options)`.
148
+ - preProcessor.js: Runs `runPreProcess(options, 'nodemon')` before server.
149
+ - commandExecutor.js: Starts dev server via `shared/server/serverBywebpackDevMiddleware.run(options)`.
150
+
151
+ ### buildEs (src/commands/buildEs/*)
152
+ - config.js: Default export `{ name: 'buildEs', alias: ['build_es','build:es'], dirname }`.
153
+ - preProcessor.js: Detects `-w` watch; runs `runPreProcess` with `'nodemon'` if watch else `'node'`.
154
+ - commandExecutor.js: Parses `[src,target]` from `extraArgs` (defaults `src -> app/src`, `target -> app/es`), then calls `watchRun({ mode: 'es' })`.
155
+
156
+ ### buildLib (src/commands/buildLib/*)
157
+ - config.js: Default export `{ name: 'buildLib', alias: ['build:lib','build_lib'], dirname }`.
158
+ - preProcessor.js: Same watch handling as buildEs.
159
+ - commandExecutor.js: Defaults `target -> app/lib`, runs `watchRun({ mode: 'lib' })`.
160
+
161
+ ### mockServer (src/commands/mockserver/*)
162
+ - config.js: Default export `{ name: 'mockServer', alias: ['mockserver','mock_server','mock-server','mock:server'], dirname }`.
163
+ - commandExecutor.js:
164
+ - Reads `options.mockServer { enable, separateSeverPort, mockEntryFile, disableNodemon }`.
165
+ - If separate port: proxies requests; otherwise runs CLI-managed mock server; logs target paths.
166
+
167
+ ### pre_process (src/commands/pre_process/*)
168
+ - config.js: Default export `{ name: 'pre_process', alias: ['preprocess','pre:process','preProcess'], dirname }`.
169
+ - commandExecutor.js: Detects `-w`; runs preprocessing via `runPreProcess`. Exits with status when not watching.
170
+
171
+ ### template (src/commands/template/*)
172
+ - config.js: Default export `{ name: 'template', alias: ['template','templates'], dirname }`.
173
+ - commandExecutor.js: Supports templates: `app`, `library`. Copies with `cp -r getTemplatePath(templateName)` using `spawnSyncIO`.
174
+
175
+ ### version (src/commands/version/*)
176
+ - config.js: Default export `{ name: 'version', alias: ['v','-v','--v','-version','--version'], dirname }`.
177
+ - commandExecutor.js: Invokes `versionPrint(messageLogger)`.
178
+
179
+ ## Schemas and Options
180
+
181
+ ### src/schemas/defaultConfigValues.js
182
+ - Purpose: Full schema describing options, defaults, and CLI mapping keys for `applyValuesToSchema`.
183
+ - Exports: default object with nested option trees (server, mockServer, css plugins, i18nChunkSplit, i18nIndexing, resolve, htmlTemplate, efc, etc.).
184
+ - Notables: `server.k8s`, `httpsCerts`, `disableContextURL`; `mockServer` settings; rich CSS plugin customization; i18n splitting/indexing blocks; `preProcess` runner options; `typeScript.enable`; `customScriptLoadingStrategey`.
185
+
186
+ ### src/schemas/defaultConfigValuesOnly.js
187
+ - Purpose: Plain default values (no CLI mapping) suitable for config file generation or validation baselines.
188
+ - Exports: default object mirroring many keys (context, devtool, server, etc.).
189
+
190
+ ### src/schemas/cliArgsToObject.js
191
+ - Purpose: Experimental parser for `--key=value` or `--flag` CLI args to an object.
192
+ - Exports: `cliArgsToObject(cliArgs)` using `giveDefaultValue` and `key.replace(/-|:/g,'_')`.
193
+
194
+ ### src/schemas/giveDefaultValue.js
195
+ - Purpose: Coerces `'true'|'false'|''` to booleans; otherwise returns the value.
196
+ - Exports: `giveDefaultValue(value)`.
197
+
198
+ ### src/schemas/npmConfigToObject.js
199
+ - Purpose: Reads `process.env.npm_config_*` into object, duplicating colon-keys with underscores to avoid conflicts (warns on collisions).
200
+ - Exports: `npmConfigToObject()`.
201
+
202
+ ### src/schemas/getNpmVersion.js
203
+ - Purpose: Best-effort major npm version detection via `npm -v` (defaults to `'6'`).
204
+ - Exports: `getNpmVersion()`.
205
+
206
+ ### src/schemas/deprecatedOptionsHandler.js
207
+ - Purpose: Mutates options to handle deprecated keys and logs warnings.
208
+ - Exports: `deprecatedOptionsHandler(options)`; updates/aliases legacy paths (e.g., `app.context -> context`, RTL flags to new locations).
209
+
210
+ ### src/schemas/readOptionsForConfigFile.js
211
+ - Purpose: Reads CBT config from package.json under `BASE_CONFIG_KEY` or from an explicit config file.
212
+ - Imports: `BASE_CONFIG_KEY` from `shared/constants`.
213
+ - Exports:
214
+ - `readOptionsForPackageJson(appPath)` → object or empty.
215
+ - `readOptionsForConfigFile(appPath, configFile)` → `{config}` or null.
216
+
217
+ ### src/schemas/applyValuesToSchema/*
218
+ - index.js: Core merger `applyValuesToSchema(schemas, customOptions, processEnv)` that:
219
+ - For leaf schema: returns `customOptions[key] ?? default` unless `cli` is present, in which case it prefers `processEnv[cli]`.
220
+ - For objects: recurses into nested schema.
221
+ - Also exports helpers `isObject(obj)` and `isValid(value, fallback)`.
222
+ - isObject.js: Same object guard as above (non-null object and not array).
223
+ - isValid.js: Nullish coalescing with a `Number.isNaN` guard for numbers.
224
+
225
+ ### src/schemas/readOptions.js
226
+ - Purpose: Composes final `options` for the CLI by merging defaults, package/config file, and environment/CLI args.
227
+ - Exports:
228
+ - `args`: `process.argv.slice(2)`.
229
+ - `getOptions()`: Memoized; merges `defaultConfigValues` with config sources via `applyValuesToSchema`, runs `deprecatedOptionsHandler`, attaches `npmVersion`, `cwd`, `packageVersion`, `extraArgs`, and `commandOption`.
230
+ - CLI compatibility shims: maps `app_domain|app_port|app_host` into `domain|port|host` and infers `k8s`.
231
+
232
+ ### src/schemas/configValidator.js
233
+ - Purpose: Runtime validators and a structured `ConfigValidationError`.
234
+ - Exports:
235
+ - `ConfigValidationError` (class).
236
+ - `validateType`, `validateFilePath`, `validateDirectoryPath`, `validatePort`.
237
+ - `validateI18nIndexingDependencies(i18nConfig, basePath)`.
238
+ - `validateConfig(config, basePath)` and `validateConfigWithWarnings(config, basePath, strict)`; the latter logs warnings instead of throwing.
239
+
240
+ ## Shared Constants and Preprocess
241
+
242
+ ### src/shared/constants.js
243
+ - Purpose: Paths and constants used across the tool.
244
+ - Exports: `BASE_CONFIG_KEY='react-cli'`, `cliRootPath`, `CONFIG_ROOT`, `cliNodeModulesPath`, `babelrcPath`, `appPath`, `joinWithAppPath(filePath)`, `appNodeModules`, `templatesPath`, `getTemplatePath(...filePath)`.
245
+
246
+ ### src/shared/pre_process/runPreProcess.js
247
+ - Purpose: Executes an app-provided preprocess script under `nodemon` or `node`.
248
+ - Exports: `runPreProcess(options, runnerCli='node')` which resolves the app runner path, watches the directory for changes when using nodemon, and returns the spawn result. Logs and exits if path is missing.
249
+
250
+ ## Build Pipeline Helpers
251
+
252
+ ### src/shared/fileUtils/directoryIterator.js
253
+ - Purpose: Depth-first traversal; invokes callback for files and recurses into directories.
254
+ - Exports: `directoryIterator(filename, cb)`.
255
+
256
+ ### src/shared/fileUtils/copyFile.js
257
+ - Purpose: Ensure parent dirs exist and copy a file stream-to-stream.
258
+ - Exports: `createParentDir`, `copyFile(filename, outputFile)`, `writeFile(filename, data)`.
259
+
260
+ ### src/shared/fileUtils/watchRun.js
261
+ - Purpose: One-shot and watch-based compilation/copy pipeline for JS/TS/CSS/other assets.
262
+ - Exports: `watchRun({ options, src, target, canWatch, mode })` that dispatches by ext to Babel or PostCSS, copies others, prints counts/timing, and sets up `Watcher` if `canWatch`.
263
+
264
+ ### src/shared/commands-utils/*
265
+ - doBasicRequirementCheck.js: Throws if Node major version not in [14..18].
266
+ - getCliPath.js: Resolves binaries from CLI-local `node_modules/.bin` (adds `.cmd` on Windows); falls back to bare name.
267
+ - readArgsFormCommandLine.js / readOptionFormCommandLine.js: Simple argv readers.
268
+ - log.js: Minimal passthrough logger.
269
+ - index.js: Re-exports the above.
270
+
271
+ ### src/shared/commands-utils/spawnSyncIO.js
272
+ - Purpose: Spawn wrappers with CLI-local binary resolution.
273
+ - Exports: `defaultSpawnSyncOptions`, `spawnSyncIO(commandName, args, options)`, `spawnIO(commandName, args, cb)` with error logging.
274
+
275
+ ## Dev Server Composition
276
+
277
+ ### src/shared/server/*
278
+ - corsHandling.js: Adds permissive CORS headers and handles `OPTIONS` preflight.
279
+ - initExpressApp.js: Creates and configures Express app with JSON/urlencoded.
280
+ - configWebpackDevMiddleware.js: Creates webpack config, compiler, and applies dev middleware with headers and stats.
281
+ - startHttpsServer.js: Starts HTTPS server when `httpsOptions` is available; logs URL.
282
+ - startHttpServer.js: Starts HTTP listener; logs URL.
283
+ - initialHTMLHandling.js: Serves index HTML at `contextURL/*`, applies mock replacements for locale/dir, and flips https→http if request protocol is HTTP.
284
+ - mockApiHandler.js: If `mockServer.enable`, proxies to external mock server or mounts in-process handler based on options.
285
+ - getServerURL.js: `getServerDomain({host,domain,k8s})` and `getServerUrl({domain,k8s,port,protocol})` helpers.
286
+ - httpsOptions.js: `httpsOptionsWithUserFriendlyError(options)` loads certs from configured/local/global packages; logs user-friendly errors and exits if misconfigured.
287
+ - urlConcat.js: Joins base URL and path with slash-normalization.
288
+ - getIp.js: Returns first IPv4 address or `127.0.0.1`.
289
+ - serverBywebpackDevMiddleware.js: Orchestrates middleware composition and starts HTTP/HTTPS servers.
290
+
291
+ ## Webpack Bundler (Configs and Utilities)
292
+
293
+ ### Core config
294
+ - webpackConfig.js: Composes entry/output, loaders (JS/TS/CSS/assets), plugins, externals, resolve, and stats; uses `getWebpackMode`.
295
+ - plugins.js: Returns ordered plugin instances based on options (HTML, i18n split, RTL CSS, CDN, SW, EFC SDK, manifests, resource hints, integrity report, etc.).
296
+ - entryConfig.js: Adds `main` entry and optional EFC entry.
297
+ - outputConfig.js: Sets `filename`, `chunkFilename`, `publicPath`, `chunkLoadingGlobal` and target output path; supports `crossorigin`.
298
+ - jsLoaders.js: Applies `babel-loader` (+ optional i18n ID replace loader when numeric indexing is enabled).
299
+ - tsLoaders.js: Adds TSX support via Babel.
300
+ - cssLoaders.js and getCSSLoaders.js: Configure MiniCssExtractPlugin, css-loader, and PostCSS.
301
+ - loaderConfigs/*: Asset loaders, HTML template loader, Web Worker loader, Babel loader wrapper, and `checkIsPatternsMatchFilename` using `ignore` syntax.
302
+ - splitChunksConfig.js: Builds default vendor/react cache groups and user-defined custom cache groups using filename pattern tests.
303
+ - optimizationConfig.js: Terser + CSS minimizer, runtime chunk naming (optionally locale-suffixed when i18n chunks use contenthash).
304
+ - statsConfig.js: Minimal stats with overrides via `options.statsLogConfig`.
305
+ - devtoolConfig.js: Enables `devtool` only when `createSeparateSMap` is true.
306
+ - externals.js: Adds `ZC: '$ZC'` and merges `options.externals`.
307
+ - resolvers.js: Module and loader resolvers with optional package-group resolver; merges default library alias map; extension list `.ts,.js,.json,.tsx`.
308
+
309
+ ### Webpack common helpers
310
+ - common/nameTemplates.js: Template names (dev vs prod) for assets; `nameTemplates(type, options)`, `isI18nFile(url)`.
311
+ - common/modeUtils.js: Mode helpers and JSONP global naming.
312
+ - common/decidePublicPath.js: Builds server extras and selects `publicPath`.
313
+ - common/resourceBasedPublicPath.js: Returns public path or JS expression for i18n resources.
314
+ - common/libAlias.js: Maps internal packages from `/lib` to `/es`.
315
+
316
+ ### Webpack plugin configs (selected)
317
+ - configHtmlWebpackPlugin.js: Wraps InitialHtmlPlugin with minifier options and template path.
318
+ - configCdnChangePlugin.js: Enables CDN URL rewriting in production via CdnChangePlugin.
319
+ - configCopyPublicFolders.js: Copies app public folders to build output; supports defaults and merging with `...` placeholder.
320
+ - configMiniCSSExtractPlugin.js: Emits CSS filenames (with `[dir]` variants when RTL split is enabled).
321
+ - configI18nSplitPlugin.js: Configures i18n chunk splitting with filename templates and publicPath.
322
+ - configI18nNumericIndexPlugin.js: Validates i18n indexing settings, reads resources, and returns NumericIndex + HTML injector plugins.
323
+ - configEFCTemplatePlugin.js: Generates an EFC SDK file based on a template and initial assets.
324
+ - configServiceWorkerPlugin.js: Emits service worker with awareness of i18n/RTL assets.
325
+ - configResourceHintsPlugin.js: Adds runtime resource hinting hooks.
326
+ - configRuntimeResourceCleanup.js: Injects runtime cleanup when EFC and resource cleanup are enabled.
327
+ - configManifestJsonPlugin.js: Emits asset manifests for app, i18n, and license files.
328
+ - configSelectorWeightPlugin.js: Applies selector weighting plugin based on config.
329
+ - configBundleAnalyzer.js: Adds Webpack Bundle Analyzer for production when enabled.
330
+ - configBundleIntegrityReport.js: Emits a trimmed stats JSON report at build end.
331
+ - configEnvVariables.js: Injects environment defines based on dev/prod and `disableReactDevWarning`.
332
+ - configTPHashMappingPlugin.js: Emits a mapping file of hashed filenames to a variable for TP integration.
333
+ - configSourceMapPlugin.js: Adds separate source map plugin when enabled.
334
+ - configCustomAttributesPlugin.js: Injects custom attributes into tags in generated HTML.
335
+ - configCustomScriptLoadingStrategyPlugin.js: Applies per-file script loading strategies (blocking/defer/async/module) via tag transformation.
336
+
337
+ ## Webpack Custom Plugins (selected)
338
+
339
+ - CustomScriptLoadingPlugin.js (class `CustomScriptLoadingStrategyPlugin`): Adds/removes `defer/async/module` attributes on selected script tags.
340
+ - InitialHtmlPlugin.js: Thin wrapper around HtmlWebpackPlugin that injects nonce and reorders tags.
341
+ - ResourceHintsPlugin.js: Hooks Webpack runtime to compute prefetch/preload URLs for JS/CSS/i18n chunks, honoring `publicPath`.
342
+ - BundleIntegrityReport/index.js: Streams a filtered `stats.toJson()` to a file as a post-build report.
343
+ - CdnChangePlugin/index.js + webpackCustomJsUrlLoader.js: Rewrites emitted asset URLs with CDN templates; patches Webpack runtime to prefix chunk filenames via a global variable.
344
+ - RtlSplitPlugin/*:
345
+ - RtlCssPlugin.js: Splits CSS into LTR/RTL variants (via PostCSS RTLSplitPlugin) and adjusts output asset paths; uses OverwriteCssPathForRTL and helpers.
346
+ - OverwriteCssPathForRTL.js, replaceCssDirTemplate.js: Path templating and injection into runtime/HTML.
347
+ - EFCTemplatePlugin.js (class): Generates an SDK file using a template; injects a function returning initial asset URLs; supports RTL/i18n splitting.
348
+ - ManifestJsonPlugin/*: Adds configurable manifest JSONs (app/i18n/license) by inspecting emitted assets.
349
+ - I18nSplitPlugin/*: Orchestrates i18n key identification, file emission, and runtime handling for on-demand i18n chunks.
350
+ - I18nNumericIndexPlugin/*: Emits numeric-indexed i18n bundles and injects HTML placeholders for initial i18n assets.
351
+
352
+ ## Babel Pipeline
353
+
354
+ ### src/shared/babel/*
355
+ - addDefaultPlugins.js: Returns plugin tuple when enabled.
356
+ - babel_plugins/removeAttributesPlugin.js: Removes specified JSX attributes.
357
+ - babelWebConfig.js: Presets/plugins for web builds; respects TS and browser targets.
358
+ - getBabelPlugin.js: Production-only plugins from `options.babelCustomizations`.
359
+ - runBabelForJSFile.js / runBabelForTsFile.js: Transform-and-write helpers for JS/TSX.
360
+
361
+ ## PostCSS Pipeline
362
+
363
+ ### Core helpers
364
+ - filterPluginsAllowedForSpecficFile.js: Select built-in/custom plugins by filename patterns.
365
+ - getAllowedPostCssPlugins.js: Returns `{ plugins: [...] }` for a file; `postcssPluginGetter(options)` closure.
366
+ - getSpecificPostCssPlugin.js: Maps option names to actual plugin instances; supports RTL, selector/value replacement, hover/active, and variable replacement.
367
+ - runPostCssForCssFile.js: Runs PostCSS on a file and writes output.
368
+
369
+ ### Custom plugins
370
+ - RTLSplitPlugin.js: Splits CSS into LTR/RTL variants by removing opposite selectors/keyframes and minifying dir markers.
371
+ - HoverActivePlugin/*: Moves `:hover` to `(hover:hover)` media and `:active` to `(hover:none)` with ignore comments and AST helpers.
372
+ - SelectorReplace.js: Generic selector search/replace plugin with validation.
373
+ - ValueReplacer.js: Replaces declaration values per prop mapping (longest-key-first replacement).
374
+ - VariableModificationPlugin/index.js: Converts numeric CSS values into configured CSS variables and reports via error handler.
375
+ - EmptyPlugin.js: No-op extension point.
376
+
377
+ ## Utilities
378
+
379
+ - loaderConfigs/checkIsPatternsMatchFilename.js: Filename pattern matching with include/exclude (ignore syntax) and helpers to invert patterns.
380
+ - utils/updateArrayWithDefault.js: Replaces `...` in an array with default values.
381
+ - utils/getArrayWithDefaultWithCustomEqual.js: Like above with custom equality to avoid duplicates.
382
+ - utils/propertiesParser.js: Parses `.properties` content into object or set; decodes unicode escapes.
383
+ - utils/object-manipulation.js: Helpers for object key removal and streaming stringification.
384
+ - utils/getFilenameFromModule.js: Extracts userRequest/filename from Webpack modules.
385
+
386
+ ---
387
+
388
+ Progress
389
+ - Status: Completed
390
+ - Scope: All non-generated sources in `src` and CLI entry summarized; tests and built outputs ignored.
@@ -115,7 +115,10 @@ var _default = {
115
115
  // Name Suggestions `customizations` this will be easier then `plugin` to understand for developers
116
116
  plugins: {
117
117
  rtlSplit: {
118
- enableRTLSplit: false,
118
+ enableRTLSplit: {
119
+ value: false,
120
+ cli: 'enable_rtl_split'
121
+ },
119
122
  templateLabel: '{{--dir}}',
120
123
  disableMinifySelector: false,
121
124
  dirVarName: 'document.dir'
@@ -171,27 +174,27 @@ var _default = {
171
174
  localeVarName: 'document.documentElement.lang',
172
175
  jsonpFunc: 'console.log',
173
176
  jsResource: null,
174
- propertiesFolder: null,
175
- useNumericIndexing: false
177
+ propertiesFolder: null
176
178
  },
177
179
  i18nIndexing: {
178
- enable: false,
179
- devMode: false,
180
- jsResourcePath: './deskapp/properties/JSResources.properties',
181
- propertiesFolderPath: './deskapp/properties',
182
- numericMapPath: './deskapp/properties/i18n-numeric-map.json',
180
+ enable: {
181
+ value: false,
182
+ cli: 'i18n_indexing'
183
+ },
184
+ jsResourcePath: null,
185
+ propertiesFolderPath: null,
186
+ numericMapPath: null,
183
187
  numericFilenameTemplate: 'i18n-chunk/[locale]/numeric.i18n.js',
184
188
  dynamicFilenameTemplate: 'i18n-chunk/[locale]/dynamic.i18n.js',
185
- singleFileTemplate: 'i18n/[locale].js',
186
189
  jsonpFunc: 'window.loadI18nChunk',
187
190
  htmlTemplateLabel: '{{--user-locale}}',
188
191
  localeVarName: 'window.userLangCode',
189
- singleFile: false,
190
- includeContentHash: false,
191
- generateManifest: false,
192
- manifestPath: null
192
+ customGroups: null
193
+ },
194
+ publicFolders: {
195
+ dev: ['...'],
196
+ prod: ['...']
193
197
  },
194
- publicFolders: ['...'],
195
198
  app: {
196
199
  entryFile: {
197
200
  value: 'src/index.js',
@@ -94,29 +94,12 @@ var _default = {
94
94
  localeVarName: 'document.documentElement.lang',
95
95
  jsonpFunc: 'console.log',
96
96
  jsResource: null,
97
- propertiesFolder: null,
98
- useNumericIndexing: false
97
+ propertiesFolder: null
99
98
  },
100
- i18nIndexing: {
101
- enable: false,
102
- devMode: false,
103
- jsResourcePath: './deskapp/properties/JSResources.properties',
104
- propertiesFolderPath: './deskapp/properties',
105
- numericMapPath: './deskapp/properties/i18n-numeric-map.json',
106
- numericFilenameTemplate: 'i18n-chunk/[locale]/numeric.i18n.js',
107
- dynamicFilenameTemplate: 'i18n-chunk/[locale]/dynamic.i18n.js',
108
- jsonpFunc: 'window.loadI18nChunk',
109
- htmlTemplateLabel: '{{--user-locale}}',
110
- localeVarName: 'window.userLangCode',
111
- singleFile: false,
112
- includeContentHash: false,
113
- generateManifest: false,
114
- manifestPath: null
99
+ publicFolders: {
100
+ dev: ['...'],
101
+ prod: ['...']
115
102
  },
116
- publicFolders: ['...', {
117
- source: './deskapp/tp/',
118
- target: './tp/'
119
- }],
120
103
  app: {
121
104
  entryFile: 'src/index.js',
122
105
  tpFolder: null,
@@ -19,7 +19,8 @@ const babelPluginOrder = ['removeAttribute', 'removePropTypes', 'devConsoleExclu
19
19
  function getBabelPlugin(options) {
20
20
  const {
21
21
  mode
22
- } = options;
22
+ } = options; // let customPlugins = [];
23
+
23
24
  let customPlugins = [];
24
25
  const {
25
26
  babelCustomizations
@@ -32,6 +33,4 @@ function getBabelPlugin(options) {
32
33
  }
33
34
 
34
35
  return customPlugins.filter(Boolean);
35
- }
36
-
37
- ;
36
+ }
@@ -25,6 +25,6 @@ function runBabelForTSFile({
25
25
  // const jsSourceCode = readFileSync(filename).toString();
26
26
  const babelConfig = (0, _babelWebConfig.babelWebConfig)(options, mode);
27
27
  const result = (0, _core.transformFileSync)(filename, babelConfig);
28
- (0, _copyFile.writeFile)(outputFile.replace('.tsx', '.js'), result.code);
28
+ (0, _copyFile.writeFile)(outputFile.replace('.tsx', '.js').replace('.ts', '.js'), result.code);
29
29
  }
30
30
  }
@@ -30,6 +30,16 @@ class BundleIntegrityReport {
30
30
 
31
31
  apply(compiler) {
32
32
  compiler.hooks.done.tapAsync(pluginName, (stats, callback) => {
33
+ if (stats.hasErrors()) {
34
+ console.error(stats.toString({
35
+ all: false,
36
+ errors: true,
37
+ errorDetails: true,
38
+ colors: true
39
+ }));
40
+ return callback(new Error('Build failed due to compilation errors.'));
41
+ }
42
+
33
43
  const statsJson = (0, _objectManipulation.removeKeysFromObject)(stats.toJson(this.statsOptions), this.excludeKeysInStat);
34
44
  this.emitStats(statsJson).on('end', () => {
35
45
  callback();
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.I18nGroupRuntimeModule = void 0;
7
+
8
+ var _webpack = require("webpack");
9
+
10
+ class I18nGroupRuntimeModule extends _webpack.RuntimeModule {
11
+ constructor(options) {
12
+ super('i18n-group-loader');
13
+ this.options = options;
14
+ }
15
+
16
+ generate() {
17
+ const {
18
+ customGroups,
19
+ localeVarName,
20
+ jsonpFunc
21
+ } = this.options; // Build chunk-to-group mapping from config
22
+
23
+ const chunkToGroup = {};
24
+ Object.entries(customGroups || {}).forEach(([groupName, config]) => {
25
+ (config.chunks || []).forEach(chunkName => {
26
+ chunkToGroup[chunkName] = groupName;
27
+ });
28
+ });
29
+ return `
30
+ // I18n Group Loading Runtime
31
+ (function() {
32
+ var loadedGroups = {};
33
+ var chunkToGroup = ${JSON.stringify(chunkToGroup)};
34
+
35
+ // Store original webpack chunk loading function
36
+ var originalEnsureChunk = __webpack_require__.e;
37
+
38
+ // Override webpack's chunk loading
39
+ __webpack_require__.e = function(chunkId) {
40
+ var promise = originalEnsureChunk.apply(this, arguments);
41
+
42
+ // Check if this chunk needs an i18n group
43
+ var groupName = chunkToGroup[chunkId];
44
+ if (groupName && !loadedGroups[groupName]) {
45
+ // Load the i18n group
46
+ var locale = ${localeVarName} || 'en_US';
47
+ var groupConfig = ${JSON.stringify(customGroups)};
48
+ var config = groupConfig[groupName];
49
+
50
+ if (config) {
51
+ var i18nUrl = config.filenameTemplate
52
+ .replace('[locale]', locale)
53
+ .replace('i18n-chunk/', __webpack_require__.p + 'i18n-chunk/');
54
+
55
+ // Create script tag to load i18n chunk
56
+ var script = document.createElement('script');
57
+ script.src = i18nUrl;
58
+ script.async = true;
59
+
60
+ // Mark as loaded when script loads
61
+ script.onload = function() {
62
+ loadedGroups[groupName] = true;
63
+ };
64
+
65
+ document.head.appendChild(script);
66
+
67
+ // If prefetch is enabled, prefetch other locales
68
+ if (config.prefetch && !config.preload) {
69
+ var link = document.createElement('link');
70
+ link.rel = 'prefetch';
71
+ link.href = i18nUrl;
72
+ document.head.appendChild(link);
73
+ }
74
+ }
75
+ }
76
+
77
+ return promise;
78
+ };
79
+
80
+ // Also check for webpackI18nGroup comments in dynamic imports
81
+ if (typeof __webpack_require__.l !== 'undefined') {
82
+ var originalLoadScript = __webpack_require__.l;
83
+ __webpack_require__.l = function(url, done, key, chunkId) {
84
+ // Check if chunk has i18n group
85
+ var groupName = chunkToGroup[chunkId];
86
+ if (groupName && !loadedGroups[groupName]) {
87
+ // Load i18n before main chunk
88
+ var locale = ${localeVarName} || 'en_US';
89
+ var groupConfig = ${JSON.stringify(customGroups)};
90
+ var config = groupConfig[groupName];
91
+
92
+ if (config) {
93
+ var i18nUrl = config.filenameTemplate
94
+ .replace('[locale]', locale)
95
+ .replace('i18n-chunk/', __webpack_require__.p + 'i18n-chunk/');
96
+
97
+ // Load i18n first, then the chunk
98
+ var i18nScript = document.createElement('script');
99
+ i18nScript.src = i18nUrl;
100
+ i18nScript.onload = function() {
101
+ loadedGroups[groupName] = true;
102
+ // Now load the original chunk
103
+ originalLoadScript.call(__webpack_require__, url, done, key, chunkId);
104
+ };
105
+ i18nScript.onerror = function() {
106
+ // Continue even if i18n fails
107
+ originalLoadScript.call(__webpack_require__, url, done, key, chunkId);
108
+ };
109
+ document.head.appendChild(i18nScript);
110
+ return;
111
+ }
112
+ }
113
+
114
+ // Default behavior
115
+ return originalLoadScript.call(__webpack_require__, url, done, key, chunkId);
116
+ };
117
+ }
118
+ })();
119
+ `;
120
+ }
121
+
122
+ }
123
+
124
+ exports.I18nGroupRuntimeModule = I18nGroupRuntimeModule;