@zohodesk/client_build_tool 0.0.13 → 0.0.14-exp.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +10 -0
- package/lib/schemas/defaultConfigValues.js +13 -0
- package/lib/shared/bundler/webpack/custom_plugins/BundleIntegrityReport/ChunkHierarchyPlugin.js +52 -0
- package/lib/shared/bundler/webpack/custom_plugins/ChunkHierarchyPlugin.js +64 -0
- package/lib/shared/bundler/webpack/custom_plugins/InitialHtmlPlugin.js +40 -2
- package/lib/shared/bundler/webpack/pluginConfigs/ChunkHierarchyPlugin.js +15 -0
- package/lib/shared/bundler/webpack/pluginConfigs/config +0 -0
- package/lib/shared/bundler/webpack/pluginConfigs/configChunkHierarchyPlugin.js +19 -0
- package/lib/shared/bundler/webpack/pluginConfigs/configHtmlWebpackPlugin.js +4 -2
- package/lib/shared/bundler/webpack/plugins.js +3 -1
- package/lib/shared/bundler/webpack/tsLoaders.js +3 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog and Release Notes
|
|
2
2
|
|
|
3
|
+
# v0.0.14 (06-10-2025)
|
|
4
|
+
|
|
5
|
+
**Feature:-**
|
|
6
|
+
- Added integrity and crossorigin attributes for all the js and css files in index.html
|
|
7
|
+
|
|
8
|
+
```enableSubResourceIntegrity: true
|
|
9
|
+
```
|
|
10
|
+
**Adjustments:-**
|
|
11
|
+
- add ts-loader to parse tsx and ts files
|
|
12
|
+
|
|
3
13
|
# v0.0.13 (02-09-2025)
|
|
4
14
|
|
|
5
15
|
**Adjustments:-**
|
package/README.md
CHANGED
|
@@ -306,6 +306,16 @@ First Release
|
|
|
306
306
|
- 'templates' command to create es for react library
|
|
307
307
|
# Changelog and Release Notes
|
|
308
308
|
|
|
309
|
+
# v0.0.14 (06-10-2025)
|
|
310
|
+
|
|
311
|
+
**Feature:-**
|
|
312
|
+
- Added integrity and crossorigin attributes for all the js and css files in index.html
|
|
313
|
+
|
|
314
|
+
```enableSubResourceIntegrity: true
|
|
315
|
+
```
|
|
316
|
+
**Adjustments:-**
|
|
317
|
+
- add ts-loader to parse tsx and ts files
|
|
318
|
+
|
|
309
319
|
# v0.0.13 (02-09-2025)
|
|
310
320
|
|
|
311
321
|
**Adjustments:-**
|
|
@@ -7,6 +7,8 @@ exports.default = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _os = require("os");
|
|
9
9
|
|
|
10
|
+
var _webpack = require("webpack");
|
|
11
|
+
|
|
10
12
|
// NOTE: Don't use 'config_file' as cli option it was reserved
|
|
11
13
|
var _default = {
|
|
12
14
|
context: {
|
|
@@ -355,6 +357,17 @@ var _default = {
|
|
|
355
357
|
enable: false,
|
|
356
358
|
chunkName: '',
|
|
357
359
|
filePath: ''
|
|
360
|
+
},
|
|
361
|
+
enableSubResourceIntegrity: {
|
|
362
|
+
value: false,
|
|
363
|
+
cli: 'enable_sub_resource_integrity'
|
|
364
|
+
},
|
|
365
|
+
chunkGraph: {
|
|
366
|
+
enable: {
|
|
367
|
+
value: false,
|
|
368
|
+
cli: 'chunk_graph_enable'
|
|
369
|
+
},
|
|
370
|
+
fileName: ''
|
|
358
371
|
}
|
|
359
372
|
};
|
|
360
373
|
exports.default = _default;
|
package/lib/shared/bundler/webpack/custom_plugins/BundleIntegrityReport/ChunkHierarchyPlugin.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// plugins/ChunkHierarchyPlugin.js
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
|
|
6
|
+
const path = require("path");
|
|
7
|
+
|
|
8
|
+
class ChunkHierarchyPlugin {
|
|
9
|
+
apply(compiler) {
|
|
10
|
+
compiler.hooks.afterEmit.tap("ChunkHierarchyPlugin", compilation => {
|
|
11
|
+
try {
|
|
12
|
+
const {
|
|
13
|
+
chunkGraph,
|
|
14
|
+
moduleGraph
|
|
15
|
+
} = compilation;
|
|
16
|
+
const hierarchy = {};
|
|
17
|
+
|
|
18
|
+
for (const chunk of compilation.chunks) {
|
|
19
|
+
// skip unnamed or runtime chunks
|
|
20
|
+
if (!chunk.name) continue;
|
|
21
|
+
if (chunk.name.includes("runtime")) continue;
|
|
22
|
+
const modules = chunkGraph.getChunkModulesIterable(chunk);
|
|
23
|
+
const deps = new Set();
|
|
24
|
+
|
|
25
|
+
for (const module of modules) {
|
|
26
|
+
for (const conn of moduleGraph.getOutgoingConnections(module)) {
|
|
27
|
+
if (conn.module && conn.module.resource) {
|
|
28
|
+
deps.add(conn.module.resource);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
hierarchy[chunk.name] = Array.from(deps);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const outputPath = compiler.options.output.path;
|
|
37
|
+
const outputFile = path.join(outputPath, "chunk-hierarchy-report.json"); // Ensure folder exists before writing
|
|
38
|
+
|
|
39
|
+
fs.mkdirSync(outputPath, {
|
|
40
|
+
recursive: true
|
|
41
|
+
});
|
|
42
|
+
fs.writeFileSync(outputFile, JSON.stringify(hierarchy, null, 2), "utf-8");
|
|
43
|
+
console.log(`🧩 Chunk hierarchy report written to: ${outputFile}`);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
console.error("❌ ChunkHierarchyPlugin failed:", err);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = ChunkHierarchyPlugin;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// plugins/ChunkHierarchyPlugin.js
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
|
|
6
|
+
const path = require("path");
|
|
7
|
+
|
|
8
|
+
class ChunkHierarchyPlugin {
|
|
9
|
+
constructor(outputFileName) {
|
|
10
|
+
this.outputFileName = outputFileName || "chunk-hierarchy-report.json";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
apply(compiler) {
|
|
14
|
+
compiler.hooks.afterEmit.tap("ChunkHierarchyPlugin", compilation => {
|
|
15
|
+
try {
|
|
16
|
+
const {
|
|
17
|
+
chunkGraph,
|
|
18
|
+
moduleGraph
|
|
19
|
+
} = compilation;
|
|
20
|
+
const hierarchy = {};
|
|
21
|
+
|
|
22
|
+
for (const chunk of compilation.chunks) {
|
|
23
|
+
// skip unnamed or runtime chunks
|
|
24
|
+
if (!chunk.name) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
;
|
|
29
|
+
|
|
30
|
+
if (chunk.name.includes("runtime")) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
;
|
|
35
|
+
const modules = chunkGraph.getChunkModulesIterable(chunk);
|
|
36
|
+
const deps = new Set();
|
|
37
|
+
|
|
38
|
+
for (const module of modules) {
|
|
39
|
+
for (const conn of moduleGraph.getOutgoingConnections(module)) {
|
|
40
|
+
if (conn.module && conn.module.resource) {
|
|
41
|
+
deps.add(conn.module.resource);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
hierarchy[chunk.name] = Array.from(deps);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const outputPath = compiler.options.output.path;
|
|
50
|
+
const outputFile = path.join(outputPath, this.outputFileName); // Ensure folder exists before writing
|
|
51
|
+
|
|
52
|
+
fs.mkdirSync(outputPath, {
|
|
53
|
+
recursive: true
|
|
54
|
+
});
|
|
55
|
+
fs.writeFileSync(outputFile, JSON.stringify(hierarchy, null, 2), "utf-8");
|
|
56
|
+
} catch (err) {
|
|
57
|
+
console.error("❌ ChunkHierarchyPlugin failed:", err);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = ChunkHierarchyPlugin;
|
|
@@ -16,13 +16,28 @@ class InitialHtmlPlugin {
|
|
|
16
16
|
this.options = options;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
getBaseName(str) {
|
|
20
|
+
const fileName = str.split("/").pop();
|
|
21
|
+
const parts = fileName.split("."); // Find index of the hash-like segment
|
|
22
|
+
|
|
23
|
+
const hashIndex = parts.findIndex(p => /^[0-9a-f_]{20,}$/i.test(p)); // If a hash is found, return everything before it
|
|
24
|
+
|
|
25
|
+
if (hashIndex < 0) {
|
|
26
|
+
console.error('this initial file dont have a hash');
|
|
27
|
+
return parts.slice(0, -1).join(".");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return parts.slice(0, hashIndex).join("."); // Otherwise fallback: remove only ".js"
|
|
31
|
+
}
|
|
32
|
+
|
|
19
33
|
apply(compiler) {
|
|
20
34
|
const {
|
|
21
35
|
filename,
|
|
22
36
|
template,
|
|
23
37
|
minify,
|
|
24
38
|
inject,
|
|
25
|
-
mainChunkName
|
|
39
|
+
mainChunkName,
|
|
40
|
+
enableSubResourceIntegrity
|
|
26
41
|
} = this.options;
|
|
27
42
|
new _htmlWebpackPlugin.default({
|
|
28
43
|
filename,
|
|
@@ -37,13 +52,36 @@ class InitialHtmlPlugin {
|
|
|
37
52
|
const headTags = [];
|
|
38
53
|
const bodyTags = [];
|
|
39
54
|
data.headTags.forEach(tag => {
|
|
55
|
+
const url = tag.attributes?.src || tag.attributes?.href;
|
|
56
|
+
let chunkName;
|
|
57
|
+
|
|
58
|
+
const addIntegrity = (tag, suffix) => {
|
|
59
|
+
if (enableSubResourceIntegrity && chunkName) {
|
|
60
|
+
Object.assign(tag.attributes, {
|
|
61
|
+
integrity: `{{--${chunkName}-${suffix}-integrity}}`
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
if (enableSubResourceIntegrity) {
|
|
67
|
+
chunkName = this.getBaseName(url);
|
|
68
|
+
}
|
|
69
|
+
|
|
40
70
|
Object.assign(tag.attributes, {
|
|
41
|
-
nonce: '{{--CSP-nonce}}'
|
|
71
|
+
nonce: '{{--CSP-nonce}}',
|
|
72
|
+
crossorigin: "anonymous"
|
|
42
73
|
});
|
|
43
74
|
|
|
44
75
|
if (tag.tagName === 'link') {
|
|
76
|
+
addIntegrity(tag, 'css');
|
|
45
77
|
headTags.push(tag);
|
|
46
78
|
} else {
|
|
79
|
+
if (url.endsWith('.i18n.js')) {
|
|
80
|
+
addIntegrity(tag, 'i18n');
|
|
81
|
+
} else {
|
|
82
|
+
addIntegrity(tag, 'js');
|
|
83
|
+
}
|
|
84
|
+
|
|
47
85
|
bodyTags.push(tag);
|
|
48
86
|
}
|
|
49
87
|
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ChunkHierarchyPlugin = ChunkHierarchyPlugin;
|
|
7
|
+
|
|
8
|
+
var _webpackBundleAnalyzer = require("webpack-bundle-analyzer");
|
|
9
|
+
|
|
10
|
+
var _modeUtils = require("../common/modeUtils");
|
|
11
|
+
|
|
12
|
+
/* eslint-disable no-use-before-define */
|
|
13
|
+
function ChunkHierarchyPlugin(options) {
|
|
14
|
+
return new _webpackBundleAnalyzer.BundleAnalyzerPlugin(bundleAnalyzerOptions);
|
|
15
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.configChunkHierarchyPlugin = configChunkHierarchyPlugin;
|
|
7
|
+
|
|
8
|
+
var _ChunkHierarchyPlugin = _interopRequireDefault(require("../custom_plugins/ChunkHierarchyPlugin"));
|
|
9
|
+
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
|
|
12
|
+
/* eslint-disable no-use-before-define */
|
|
13
|
+
function configChunkHierarchyPlugin(options) {
|
|
14
|
+
if (options.chunkGraph.enable) {
|
|
15
|
+
return new _ChunkHierarchyPlugin.default(options.chunkGraph.fileName);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
@@ -16,7 +16,8 @@ var _InitialHtmlPlugin = require("../custom_plugins/InitialHtmlPlugin");
|
|
|
16
16
|
function configHtmlWebpackPlugin(options) {
|
|
17
17
|
const {
|
|
18
18
|
htmlTemplate,
|
|
19
|
-
mode
|
|
19
|
+
mode,
|
|
20
|
+
enableSubResourceIntegrity
|
|
20
21
|
} = options;
|
|
21
22
|
const {
|
|
22
23
|
inject,
|
|
@@ -31,7 +32,8 @@ function configHtmlWebpackPlugin(options) {
|
|
|
31
32
|
template: appInitialHTMLTemplatePath,
|
|
32
33
|
minify: minifyHtmlOptions,
|
|
33
34
|
inject,
|
|
34
|
-
scriptLoading: 'defer'
|
|
35
|
+
scriptLoading: 'defer',
|
|
36
|
+
enableSubResourceIntegrity
|
|
35
37
|
});
|
|
36
38
|
}
|
|
37
39
|
|
|
@@ -51,10 +51,12 @@ var _configMurphyInjectorPlugin = require("./pluginConfigs/configMurphyInjectorP
|
|
|
51
51
|
|
|
52
52
|
var _configCustomScriptLoadingStrategyPlugin = require("./pluginConfigs/configCustomScriptLoadingStrategyPlugin");
|
|
53
53
|
|
|
54
|
+
var _configChunkHierarchyPlugin = require("./pluginConfigs/configChunkHierarchyPlugin");
|
|
55
|
+
|
|
54
56
|
// import { IgnorePlugin } from 'webpack';
|
|
55
57
|
function plugins(options) {
|
|
56
58
|
const {
|
|
57
59
|
webpackPlugins
|
|
58
60
|
} = options;
|
|
59
|
-
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), ...webpackPlugins].filter(Boolean);
|
|
61
|
+
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, _configChunkHierarchyPlugin.configChunkHierarchyPlugin)(options), ...webpackPlugins].filter(Boolean);
|
|
60
62
|
}
|
|
@@ -8,10 +8,11 @@ exports.tsLoaders = tsLoaders;
|
|
|
8
8
|
var _babelLoaderConfig = require("./loaderConfigs/babelLoaderConfig");
|
|
9
9
|
|
|
10
10
|
function tsLoaders(options) {
|
|
11
|
+
console.log('testing');
|
|
11
12
|
return [{
|
|
12
|
-
test: /\.tsx
|
|
13
|
+
test: /\.tsx?$/,
|
|
13
14
|
exclude: /node_modules/,
|
|
14
|
-
use:
|
|
15
|
+
use: "ts-loader" // include: path.join(appPath, folder)
|
|
15
16
|
|
|
16
17
|
}];
|
|
17
18
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zohodesk/client_build_tool",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14-exp.2",
|
|
4
4
|
"description": "A CLI tool to build web applications and client libraries",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
|
-
"url": "https://zgit.
|
|
21
|
+
"url": "https://zgit.csecz.zohocorpin.com/zohodesk/react-cli.git"
|
|
22
22
|
},
|
|
23
23
|
"keywords": [
|
|
24
24
|
"buildtool",
|