@nx/webpack 23.2.0-pr.36527.2252709 → 23.2.0-pr.36866.449f6f3

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/README.md CHANGED
@@ -7,9 +7,9 @@
7
7
 
8
8
  <div style="text-align: center;">
9
9
 
10
- [![License](https://img.shields.io/npm/l/@nx/workspace.svg?style=flat-square)]()
10
+ [![License](https://img.shields.io/npm/l/@nx/workspace.svg?style=flat-square)](<>)
11
11
  [![NPM Version](https://badge.fury.io/js/nx.svg)](https://www.npmjs.com/package/nx)
12
- [![Semantic Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)]()
12
+ [![Semantic Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](<>)
13
13
  [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
14
14
  [![Join us on the Official Nx Discord Server](https://img.shields.io/discord/1143497901675401286?label=discord)](https://go.nx.dev/community)
15
15
  [![Nx Sandboxing](https://staging.nx.app/workspaces/62d013ea0852fe0a2df74438/sandbox-badge.svg)](https://nx.dev/docs/features/ci-features/sandboxing)
@@ -82,6 +82,7 @@ export interface WebpackExecutorOptions {
82
82
  crossOrigin?: 'none' | 'anonymous' | 'use-credentials';
83
83
  deployUrl?: string;
84
84
  extractCss?: boolean;
85
+ cssModuleHashFunction?: string;
85
86
  generateIndexHtml?: boolean;
86
87
  index?: string;
87
88
  postcssConfig?: string;
@@ -93,8 +94,7 @@ export interface WebpackExecutorOptions {
93
94
  rebaseRootRelative?: boolean;
94
95
  }
95
96
 
96
- export interface NormalizedWebpackExecutorOptions
97
- extends WebpackExecutorOptions {
97
+ export interface NormalizedWebpackExecutorOptions extends WebpackExecutorOptions {
98
98
  outputFileName: string;
99
99
  assets: AssetGlobPattern[];
100
100
  root: string;
@@ -265,6 +265,10 @@
265
265
  "type": "boolean",
266
266
  "description": "Extract CSS into a `.css` file."
267
267
  },
268
+ "cssModuleHashFunction": {
269
+ "type": "string",
270
+ "description": "Hash algorithm used to generate CSS module class names. Defaults to `md5`, which FIPS-restricted OpenSSL rejects. Changing it renames generated class names."
271
+ },
268
272
  "subresourceIntegrity": {
269
273
  "type": "boolean",
270
274
  "description": "Enables the use of subresource integrity validation."
@@ -55,16 +55,13 @@ class GeneratePackageJsonPlugin {
55
55
  ...packageJson.dependencies,
56
56
  ...runtimeDependencies,
57
57
  };
58
- compilation.emitAsset('package.json', new sources.RawSource((0, devkit_1.serializeJson)(packageJson)));
59
58
  const packageManager = (0, devkit_1.detectPackageManager)(this.options.root);
60
- if (packageManager === 'bun') {
61
- compilation
62
- .getLogger('GeneratePackageJsonPlugin')
63
- .warn('Bun lockfile generation is not supported. Only package.json will be generated.');
64
- }
65
- else {
66
- compilation.emitAsset((0, js_1.getLockFileName)(packageManager), new sources.RawSource((0, js_1.createLockFile)(packageJson, this.options.projectGraph, packageManager)));
67
- }
59
+ (0, js_1.generatePrunedDeployOutput)(packageJson, this.options.projectGraph, this.options.projectGraph.nodes[this.options.projectName].data.root, {
60
+ emit: (assetPath, content) => compilation.emitAsset(assetPath, new sources.RawSource(content)),
61
+ packageManager,
62
+ workspaceRoot: this.options.root,
63
+ });
64
+ compilation.emitAsset('package.json', new sources.RawSource((0, devkit_1.serializeJson)(packageJson)));
68
65
  });
69
66
  });
70
67
  }
@@ -24,6 +24,23 @@ const extensionAlias = {
24
24
  };
25
25
  const extensions = ['.ts', '.tsx', '.mjs', '.js', '.jsx'];
26
26
  const mainFields = ['module', 'main'];
27
+ /**
28
+ * `withNx` builds a raw config that webpack validates, and only the boolean is
29
+ * schema-valid before 5.110. `NxAppWebpackPlugin` instead mutates options that
30
+ * are already normalized, which 5.110 fills by setting `.javascript` on
31
+ * `minimize`, so a boolean throws there.
32
+ */
33
+ function setMinimizeValue(optimization, shouldMinify, configIsNormalized) {
34
+ if (!shouldMinify) {
35
+ optimization.minimize = false;
36
+ return;
37
+ }
38
+ if (configIsNormalized) {
39
+ optimization.minimize = {};
40
+ return;
41
+ }
42
+ optimization.minimize = true;
43
+ }
27
44
  function applyBaseConfig(options, config = {}, { useNormalizedEntry, } = {}) {
28
45
  // Defaults that was applied from executor schema previously.
29
46
  options.compiler ??= 'babel';
@@ -31,13 +48,13 @@ function applyBaseConfig(options, config = {}, { useNormalizedEntry, } = {}) {
31
48
  options.fileReplacements ??= [];
32
49
  options.memoryLimit ??= 2048;
33
50
  options.transformers ??= [];
34
- applyNxIndependentConfig(options, config);
51
+ applyNxIndependentConfig(options, config, !!useNormalizedEntry);
35
52
  // Some of the options only work during actual tasks, not when reading the webpack config during CreateNodes.
36
53
  if (global.NX_GRAPH_CREATION)
37
54
  return;
38
55
  applyNxDependentConfig(options, config, { useNormalizedEntry });
39
56
  }
40
- function applyNxIndependentConfig(options, config) {
57
+ function applyNxIndependentConfig(options, config, configIsNormalized) {
41
58
  const TerserPlugin = require('terser-webpack-plugin');
42
59
  const hashFormat = (0, hash_format_1.getOutputHashFormat)(options.outputHashing);
43
60
  config.context = path.join(options.root, options.projectRoot);
@@ -126,12 +143,12 @@ function applyNxIndependentConfig(options, config) {
126
143
  (x) => IGNORED_WEBPACK_WARNINGS.some((r) => typeof x === 'string' ? r.test(x) : r.test(x.message)),
127
144
  ...(config.ignoreWarnings ?? []),
128
145
  ];
146
+ const shouldMinify = typeof options.optimization === 'object'
147
+ ? !!options.optimization.scripts
148
+ : !!options.optimization;
129
149
  config.optimization = {
130
150
  ...config.optimization,
131
151
  sideEffects: true,
132
- minimize: typeof options.optimization === 'object'
133
- ? !!options.optimization.scripts
134
- : !!options.optimization,
135
152
  minimizer: [
136
153
  options.compiler !== 'swc'
137
154
  ? new TerserPlugin({
@@ -164,6 +181,7 @@ function applyNxIndependentConfig(options, config) {
164
181
  runtimeChunk: false,
165
182
  concatenateModules: true,
166
183
  };
184
+ setMinimizeValue(config.optimization, shouldMinify, configIsNormalized);
167
185
  config.stats = {
168
186
  hash: true,
169
187
  timings: false,
@@ -1,4 +1,3 @@
1
- import { getCSSModuleLocalIdent } from '../../../utils/get-css-module-local-ident';
2
1
  import { NormalizedNxAppWebpackPluginOptions } from '../nx-app-webpack-plugin-options';
3
2
  interface PostcssOptions {
4
3
  (loader: any): any;
@@ -12,7 +11,7 @@ export declare function getCommonLoadersForCssModules(options: NormalizedNxAppWe
12
11
  options: {
13
12
  modules: {
14
13
  mode: string;
15
- getLocalIdent: typeof getCSSModuleLocalIdent;
14
+ getLocalIdent: (ctx: any, localIdentName: any, localName: any, loaderOptions: any) => any;
16
15
  namedExport: boolean;
17
16
  exportLocalsConvention: string;
18
17
  };
@@ -24,7 +24,7 @@ function getCommonLoadersForCssModules(options, includePaths) {
24
24
  options: {
25
25
  modules: {
26
26
  mode: 'local',
27
- getLocalIdent: get_css_module_local_ident_1.getCSSModuleLocalIdent,
27
+ getLocalIdent: (ctx, localIdentName, localName, loaderOptions) => (0, get_css_module_local_ident_1.getCSSModuleLocalIdent)(ctx, localIdentName, localName, loaderOptions, options.cssModuleHashFunction),
28
28
  // css-loader 7 defaults namedExport to true, and to camel-case-only
29
29
  // locals when it is off. Generated components import the default
30
30
  // export and reference class names as authored, so pin both.
@@ -74,6 +74,11 @@ export interface NxAppWebpackPluginOptions {
74
74
  * Set `crossorigin` attribute on the `script` and `link` tags.
75
75
  */
76
76
  crossOrigin?: 'none' | 'anonymous' | 'use-credentials';
77
+ /**
78
+ * Hash algorithm used to generate CSS module class names. Defaults to `md5`,
79
+ * which FIPS-restricted OpenSSL rejects. Changing it renames generated class names.
80
+ */
81
+ cssModuleHashFunction?: string;
77
82
  /**
78
83
  * The deploy path for the application. e.g. `/my-app/`
79
84
  */
@@ -28,13 +28,14 @@ exports.createNodes = [
28
28
  const packageManager = (0, devkit_1.detectPackageManager)(context.workspaceRoot);
29
29
  const pmc = (0, devkit_1.getPackageManagerCommand)(packageManager);
30
30
  const lockFileName = (0, js_1.getLockFileName)(packageManager);
31
+ const includePnpmMajorRuntimeInput = (0, internal_2.shouldIncludePnpmMajorRuntimeInput)(packageManager, context.workspaceRoot);
31
32
  try {
32
33
  const { entries, preErrors } = await filterWebpackConfigs(configFilePaths, context);
33
- const projectHashes = await (0, internal_1.calculateHashesForCreateNodes)(entries.map((e) => e.projectRoot), normalizedOptions, context, entries.map(() => [lockFileName]));
34
+ const projectHashes = await (0, internal_1.calculateHashesForCreateNodes)(entries.map((e) => e.projectRoot), { ...normalizedOptions, includePnpmMajorRuntimeInput }, context, entries.map(() => [lockFileName]));
34
35
  let results = [];
35
36
  let nodeErrors = [];
36
37
  try {
37
- results = await (0, devkit_1.createNodesFromFiles)((configFile, opts, ctx, idx) => createNodesInternal(configFile, opts, ctx, targetsCache, isTsSolutionSetup, pmc, projectHashes[idx]), entries.map((e) => e.configFile), normalizedOptions, context);
38
+ results = await (0, devkit_1.createNodesFromFiles)((configFile, opts, ctx, idx) => createNodesInternal(configFile, opts, ctx, targetsCache, isTsSolutionSetup, packageManager, pmc, includePnpmMajorRuntimeInput, projectHashes[idx]), entries.map((e) => e.configFile), normalizedOptions, context);
38
39
  }
39
40
  catch (e) {
40
41
  if (e instanceof devkit_1.AggregateCreateNodesError) {
@@ -57,10 +58,10 @@ exports.createNodes = [
57
58
  },
58
59
  ];
59
60
  exports.createNodesV2 = exports.createNodes;
60
- async function createNodesInternal(configFilePath, options, context, targetsCache, isTsSolutionSetup, pmc, hash) {
61
+ async function createNodesInternal(configFilePath, options, context, targetsCache, isTsSolutionSetup, packageManager, pmc, includePnpmMajorRuntimeInput, hash) {
61
62
  const projectRoot = (0, path_1.dirname)(configFilePath);
62
63
  if (!targetsCache.has(hash)) {
63
- targetsCache.set(hash, await createWebpackTargets(configFilePath, projectRoot, options, context, isTsSolutionSetup, pmc));
64
+ targetsCache.set(hash, await createWebpackTargets(configFilePath, projectRoot, options, context, isTsSolutionSetup, packageManager, pmc, includePnpmMajorRuntimeInput));
64
65
  }
65
66
  const { targets, metadata } = targetsCache.get(hash);
66
67
  return {
@@ -73,7 +74,7 @@ async function createNodesInternal(configFilePath, options, context, targetsCach
73
74
  },
74
75
  };
75
76
  }
76
- async function createWebpackTargets(configFilePath, projectRoot, options, context, isTsSolutionSetup, pmc) {
77
+ async function createWebpackTargets(configFilePath, projectRoot, options, context, isTsSolutionSetup, packageManager, pmc, includePnpmMajorRuntimeInput) {
77
78
  const namedInputs = (0, internal_1.getNamedInputs)(projectRoot, context);
78
79
  const webpackConfig = (0, resolve_user_defined_webpack_config_1.resolveUserDefinedWebpackConfig)((0, path_1.join)(context.workspaceRoot, configFilePath), (0, js_1.getRootTsConfigPath)(), true);
79
80
  const webpackOptions = await (0, read_webpack_options_1.readWebpackOptions)(webpackConfig);
@@ -87,25 +88,28 @@ async function createWebpackTargets(configFilePath, projectRoot, options, contex
87
88
  targets[options.buildTargetName] = {
88
89
  command: `webpack-cli build`,
89
90
  options: { cwd: projectRoot, env: { NODE_ENV: 'production' } },
91
+ configurations: {
92
+ development: {
93
+ env: { NODE_ENV: 'development' },
94
+ },
95
+ },
90
96
  cache: true,
91
97
  dependsOn: [`^${options.buildTargetName}`],
92
- inputs: 'production' in namedInputs
93
- ? [
94
- 'production',
95
- '^production',
96
- {
97
- externalDependencies: ['webpack-cli'],
98
- },
99
- internal_2.TS_SOLUTION_SETUP_TSCONFIG_INPUT,
100
- ]
101
- : [
102
- 'default',
103
- '^default',
104
- {
105
- externalDependencies: ['webpack-cli'],
106
- },
107
- internal_2.TS_SOLUTION_SETUP_TSCONFIG_INPUT,
108
- ],
98
+ inputs: [
99
+ ...('production' in namedInputs
100
+ ? ['production', '^production']
101
+ : ['default', '^default']),
102
+ {
103
+ externalDependencies: ['webpack-cli'],
104
+ },
105
+ internal_2.TS_SOLUTION_SETUP_TSCONFIG_INPUT,
106
+ // The build can emit a pruned pnpm deploy output (NxAppWebpackPlugin
107
+ // with generatePackageJson), whose install settings come from these
108
+ // otherwise-unhashed root sources.
109
+ ...(packageManager === 'pnpm'
110
+ ? (0, internal_2.pnpmInstallSettingsInputsForInferredTarget)(includePnpmMajorRuntimeInput)
111
+ : []),
112
+ ],
109
113
  outputs,
110
114
  metadata: {
111
115
  technologies: ['webpack'],
@@ -8,7 +8,10 @@ async function getWebpackE2EWebServerInfo(tree, projectName, configFilePath, isP
8
8
  let e2ePort = e2ePortOverride ?? 4200;
9
9
  const servePort = (0, internal_1.readTargetDefaultsForTarget)('serve', nxJson.targetDefaults)
10
10
  ?.options?.port;
11
- if (servePort) {
11
+ // targetDefaults is a workspace-wide fallback, so it fills in only when the caller
12
+ // did not ask for a port. Letting it win over an explicit request would point e2e at
13
+ // a different port than the serve target the generator just wrote.
14
+ if (servePort && e2ePortOverride == null) {
12
15
  e2ePort = servePort;
13
16
  }
14
17
  return (0, internal_1.getE2EWebServerInfo)(tree, projectName, {
@@ -22,5 +25,6 @@ async function getWebpackE2EWebServerInfo(tree, projectName, configFilePath, isP
22
25
  defaultE2EWebServerAddress: `http://localhost:${e2ePort}`,
23
26
  defaultE2ECiBaseUrl: `http://localhost:${e2ePort}`,
24
27
  defaultE2EPort: e2ePort,
28
+ e2EPortIsExplicit: e2ePortOverride != null,
25
29
  }, isPluginBeingAdded);
26
30
  }
@@ -1 +1 @@
1
- export declare function getCSSModuleLocalIdent(ctx: any, localIdentName: any, localName: any, options: any): any;
1
+ export declare function getCSSModuleLocalIdent(ctx: any, localIdentName: any, localName: any, options: any, hashFunction?: string): any;
@@ -3,13 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCSSModuleLocalIdent = getCSSModuleLocalIdent;
4
4
  const path_1 = require("path");
5
5
  const loader_utils_1 = require("loader-utils");
6
- function getCSSModuleLocalIdent(ctx, localIdentName, localName, options) {
6
+ function getCSSModuleLocalIdent(ctx, localIdentName, localName, options, hashFunction) {
7
7
  // Use the filename or folder name, based on some uses the index.js / index.module.(css|scss|sass) project style
8
8
  const fileNameOrFolder = ctx.resourcePath.match(/index\.module\.(css|scss|sass)$/)
9
9
  ? '[folder]'
10
10
  : '[name]';
11
11
  // Create a hash based on a the file location and class name. Will be unique across a project, and close to globally unique.
12
- const hash = (0, loader_utils_1.getHashDigest)(path_1.posix.relative(ctx.rootContext, ctx.resourcePath) + localName, 'md5', 'base64', 5);
12
+ const hash = (0, loader_utils_1.getHashDigest)(path_1.posix.relative(ctx.rootContext, ctx.resourcePath) + localName,
13
+ // md5 is unavailable under FIPS-restricted OpenSSL (nx#36829). Env var stays
14
+ // undocumented on purpose - `cssModuleHashFunction` is the documented option.
15
+ hashFunction || process.env.NX_CSS_MODULE_HASH_FUNCTION || 'md5', 'base64', 5);
13
16
  // Use loaderUtils to find the file or folder name
14
17
  const className = (0, loader_utils_1.interpolateName)(ctx, `${fileNameOrFolder}_${localName}__${hash}`, options);
15
18
  // Remove the .module that appears in every classname when based on the file and replace all "." with "_".
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/webpack",
3
- "version": "23.2.0-pr.36527.2252709",
3
+ "version": "23.2.0-pr.36866.449f6f3",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "files": [
@@ -118,8 +118,8 @@
118
118
  "tslib": "^2.3.0",
119
119
  "webpack-node-externals": "^3.0.0",
120
120
  "webpack-subresource-integrity": "^5.1.0",
121
- "@nx/devkit": "23.2.0-pr.36527.2252709",
122
- "@nx/js": "23.2.0-pr.36527.2252709"
121
+ "@nx/devkit": "23.2.0-pr.36866.449f6f3",
122
+ "@nx/js": "23.2.0-pr.36866.449f6f3"
123
123
  },
124
124
  "peerDependencies": {
125
125
  "webpack": "^5.0.0",
@@ -138,7 +138,7 @@
138
138
  }
139
139
  },
140
140
  "devDependencies": {
141
- "nx": "23.2.0-pr.36527.2252709"
141
+ "nx": "23.2.0-pr.36866.449f6f3"
142
142
  },
143
143
  "publishConfig": {
144
144
  "access": "public"