@nx/webpack 0.0.0-pr-22179-271588f

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 (146) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +68 -0
  3. package/executors.json +19 -0
  4. package/generators.json +20 -0
  5. package/index.d.ts +18 -0
  6. package/index.js +24 -0
  7. package/migrations.json +60 -0
  8. package/package.json +74 -0
  9. package/plugin.d.ts +1 -0
  10. package/plugin.js +5 -0
  11. package/src/executors/dev-server/dev-server.impl.d.ts +7 -0
  12. package/src/executors/dev-server/dev-server.impl.js +79 -0
  13. package/src/executors/dev-server/lib/get-dev-server-config.d.ts +4 -0
  14. package/src/executors/dev-server/lib/get-dev-server-config.js +79 -0
  15. package/src/executors/dev-server/lib/serve-path.d.ts +3 -0
  16. package/src/executors/dev-server/lib/serve-path.js +45 -0
  17. package/src/executors/dev-server/schema.d.ts +17 -0
  18. package/src/executors/dev-server/schema.json +76 -0
  19. package/src/executors/ssr-dev-server/lib/wait-until-server-is-listening.d.ts +1 -0
  20. package/src/executors/ssr-dev-server/lib/wait-until-server-is-listening.js +39 -0
  21. package/src/executors/ssr-dev-server/schema.d.ts +11 -0
  22. package/src/executors/ssr-dev-server/schema.json +37 -0
  23. package/src/executors/ssr-dev-server/ssr-dev-server.impl.d.ts +8 -0
  24. package/src/executors/ssr-dev-server/ssr-dev-server.impl.js +39 -0
  25. package/src/executors/webpack/lib/normalize-options.d.ts +3 -0
  26. package/src/executors/webpack/lib/normalize-options.js +40 -0
  27. package/src/executors/webpack/lib/run-webpack.d.ts +3 -0
  28. package/src/executors/webpack/lib/run-webpack.js +36 -0
  29. package/src/executors/webpack/schema.d.ts +96 -0
  30. package/src/executors/webpack/schema.json +394 -0
  31. package/src/executors/webpack/webpack.impl.d.ts +13 -0
  32. package/src/executors/webpack/webpack.impl.js +125 -0
  33. package/src/generators/configuration/configuration.d.ts +5 -0
  34. package/src/generators/configuration/configuration.js +194 -0
  35. package/src/generators/configuration/schema.d.ts +14 -0
  36. package/src/generators/configuration/schema.json +77 -0
  37. package/src/generators/init/init.d.ts +5 -0
  38. package/src/generators/init/init.js +60 -0
  39. package/src/generators/init/schema.d.ts +7 -0
  40. package/src/generators/init/schema.json +33 -0
  41. package/src/migrations/update-15-0-0/add-babel-inputs.d.ts +2 -0
  42. package/src/migrations/update-15-0-0/add-babel-inputs.js +9 -0
  43. package/src/migrations/update-15-4-5/remove-es2015-polyfills-option.d.ts +2 -0
  44. package/src/migrations/update-15-4-5/remove-es2015-polyfills-option.js +20 -0
  45. package/src/migrations/update-15-6-3/webpack-config-setup.d.ts +2 -0
  46. package/src/migrations/update-15-6-3/webpack-config-setup.js +100 -0
  47. package/src/migrations/update-15-7-2/add-babelUpwardRootMode-flag.d.ts +2 -0
  48. package/src/migrations/update-15-7-2/add-babelUpwardRootMode-flag.js +17 -0
  49. package/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.d.ts +2 -0
  50. package/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.js +9 -0
  51. package/src/migrations/update-17-2-1/webpack-config-setup.d.ts +2 -0
  52. package/src/migrations/update-17-2-1/webpack-config-setup.js +31 -0
  53. package/src/plugins/generate-package-json-plugin.d.ts +14 -0
  54. package/src/plugins/generate-package-json-plugin.js +44 -0
  55. package/src/plugins/nx-typescript-webpack-plugin/nx-tsconfig-paths-webpack-plugin.d.ts +8 -0
  56. package/src/plugins/nx-typescript-webpack-plugin/nx-tsconfig-paths-webpack-plugin.js +31 -0
  57. package/src/plugins/nx-webpack-plugin/lib/apply-base-config.d.ts +5 -0
  58. package/src/plugins/nx-webpack-plugin/lib/apply-base-config.js +318 -0
  59. package/src/plugins/nx-webpack-plugin/lib/apply-web-config.d.ts +5 -0
  60. package/src/plugins/nx-webpack-plugin/lib/apply-web-config.js +372 -0
  61. package/src/plugins/nx-webpack-plugin/lib/compiler-loaders.d.ts +53 -0
  62. package/src/plugins/nx-webpack-plugin/lib/compiler-loaders.js +78 -0
  63. package/src/plugins/nx-webpack-plugin/lib/get-terser-ecma-version.d.ts +1 -0
  64. package/src/plugins/nx-webpack-plugin/lib/get-terser-ecma-version.js +35 -0
  65. package/src/plugins/nx-webpack-plugin/lib/instantiate-script-plugins.d.ts +3 -0
  66. package/src/plugins/nx-webpack-plugin/lib/instantiate-script-plugins.js +42 -0
  67. package/src/plugins/nx-webpack-plugin/lib/normalize-options.d.ts +4 -0
  68. package/src/plugins/nx-webpack-plugin/lib/normalize-options.js +143 -0
  69. package/src/plugins/nx-webpack-plugin/lib/stylesheet-loaders.d.ts +73 -0
  70. package/src/plugins/nx-webpack-plugin/lib/stylesheet-loaders.js +117 -0
  71. package/src/plugins/nx-webpack-plugin/nx-webpack-plugin-options.d.ts +216 -0
  72. package/src/plugins/nx-webpack-plugin/nx-webpack-plugin-options.js +2 -0
  73. package/src/plugins/nx-webpack-plugin/nx-webpack-plugin.d.ts +17 -0
  74. package/src/plugins/nx-webpack-plugin/nx-webpack-plugin.js +48 -0
  75. package/src/plugins/plugin.d.ts +9 -0
  76. package/src/plugins/plugin.js +131 -0
  77. package/src/plugins/stats-json-plugin.d.ts +4 -0
  78. package/src/plugins/stats-json-plugin.js +13 -0
  79. package/src/plugins/webpack-nx-build-coordination-plugin.d.ts +11 -0
  80. package/src/plugins/webpack-nx-build-coordination-plugin.js +85 -0
  81. package/src/plugins/write-index-html-plugin.d.ts +22 -0
  82. package/src/plugins/write-index-html-plugin.js +249 -0
  83. package/src/utils/config.d.ts +22 -0
  84. package/src/utils/config.js +66 -0
  85. package/src/utils/create-copy-plugin.d.ts +3 -0
  86. package/src/utils/create-copy-plugin.js +26 -0
  87. package/src/utils/ensure-dependencies.d.ts +6 -0
  88. package/src/utils/ensure-dependencies.js +28 -0
  89. package/src/utils/fs.d.ts +6 -0
  90. package/src/utils/fs.js +58 -0
  91. package/src/utils/get-client-environment.d.ts +5 -0
  92. package/src/utils/get-client-environment.js +29 -0
  93. package/src/utils/get-css-module-local-ident.d.ts +1 -0
  94. package/src/utils/get-css-module-local-ident.js +18 -0
  95. package/src/utils/has-plugin.d.ts +2 -0
  96. package/src/utils/has-plugin.js +11 -0
  97. package/src/utils/hash-format.d.ts +7 -0
  98. package/src/utils/hash-format.js +23 -0
  99. package/src/utils/models.d.ts +23 -0
  100. package/src/utils/models.js +2 -0
  101. package/src/utils/module-federation/dependencies.d.ts +6 -0
  102. package/src/utils/module-federation/dependencies.js +57 -0
  103. package/src/utils/module-federation/get-remotes-for-host.d.ts +14 -0
  104. package/src/utils/module-federation/get-remotes-for-host.js +88 -0
  105. package/src/utils/module-federation/index.d.ts +6 -0
  106. package/src/utils/module-federation/index.js +9 -0
  107. package/src/utils/module-federation/models/index.d.ts +39 -0
  108. package/src/utils/module-federation/models/index.js +2 -0
  109. package/src/utils/module-federation/package-json.d.ts +8 -0
  110. package/src/utils/module-federation/package-json.js +13 -0
  111. package/src/utils/module-federation/public-api.d.ts +6 -0
  112. package/src/utils/module-federation/public-api.js +16 -0
  113. package/src/utils/module-federation/remotes.d.ts +19 -0
  114. package/src/utils/module-federation/remotes.js +80 -0
  115. package/src/utils/module-federation/secondary-entry-points.d.ts +12 -0
  116. package/src/utils/module-federation/secondary-entry-points.js +108 -0
  117. package/src/utils/module-federation/share.d.ts +48 -0
  118. package/src/utils/module-federation/share.js +215 -0
  119. package/src/utils/module-federation/typescript.d.ts +4 -0
  120. package/src/utils/module-federation/typescript.js +54 -0
  121. package/src/utils/run-webpack.d.ts +5 -0
  122. package/src/utils/run-webpack.js +31 -0
  123. package/src/utils/versions.d.ts +8 -0
  124. package/src/utils/versions.js +12 -0
  125. package/src/utils/web-babel-loader.d.ts +0 -0
  126. package/src/utils/web-babel-loader.js +17 -0
  127. package/src/utils/webpack/deprecated-stylus-loader.d.ts +1 -0
  128. package/src/utils/webpack/deprecated-stylus-loader.js +11 -0
  129. package/src/utils/webpack/interpolate-env-variables-to-index.d.ts +1 -0
  130. package/src/utils/webpack/interpolate-env-variables-to-index.js +30 -0
  131. package/src/utils/webpack/normalize-entry.d.ts +2 -0
  132. package/src/utils/webpack/normalize-entry.js +28 -0
  133. package/src/utils/webpack/package-chunk-sort.d.ts +5 -0
  134. package/src/utils/webpack/package-chunk-sort.js +29 -0
  135. package/src/utils/webpack/plugins/postcss-cli-resources.d.ts +13 -0
  136. package/src/utils/webpack/plugins/postcss-cli-resources.js +165 -0
  137. package/src/utils/webpack/plugins/scripts-webpack-plugin.d.ts +17 -0
  138. package/src/utils/webpack/plugins/scripts-webpack-plugin.js +119 -0
  139. package/src/utils/webpack/read-webpack-options.d.ts +10 -0
  140. package/src/utils/webpack/read-webpack-options.js +41 -0
  141. package/src/utils/webpack/resolve-user-defined-webpack-config.d.ts +3 -0
  142. package/src/utils/webpack/resolve-user-defined-webpack-config.js +39 -0
  143. package/src/utils/with-nx.d.ts +8 -0
  144. package/src/utils/with-nx.js +34 -0
  145. package/src/utils/with-web.d.ts +22 -0
  146. package/src/utils/with-web.js +26 -0
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNodes = exports.createDependencies = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const path_1 = require("path");
6
+ const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
7
+ const fs_1 = require("fs");
8
+ const read_webpack_options_1 = require("../utils/webpack/read-webpack-options");
9
+ const resolve_user_defined_webpack_config_1 = require("../utils/webpack/resolve-user-defined-webpack-config");
10
+ const js_1 = require("@nx/js");
11
+ const cache_directory_1 = require("nx/src/utils/cache-directory");
12
+ const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
13
+ const cachePath = (0, path_1.join)(cache_directory_1.projectGraphCacheDirectory, 'webpack.hash');
14
+ const targetsCache = (0, fs_1.existsSync)(cachePath) ? readTargetsCache() : {};
15
+ const calculatedTargets = {};
16
+ function readTargetsCache() {
17
+ return (0, devkit_1.readJsonFile)(cachePath);
18
+ }
19
+ function writeTargetsToCache(targets) {
20
+ (0, devkit_1.writeJsonFile)(cachePath, targets);
21
+ }
22
+ const createDependencies = () => {
23
+ writeTargetsToCache(calculatedTargets);
24
+ return [];
25
+ };
26
+ exports.createDependencies = createDependencies;
27
+ exports.createNodes = [
28
+ '**/webpack.config.{js,ts,mjs,cjs}',
29
+ async (configFilePath, options, context) => {
30
+ options ??= {};
31
+ options.buildTargetName ??= 'build';
32
+ options.serveTargetName ??= 'serve';
33
+ options.serveStaticTargetName ??= 'serve-static';
34
+ options.previewTargetName ??= 'preview';
35
+ const projectRoot = (0, path_1.dirname)(configFilePath);
36
+ // Do not create a project if package.json and project.json isn't there.
37
+ const siblingFiles = (0, fs_1.readdirSync)((0, path_1.join)(context.workspaceRoot, projectRoot));
38
+ if (!siblingFiles.includes('package.json') &&
39
+ !siblingFiles.includes('project.json')) {
40
+ return {};
41
+ }
42
+ const hash = (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, options, context, [
43
+ (0, js_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot)),
44
+ ]);
45
+ const targets = targetsCache[hash]
46
+ ? targetsCache[hash]
47
+ : await createWebpackTargets(configFilePath, projectRoot, options, context);
48
+ return {
49
+ projects: {
50
+ [projectRoot]: {
51
+ projectType: 'application',
52
+ targets,
53
+ },
54
+ },
55
+ };
56
+ },
57
+ ];
58
+ async function createWebpackTargets(configFilePath, projectRoot, options, context) {
59
+ const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
60
+ const webpackConfig = (0, resolve_user_defined_webpack_config_1.resolveUserDefinedWebpackConfig)((0, path_1.join)(context.workspaceRoot, configFilePath), (0, js_1.getRootTsConfigPath)(), true);
61
+ const webpackOptions = await (0, read_webpack_options_1.readWebpackOptions)(webpackConfig);
62
+ const outputPath = normalizeOutputPath(webpackOptions.output?.path, projectRoot);
63
+ const targets = {};
64
+ targets[options.buildTargetName] = {
65
+ command: `webpack-cli build`,
66
+ options: { cwd: projectRoot, args: ['--node-env=production'] },
67
+ cache: true,
68
+ dependsOn: [`^${options.buildTargetName}`],
69
+ inputs: 'production' in namedInputs
70
+ ? [
71
+ 'production',
72
+ '^production',
73
+ {
74
+ externalDependencies: ['webpack-cli'],
75
+ },
76
+ ]
77
+ : [
78
+ 'default',
79
+ '^default',
80
+ {
81
+ externalDependencies: ['webpack-cli'],
82
+ },
83
+ ],
84
+ outputs: [outputPath],
85
+ };
86
+ targets[options.serveTargetName] = {
87
+ command: `webpack-cli serve`,
88
+ options: {
89
+ cwd: projectRoot,
90
+ args: ['--node-env=development'],
91
+ },
92
+ };
93
+ targets[options.previewTargetName] = {
94
+ command: `webpack-cli serve`,
95
+ options: {
96
+ cwd: projectRoot,
97
+ args: ['--node-env=production'],
98
+ },
99
+ };
100
+ targets[options.serveStaticTargetName] = {
101
+ executor: '@nx/web:file-server',
102
+ options: {
103
+ buildTarget: options.buildTargetName,
104
+ },
105
+ };
106
+ return targets;
107
+ }
108
+ function normalizeOutputPath(outputPath, projectRoot) {
109
+ if (!outputPath) {
110
+ // If outputPath is undefined, use webpack's default `dist` directory.
111
+ if (projectRoot === '.') {
112
+ return `{projectRoot}/dist}`;
113
+ }
114
+ else {
115
+ return `{workspaceRoot}/dist/{projectRoot}`;
116
+ }
117
+ }
118
+ else {
119
+ if ((0, path_1.isAbsolute)(outputPath)) {
120
+ return `{workspaceRoot}/${(0, path_1.relative)(devkit_1.workspaceRoot, outputPath)}`;
121
+ }
122
+ else {
123
+ if (outputPath.startsWith('..')) {
124
+ return (0, path_1.join)('{workspaceRoot}', (0, path_1.join)(projectRoot, outputPath));
125
+ }
126
+ else {
127
+ return (0, path_1.join)('{projectRoot}', outputPath);
128
+ }
129
+ }
130
+ }
131
+ }
@@ -0,0 +1,4 @@
1
+ import { Compiler } from 'webpack';
2
+ export declare class StatsJsonPlugin {
3
+ apply(compiler: Compiler): void;
4
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StatsJsonPlugin = void 0;
4
+ const webpack_1 = require("webpack");
5
+ class StatsJsonPlugin {
6
+ apply(compiler) {
7
+ compiler.hooks.emit.tap('StatsJsonPlugin', (compilation) => {
8
+ const data = JSON.stringify(compilation.getStats().toJson('verbose'));
9
+ compilation.assets[`stats.json`] = new webpack_1.sources.RawSource(data);
10
+ });
11
+ }
12
+ }
13
+ exports.StatsJsonPlugin = StatsJsonPlugin;
@@ -0,0 +1,11 @@
1
+ import type { Compiler } from 'webpack';
2
+ export declare class WebpackNxBuildCoordinationPlugin {
3
+ private readonly buildCmd;
4
+ private currentlyRunning;
5
+ private buildCmdProcess;
6
+ constructor(buildCmd: string, skipInitialBuild?: boolean);
7
+ apply(compiler: Compiler): void;
8
+ startWatchingBuildableLibs(): Promise<void>;
9
+ buildChangedProjects(): Promise<void>;
10
+ private createFileWatcher;
11
+ }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebpackNxBuildCoordinationPlugin = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const client_1 = require("nx/src/daemon/client/client");
6
+ const watch_1 = require("nx/src/command-line/watch");
7
+ const output_1 = require("nx/src/utils/output");
8
+ class WebpackNxBuildCoordinationPlugin {
9
+ constructor(buildCmd, skipInitialBuild) {
10
+ this.buildCmd = buildCmd;
11
+ this.currentlyRunning = 'none';
12
+ this.buildCmdProcess = null;
13
+ if (!skipInitialBuild) {
14
+ this.buildChangedProjects();
15
+ }
16
+ this.startWatchingBuildableLibs();
17
+ }
18
+ apply(compiler) {
19
+ compiler.hooks.beforeCompile.tapPromise('IncrementalDevServerPlugin', async () => {
20
+ while (this.currentlyRunning === 'nx-build') {
21
+ await sleep(50);
22
+ }
23
+ this.currentlyRunning = 'webpack-build';
24
+ });
25
+ compiler.hooks.done.tapPromise('IncrementalDevServerPlugin', async () => {
26
+ this.currentlyRunning = 'none';
27
+ });
28
+ }
29
+ async startWatchingBuildableLibs() {
30
+ const unregisterFileWatcher = await this.createFileWatcher();
31
+ process.on('exit', () => {
32
+ unregisterFileWatcher();
33
+ });
34
+ }
35
+ async buildChangedProjects() {
36
+ while (this.currentlyRunning === 'webpack-build') {
37
+ await sleep(50);
38
+ }
39
+ this.currentlyRunning = 'nx-build';
40
+ try {
41
+ return await new Promise((res) => {
42
+ this.buildCmdProcess = (0, child_process_1.exec)(this.buildCmd);
43
+ this.buildCmdProcess.stdout.pipe(process.stdout);
44
+ this.buildCmdProcess.stderr.pipe(process.stderr);
45
+ this.buildCmdProcess.on('exit', () => {
46
+ res();
47
+ });
48
+ this.buildCmdProcess.on('error', () => {
49
+ res();
50
+ });
51
+ });
52
+ }
53
+ finally {
54
+ this.currentlyRunning = 'none';
55
+ this.buildCmdProcess = null;
56
+ }
57
+ }
58
+ createFileWatcher() {
59
+ const runner = new watch_1.BatchFunctionRunner(() => this.buildChangedProjects());
60
+ return client_1.daemonClient.registerFileWatcher({
61
+ watchProjects: 'all',
62
+ }, (err, { changedProjects, changedFiles }) => {
63
+ if (err === 'closed') {
64
+ output_1.output.error({
65
+ title: 'Watch connection closed',
66
+ bodyLines: [
67
+ 'The daemon has closed the connection to this watch process.',
68
+ 'Please restart your watch command.',
69
+ ],
70
+ });
71
+ process.exit(1);
72
+ }
73
+ if (this.buildCmdProcess) {
74
+ this.buildCmdProcess.kill(2);
75
+ this.buildCmdProcess = null;
76
+ }
77
+ // Queue a build
78
+ runner.enqueue(changedProjects, changedFiles);
79
+ });
80
+ }
81
+ }
82
+ exports.WebpackNxBuildCoordinationPlugin = WebpackNxBuildCoordinationPlugin;
83
+ function sleep(time) {
84
+ return new Promise((resolve) => setTimeout(resolve, time));
85
+ }
@@ -0,0 +1,22 @@
1
+ import { Compiler } from 'webpack';
2
+ import { ExtraEntryPoint } from '../utils/models';
3
+ export interface WriteIndexHtmlOptions {
4
+ indexPath: string;
5
+ outputPath: string;
6
+ baseHref?: string;
7
+ deployUrl?: string;
8
+ sri?: boolean;
9
+ scripts?: ExtraEntryPoint[];
10
+ styles?: ExtraEntryPoint[];
11
+ crossOrigin?: 'none' | 'anonymous' | 'use-credentials';
12
+ }
13
+ export declare class WriteIndexHtmlPlugin {
14
+ private readonly options;
15
+ constructor(options: WriteIndexHtmlOptions);
16
+ apply(compiler: Compiler): void;
17
+ private getEmittedFiles;
18
+ private stripBom;
19
+ private augmentIndexHtml;
20
+ private generateSriAttributes;
21
+ private filterAndMapBuildFiles;
22
+ }
@@ -0,0 +1,249 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WriteIndexHtmlPlugin = void 0;
4
+ const webpack = require("webpack");
5
+ const crypto_1 = require("crypto");
6
+ const fs_1 = require("fs");
7
+ const interpolate_env_variables_to_index_1 = require("../utils/webpack/interpolate-env-variables-to-index");
8
+ const package_chunk_sort_1 = require("../utils/webpack/package-chunk-sort");
9
+ const path_1 = require("path");
10
+ const parse5 = require('parse5');
11
+ class WriteIndexHtmlPlugin {
12
+ constructor(options) {
13
+ this.options = options;
14
+ }
15
+ apply(compiler) {
16
+ const { outputPath, indexPath, baseHref, deployUrl, sri = false, scripts = [], styles = [], crossOrigin, } = this.options;
17
+ compiler.hooks.thisCompilation.tap('WriteIndexHtmlPlugin', (compilation) => {
18
+ compilation.hooks.processAssets.tap({
19
+ name: 'WriteIndexHtmlPlugin',
20
+ // After minification and sourcemaps are done
21
+ stage: webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE,
22
+ }, () => {
23
+ const moduleFiles = this.getEmittedFiles(compilation);
24
+ const files = moduleFiles.filter((x) => x.extension === '.css');
25
+ let content = (0, fs_1.readFileSync)(indexPath).toString();
26
+ content = this.stripBom(content);
27
+ compilation.assets[outputPath] = this.augmentIndexHtml({
28
+ input: outputPath,
29
+ inputContent: (0, interpolate_env_variables_to_index_1.interpolateEnvironmentVariablesToIndex)(content, deployUrl),
30
+ baseHref,
31
+ deployUrl,
32
+ crossOrigin,
33
+ sri,
34
+ entrypoints: (0, package_chunk_sort_1.generateEntryPoints)({ scripts, styles }),
35
+ files: this.filterAndMapBuildFiles(files, ['.js', '.css']),
36
+ moduleFiles: this.filterAndMapBuildFiles(moduleFiles, ['.js']),
37
+ loadOutputFile: (filePath) => compilation.assets[filePath].source().toString(),
38
+ });
39
+ });
40
+ });
41
+ }
42
+ getEmittedFiles(compilation) {
43
+ const files = [];
44
+ // adds all chunks to the list of emitted files such as lazy loaded modules
45
+ for (const chunk of compilation.chunks) {
46
+ for (const file of chunk.files) {
47
+ files.push({
48
+ // The id is guaranteed to exist at this point in the compilation process
49
+ id: chunk.id.toString(),
50
+ name: chunk.name,
51
+ file,
52
+ extension: (0, path_1.extname)(file),
53
+ initial: chunk.isOnlyInitial(),
54
+ });
55
+ }
56
+ }
57
+ // other all files
58
+ for (const file of Object.keys(compilation.assets)) {
59
+ files.push({
60
+ file,
61
+ extension: (0, path_1.extname)(file),
62
+ initial: false,
63
+ asset: true,
64
+ });
65
+ }
66
+ // dedupe
67
+ return files.filter(({ file, name }, index) => files.findIndex((f) => f.file === file && (!name || name === f.name)) === index);
68
+ }
69
+ stripBom(data) {
70
+ return data.replace(/^\uFEFF/, '');
71
+ }
72
+ augmentIndexHtml(params) {
73
+ const { loadOutputFile, files, moduleFiles = [], entrypoints } = params;
74
+ let { crossOrigin = 'none' } = params;
75
+ if (params.sri && crossOrigin === 'none') {
76
+ crossOrigin = 'anonymous';
77
+ }
78
+ const stylesheets = new Set();
79
+ const scripts = new Set();
80
+ // Sort files in the order we want to insert them by entrypoint and dedupes duplicates
81
+ const mergedFiles = [...moduleFiles, ...files];
82
+ for (const entrypoint of entrypoints) {
83
+ for (const { extension, file, name } of mergedFiles) {
84
+ if (name !== entrypoint) {
85
+ continue;
86
+ }
87
+ switch (extension) {
88
+ case '.js':
89
+ scripts.add(file);
90
+ break;
91
+ case '.css':
92
+ stylesheets.add(file);
93
+ break;
94
+ }
95
+ }
96
+ }
97
+ // Find the head and body elements
98
+ const treeAdapter = parse5.treeAdapters.default;
99
+ const document = parse5.parse(params.inputContent, {
100
+ treeAdapter,
101
+ locationInfo: true,
102
+ });
103
+ let headElement;
104
+ let bodyElement;
105
+ for (const docChild of document.childNodes) {
106
+ if (docChild.tagName === 'html') {
107
+ for (const htmlChild of docChild.childNodes) {
108
+ if (htmlChild.tagName === 'head') {
109
+ headElement = htmlChild;
110
+ }
111
+ else if (htmlChild.tagName === 'body') {
112
+ bodyElement = htmlChild;
113
+ }
114
+ }
115
+ }
116
+ }
117
+ if (!headElement || !bodyElement) {
118
+ throw new Error('Missing head and/or body elements');
119
+ }
120
+ // Determine script insertion point
121
+ let scriptInsertionPoint;
122
+ if (bodyElement.__location && bodyElement.__location.endTag) {
123
+ scriptInsertionPoint = bodyElement.__location.endTag.startOffset;
124
+ }
125
+ else {
126
+ // Less accurate fallback
127
+ // parse5 4.x does not provide locations if malformed html is present
128
+ scriptInsertionPoint = params.inputContent.indexOf('</body>');
129
+ }
130
+ let styleInsertionPoint;
131
+ if (headElement.__location && headElement.__location.endTag) {
132
+ styleInsertionPoint = headElement.__location.endTag.startOffset;
133
+ }
134
+ else {
135
+ // Less accurate fallback
136
+ // parse5 4.x does not provide locations if malformed html is present
137
+ styleInsertionPoint = params.inputContent.indexOf('</head>');
138
+ }
139
+ // Inject into the html
140
+ const indexSource = new webpack.sources.ReplaceSource(new webpack.sources.RawSource(params.inputContent, false), params.input);
141
+ let scriptElements = '';
142
+ for (const script of scripts) {
143
+ const attrs = [
144
+ { name: 'src', value: (params.deployUrl || '') + script },
145
+ ];
146
+ if (crossOrigin !== 'none') {
147
+ attrs.push({ name: 'crossorigin', value: crossOrigin });
148
+ }
149
+ // We want to include nomodule or module when a file is not common amongs all
150
+ // such as runtime.js
151
+ const scriptPredictor = ({ file, }) => file === script;
152
+ if (!files.some(scriptPredictor)) {
153
+ // in some cases for differential loading file with the same name is avialable in both
154
+ // nomodule and module such as scripts.js
155
+ // we shall not add these attributes if that's the case
156
+ const isModuleType = moduleFiles.some(scriptPredictor);
157
+ if (isModuleType) {
158
+ attrs.push({ name: 'type', value: 'module' });
159
+ }
160
+ else {
161
+ attrs.push({ name: 'defer', value: null });
162
+ }
163
+ }
164
+ else {
165
+ attrs.push({ name: 'type', value: 'module' });
166
+ }
167
+ if (params.sri) {
168
+ const content = loadOutputFile(script);
169
+ attrs.push(...this.generateSriAttributes(content));
170
+ }
171
+ const attributes = attrs
172
+ .map((attr) => attr.value === null ? attr.name : `${attr.name}="${attr.value}"`)
173
+ .join(' ');
174
+ scriptElements += `<script ${attributes}></script>`;
175
+ }
176
+ indexSource.insert(scriptInsertionPoint, scriptElements);
177
+ // Adjust base href if specified
178
+ if (typeof params.baseHref == 'string') {
179
+ let baseElement;
180
+ for (const headChild of headElement.childNodes) {
181
+ if (headChild.tagName === 'base') {
182
+ baseElement = headChild;
183
+ }
184
+ }
185
+ const baseFragment = treeAdapter.createDocumentFragment();
186
+ if (!baseElement) {
187
+ baseElement = treeAdapter.createElement('base', undefined, [
188
+ { name: 'href', value: params.baseHref },
189
+ ]);
190
+ treeAdapter.appendChild(baseFragment, baseElement);
191
+ indexSource.insert(headElement.__location.startTag.endOffset, parse5.serialize(baseFragment, { treeAdapter }));
192
+ }
193
+ else {
194
+ let hrefAttribute;
195
+ for (const attribute of baseElement.attrs) {
196
+ if (attribute.name === 'href') {
197
+ hrefAttribute = attribute;
198
+ }
199
+ }
200
+ if (hrefAttribute) {
201
+ hrefAttribute.value = params.baseHref;
202
+ }
203
+ else {
204
+ baseElement.attrs.push({ name: 'href', value: params.baseHref });
205
+ }
206
+ treeAdapter.appendChild(baseFragment, baseElement);
207
+ indexSource.replace(baseElement.__location.startOffset, baseElement.__location.endOffset, parse5.serialize(baseFragment, { treeAdapter }));
208
+ }
209
+ }
210
+ const styleElements = treeAdapter.createDocumentFragment();
211
+ for (const stylesheet of stylesheets) {
212
+ const attrs = [
213
+ { name: 'rel', value: 'stylesheet' },
214
+ { name: 'href', value: (params.deployUrl || '') + stylesheet },
215
+ ];
216
+ if (crossOrigin !== 'none') {
217
+ attrs.push({ name: 'crossorigin', value: crossOrigin });
218
+ }
219
+ if (params.sri) {
220
+ const content = loadOutputFile(stylesheet);
221
+ attrs.push(...this.generateSriAttributes(content));
222
+ }
223
+ const element = treeAdapter.createElement('link', undefined, attrs);
224
+ treeAdapter.appendChild(styleElements, element);
225
+ }
226
+ indexSource.insert(styleInsertionPoint, parse5.serialize(styleElements, { treeAdapter }));
227
+ return indexSource;
228
+ }
229
+ generateSriAttributes(content) {
230
+ const algo = 'sha384';
231
+ const hash = (0, crypto_1.createHash)(algo).update(content, 'utf8').digest('base64');
232
+ return [{ name: 'integrity', value: `${algo}-${hash}` }];
233
+ }
234
+ filterAndMapBuildFiles(files, extensionFilter) {
235
+ const filteredFiles = [];
236
+ // This test excludes files generated by HMR (e.g. main.hot-update.js).
237
+ const hotUpdateAsset = /hot-update\.[cm]?js$/;
238
+ for (const { file, name, extension, initial } of files) {
239
+ if (name &&
240
+ initial &&
241
+ extensionFilter.includes(extension) &&
242
+ !hotUpdateAsset.test(file)) {
243
+ filteredFiles.push({ file, extension, name });
244
+ }
245
+ }
246
+ return filteredFiles;
247
+ }
248
+ }
249
+ exports.WriteIndexHtmlPlugin = WriteIndexHtmlPlugin;
@@ -0,0 +1,22 @@
1
+ import { ExecutorContext } from '@nx/devkit';
2
+ import { Configuration } from 'webpack';
3
+ import { NormalizedWebpackExecutorOptions } from '../executors/webpack/schema';
4
+ export declare const nxWebpackComposablePlugin = "nxWebpackComposablePlugin";
5
+ export declare function isNxWebpackComposablePlugin(a: unknown): a is AsyncNxComposableWebpackPlugin;
6
+ export interface NxWebpackExecutionContext {
7
+ options: NormalizedWebpackExecutorOptions;
8
+ context: ExecutorContext;
9
+ configuration?: string;
10
+ }
11
+ export interface NxComposableWebpackPlugin {
12
+ (config: Configuration, ctx: NxWebpackExecutionContext): Configuration;
13
+ }
14
+ export interface AsyncNxComposableWebpackPlugin {
15
+ (config: Configuration, ctx: NxWebpackExecutionContext): Configuration | Promise<Configuration>;
16
+ }
17
+ export declare function composePlugins(...plugins: (NxComposableWebpackPlugin | AsyncNxComposableWebpackPlugin | Promise<NxComposableWebpackPlugin | AsyncNxComposableWebpackPlugin>)[]): ((config: Configuration, ctx: NxWebpackExecutionContext) => Promise<Configuration>) & {
18
+ nxWebpackComposablePlugin: boolean;
19
+ };
20
+ export declare function composePluginsSync(...plugins: NxComposableWebpackPlugin[]): ((config: Configuration, ctx: NxWebpackExecutionContext) => Configuration) & {
21
+ nxWebpackComposablePlugin: boolean;
22
+ };
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.composePluginsSync = exports.composePlugins = exports.isNxWebpackComposablePlugin = exports.nxWebpackComposablePlugin = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ exports.nxWebpackComposablePlugin = 'nxWebpackComposablePlugin';
6
+ function isNxWebpackComposablePlugin(a) {
7
+ return a?.[exports.nxWebpackComposablePlugin] === true;
8
+ }
9
+ exports.isNxWebpackComposablePlugin = isNxWebpackComposablePlugin;
10
+ function composePlugins(...plugins) {
11
+ return Object.assign(async function combined(config, ctx) {
12
+ // Webpack may be calling us as a standard config function.
13
+ // Build up Nx context from environment variables.
14
+ // This is to enable `@nx/webpack/plugin` to work with existing projects.
15
+ if (ctx['env']) {
16
+ ensureNxWebpackExecutionContext(ctx);
17
+ // Build this from scratch since what webpack passes us is the env, not config,
18
+ // and `withNX()` creates a new config object anyway.
19
+ config = {};
20
+ }
21
+ for (const plugin of plugins) {
22
+ const fn = await plugin;
23
+ config = await fn(config, ctx);
24
+ }
25
+ return config;
26
+ }, {
27
+ [exports.nxWebpackComposablePlugin]: true,
28
+ });
29
+ }
30
+ exports.composePlugins = composePlugins;
31
+ function composePluginsSync(...plugins) {
32
+ return Object.assign(function combined(config, ctx) {
33
+ for (const plugin of plugins) {
34
+ config = plugin(config, ctx);
35
+ }
36
+ return config;
37
+ }, {
38
+ [exports.nxWebpackComposablePlugin]: true,
39
+ });
40
+ }
41
+ exports.composePluginsSync = composePluginsSync;
42
+ function ensureNxWebpackExecutionContext(ctx) {
43
+ const projectName = process.env.NX_TASK_TARGET_PROJECT;
44
+ const targetName = process.env.NX_TASK_TARGET_TARGET;
45
+ const configurationName = process.env.NX_TASK_TARGET_CONFIGURATION;
46
+ const projectGraph = (0, devkit_1.readCachedProjectGraph)();
47
+ const projectNode = projectGraph.nodes[projectName];
48
+ ctx.options ??= {
49
+ root: devkit_1.workspaceRoot,
50
+ projectRoot: projectNode.data.root,
51
+ sourceRoot: projectNode.data.sourceRoot ?? projectNode.data.root,
52
+ // These aren't actually needed since NxWebpackPlugin and withNx both support them being undefined.
53
+ assets: undefined,
54
+ outputPath: undefined,
55
+ tsConfig: undefined,
56
+ outputFileName: undefined,
57
+ };
58
+ ctx.context ??= {
59
+ projectName,
60
+ targetName,
61
+ configurationName,
62
+ cwd: process.cwd(),
63
+ root: devkit_1.workspaceRoot,
64
+ isVerbose: process.env['NX_VERBOSE_LOGGING'] === 'true',
65
+ };
66
+ }
@@ -0,0 +1,3 @@
1
+ import * as CopyWebpackPlugin from 'copy-webpack-plugin';
2
+ import { AssetGlobPattern } from '../executors/webpack/schema';
3
+ export declare function createCopyPlugin(assets: AssetGlobPattern[]): CopyWebpackPlugin;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCopyPlugin = void 0;
4
+ const CopyWebpackPlugin = require("copy-webpack-plugin");
5
+ function createCopyPlugin(assets) {
6
+ return new CopyWebpackPlugin({
7
+ patterns: assets.map((asset) => {
8
+ return {
9
+ context: asset.input,
10
+ // Now we remove starting slash to make Webpack place it from the output root.
11
+ to: asset.output,
12
+ from: asset.glob,
13
+ globOptions: {
14
+ ignore: [
15
+ '.gitkeep',
16
+ '**/.DS_Store',
17
+ '**/Thumbs.db',
18
+ ...(asset.ignore ?? []),
19
+ ],
20
+ dot: true,
21
+ },
22
+ };
23
+ }),
24
+ });
25
+ }
26
+ exports.createCopyPlugin = createCopyPlugin;
@@ -0,0 +1,6 @@
1
+ import { type GeneratorCallback, type Tree } from '@nx/devkit';
2
+ export type EnsureDependenciesOptions = {
3
+ compiler?: 'swc' | 'tsc';
4
+ uiFramework?: 'none' | 'react';
5
+ };
6
+ export declare function ensureDependencies(tree: Tree, options: EnsureDependenciesOptions): GeneratorCallback;