@nx/next 21.6.1 → 21.6.3

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/migrations.json CHANGED
@@ -1,12 +1,5 @@
1
1
  {
2
- "generators": {
3
- "update-22-0-0-add-svgr-to-next-config": {
4
- "cli": "nx",
5
- "version": "22.0.0-beta.0",
6
- "description": "Updates next.config.js files to add SVGR webpack configuration directly instead of using the nx.svgr option in withNx.",
7
- "factory": "./src/migrations/update-22-0-0/add-svgr-to-next-config"
8
- }
9
- },
2
+ "generators": {},
10
3
  "packageJsonUpdates": {
11
4
  "19.0.3": {
12
5
  "version": "19.0.3-beta.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/next",
3
- "version": "21.6.1",
3
+ "version": "21.6.3",
4
4
  "private": false,
5
5
  "description": "The Next.js plugin for Nx contains executors and generators for managing Next.js applications and libraries within an Nx workspace. It provides:\n\n\n- Scaffolding for creating, building, serving, linting, and testing Next.js applications.\n\n- Integration with building, serving, and exporting a Next.js application.\n\n- Integration with React libraries within the workspace. \n\nWhen using Next.js in Nx, you get the out-of-the-box support for TypeScript, Playwright, Cypress, and Jest. No need to configure anything: watch mode, source maps, and typings just work.",
6
6
  "repository": {
@@ -35,7 +35,7 @@
35
35
  "next": ">=14.0.0"
36
36
  },
37
37
  "dependencies": {
38
- "@nx/devkit": "21.6.1",
38
+ "@nx/devkit": "21.6.3",
39
39
  "@babel/plugin-proposal-decorators": "^7.22.7",
40
40
  "@svgr/webpack": "^8.1.0",
41
41
  "copy-webpack-plugin": "^10.2.4",
@@ -44,15 +44,15 @@
44
44
  "semver": "^7.5.3",
45
45
  "tslib": "^2.3.0",
46
46
  "webpack-merge": "^5.8.0",
47
- "@nx/js": "21.6.1",
48
- "@nx/eslint": "21.6.1",
49
- "@nx/react": "21.6.1",
50
- "@nx/web": "21.6.1",
51
- "@nx/webpack": "21.6.1",
47
+ "@nx/js": "21.6.3",
48
+ "@nx/eslint": "21.6.3",
49
+ "@nx/react": "21.6.3",
50
+ "@nx/web": "21.6.3",
51
+ "@nx/webpack": "21.6.3",
52
52
  "@phenomnomnominal/tsquery": "~5.0.1"
53
53
  },
54
54
  "devDependencies": {
55
- "nx": "21.6.1"
55
+ "nx": "21.6.3"
56
56
  },
57
57
  "publishConfig": {
58
58
  "access": "public"
@@ -6,8 +6,18 @@ import type { NextConfig } from 'next';
6
6
  import type { NextConfigFn } from '../src/utils/config';
7
7
  import { type ProjectGraphProjectNode } from '@nx/devkit';
8
8
  import type { AssetGlobPattern } from '@nx/webpack';
9
+ export interface SvgrOptions {
10
+ svgo?: boolean;
11
+ titleProp?: boolean;
12
+ ref?: boolean;
13
+ }
9
14
  export interface WithNxOptions extends NextConfig {
10
15
  nx?: {
16
+ /**
17
+ * @deprecated Add SVGR support in your Webpack configuration without relying on Nx. See https://react-svgr.com/docs/webpack/
18
+ * TODO(v22): Remove this option and migrate userland webpack config to explicitly configure @svgr/webpack
19
+ * */
20
+ svgr?: boolean | SvgrOptions;
11
21
  babelUpwardRootMode?: boolean;
12
22
  fileReplacements?: {
13
23
  replace: string;
@@ -1 +1 @@
1
- {"version":3,"file":"with-nx.d.ts","sourceRoot":"","sources":["../../../../packages/next/plugins/with-nx.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAGL,KAAK,uBAAuB,EAE7B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,EAAE,CAAC,EAAE;QACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,gBAAgB,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACvD,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAC;KAC7B,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AA+ED;;GAEG;AACH,iBAAS,MAAM,CACb,WAAW,GAAS,aAAa,EACjC,OAAO,GAAE,aAAkC,GAC1C,YAAY,CA0Hd;AAED,wBAAgB,aAAa,CAC3B,UAAU,GAAS,aAAa,EAChC,OAAO,GAAE,aAAkC,GAC1C,UAAU,CAwHZ;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,uBAAuB,EAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAC9B,IAAI,GAAG,MAAM,CAcf;AAGD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,QAM3D;AASD,OAAO,EAAE,MAAM,EAAE,CAAC"}
1
+ {"version":3,"file":"with-nx.d.ts","sourceRoot":"","sources":["../../../../packages/next/plugins/with-nx.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAGL,KAAK,uBAAuB,EAE7B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,EAAE,CAAC,EAAE;QACH;;;aAGK;QACL,IAAI,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;QAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,gBAAgB,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACvD,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAC;KAC7B,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AA+ED;;GAEG;AACH,iBAAS,MAAM,CACb,WAAW,GAAS,aAAa,EACjC,OAAO,GAAE,aAAkC,GAC1C,YAAY,CA0Hd;AAED,wBAAgB,aAAa,CAC3B,UAAU,GAAS,aAAa,EAChC,OAAO,GAAE,aAAkC,GAC1C,UAAU,CAwKZ;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,uBAAuB,EAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAC9B,IAAI,GAAG,MAAM,CAcf;AAGD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,QAM3D;AASD,OAAO,EAAE,MAAM,EAAE,CAAC"}
@@ -237,6 +237,48 @@ function getNextConfig(nextConfig = {}, context = getWithNxContext()) {
237
237
  : includes;
238
238
  delete nextGlobalCssLoader.issuer.and;
239
239
  }
240
+ /**
241
+ * 5. Add SVGR support if option is on.
242
+ */
243
+ // Default SVGR support to be on for projects.
244
+ if (nx?.svgr !== false || typeof nx?.svgr === 'object') {
245
+ forNextVersion('>=15.0.0', () => {
246
+ // Since Next.js 15, turbopack could be enabled by default.
247
+ console.warn(`NX: Next.js SVGR support is deprecated. If used with turbopack, it may not work as expected and is not recommended. Please configure SVGR manually.`);
248
+ });
249
+ const defaultSvgrOptions = {
250
+ svgo: false,
251
+ titleProp: true,
252
+ ref: true,
253
+ };
254
+ const svgrOptions = typeof nx?.svgr === 'object' ? nx.svgr : defaultSvgrOptions;
255
+ // TODO(v22): Remove SVGR support
256
+ config.module.rules.push({
257
+ test: /\.svg$/,
258
+ issuer: { not: /\.(css|scss|sass)$/ },
259
+ resourceQuery: {
260
+ not: [
261
+ /__next_metadata__/,
262
+ /__next_metadata_route__/,
263
+ /__next_metadata_image_meta__/,
264
+ ],
265
+ },
266
+ use: [
267
+ {
268
+ loader: require.resolve('@svgr/webpack'),
269
+ options: svgrOptions,
270
+ },
271
+ {
272
+ loader: require.resolve('file-loader'),
273
+ options: {
274
+ // Next.js hard-codes assets to load from "static/media".
275
+ // See: https://github.com/vercel/next.js/blob/53d017d/packages/next/src/build/webpack-config.ts#L1993
276
+ name: 'static/media/[name].[hash].[ext]',
277
+ },
278
+ },
279
+ ],
280
+ });
281
+ }
240
282
  return userWebpack(config, options);
241
283
  },
242
284
  };
@@ -1,3 +0,0 @@
1
- import { type Tree } from '@nx/devkit';
2
- export default function addSvgrToNextConfig(tree: Tree): Promise<import("@nx/devkit").GeneratorCallback>;
3
- //# sourceMappingURL=add-svgr-to-next-config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-svgr-to-next-config.d.ts","sourceRoot":"","sources":["../../../../../../packages/next/src/migrations/update-22-0-0/add-svgr-to-next-config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,IAAI,EAQV,MAAM,YAAY,CAAC;AAKpB,wBAA8B,mBAAmB,CAAC,IAAI,EAAE,IAAI,mDA6Q3D"}
@@ -1,209 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = addSvgrToNextConfig;
4
- const devkit_1 = require("@nx/devkit");
5
- const executor_options_utils_1 = require("@nx/devkit/src/generators/executor-options-utils");
6
- const tsquery_1 = require("@phenomnomnominal/tsquery");
7
- const ts = require("typescript");
8
- async function addSvgrToNextConfig(tree) {
9
- const projects = new Map();
10
- // Find all Next.js projects using withNx that have svgr explicitly set to true or an options object
11
- (0, executor_options_utils_1.forEachExecutorOptions)(tree, '@nx/next:build', (options, project, target) => {
12
- const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, project);
13
- const nextConfigPath = `${projectConfig.root}/next.config.js`;
14
- if (!tree.exists(nextConfigPath))
15
- return;
16
- const content = tree.read(nextConfigPath, 'utf-8');
17
- if (!content.includes('withNx'))
18
- return;
19
- const ast = tsquery_1.tsquery.ast(content);
20
- let svgrValue;
21
- const nextConfigDeclarations = (0, tsquery_1.tsquery)(ast, 'VariableDeclaration:has(Identifier[name=nextConfig]) > ObjectLiteralExpression');
22
- if (nextConfigDeclarations.length > 0) {
23
- const objLiteral = nextConfigDeclarations[0];
24
- const nxProp = objLiteral.properties.find((prop) => ts.isPropertyAssignment(prop) &&
25
- ts.isIdentifier(prop.name) &&
26
- prop.name.text === 'nx');
27
- if (nxProp && ts.isObjectLiteralExpression(nxProp.initializer)) {
28
- const svgrProp = nxProp.initializer.properties.find((prop) => ts.isPropertyAssignment(prop) &&
29
- ts.isIdentifier(prop.name) &&
30
- prop.name.text === 'svgr');
31
- if (svgrProp) {
32
- // It's an object with options
33
- if (ts.isObjectLiteralExpression(svgrProp.initializer)) {
34
- svgrValue = {};
35
- for (const prop of svgrProp.initializer.properties) {
36
- if (!ts.isPropertyAssignment(prop))
37
- continue;
38
- if (!ts.isIdentifier(prop.name))
39
- continue;
40
- const key = prop.name.text;
41
- if (prop.initializer.kind === ts.SyntaxKind.TrueKeyword) {
42
- svgrValue[key] = true;
43
- }
44
- else if (prop.initializer.kind === ts.SyntaxKind.FalseKeyword) {
45
- svgrValue[key] = false;
46
- }
47
- }
48
- }
49
- // It's a boolean
50
- else {
51
- svgrValue =
52
- svgrProp.initializer.kind === ts.SyntaxKind.TrueKeyword;
53
- }
54
- }
55
- }
56
- }
57
- // If svgr is not defined, skip this project
58
- if (svgrValue === undefined)
59
- return;
60
- projects.set(nextConfigPath, {
61
- svgrOptions: svgrValue,
62
- });
63
- });
64
- if (projects.size === 0)
65
- return;
66
- // Update next.config.js files to add SVGR webpack configuration
67
- for (const [nextConfigPath, config] of projects.entries()) {
68
- let content = tree.read(nextConfigPath, 'utf-8');
69
- const ast = tsquery_1.tsquery.ast(content);
70
- const changes = [];
71
- const nextConfigDeclarations = (0, tsquery_1.tsquery)(ast, 'VariableDeclaration:has(Identifier[name=nextConfig]) > ObjectLiteralExpression');
72
- if (nextConfigDeclarations.length > 0) {
73
- const objLiteral = nextConfigDeclarations[0];
74
- const nxProp = objLiteral.properties.find((prop) => ts.isPropertyAssignment(prop) &&
75
- ts.isIdentifier(prop.name) &&
76
- prop.name.text === 'nx');
77
- if (nxProp && ts.isObjectLiteralExpression(nxProp.initializer)) {
78
- const svgrProp = nxProp.initializer.properties.find((prop) => ts.isPropertyAssignment(prop) &&
79
- ts.isIdentifier(prop.name) &&
80
- prop.name.text === 'svgr');
81
- if (svgrProp) {
82
- const nxObj = nxProp.initializer;
83
- const hasOnlySvgrProperty = nxObj.properties.length === 1;
84
- // Remove svgr property and leave remaining ones
85
- if (hasOnlySvgrProperty) {
86
- changes.push({
87
- type: devkit_1.ChangeType.Delete,
88
- start: nxObj.getStart(),
89
- length: nxObj.getEnd() - nxObj.getStart(),
90
- });
91
- changes.push({
92
- type: devkit_1.ChangeType.Insert,
93
- index: nxObj.getStart(),
94
- text: '{}',
95
- });
96
- }
97
- // If svgr property is the only property, remove the entire nx object
98
- else {
99
- const propIndex = nxObj.properties.indexOf(svgrProp);
100
- const isLastProp = propIndex === nxObj.properties.length - 1;
101
- const isFirstProp = propIndex === 0;
102
- let removeStart = svgrProp.getFullStart();
103
- let removeEnd = svgrProp.getEnd();
104
- // Handle comma removal
105
- if (!isLastProp) {
106
- // Remove trailing comma
107
- const nextProp = nxObj.properties[propIndex + 1];
108
- removeEnd = nextProp.getFullStart();
109
- }
110
- else if (!isFirstProp) {
111
- // Remove preceding comma from previous property
112
- const prevProp = nxObj.properties[propIndex - 1];
113
- const textBetween = content.substring(prevProp.getEnd(), svgrProp.getFullStart());
114
- const commaIndex = textBetween.indexOf(',');
115
- if (commaIndex !== -1) {
116
- removeStart = prevProp.getEnd() + commaIndex;
117
- }
118
- }
119
- changes.push({
120
- type: devkit_1.ChangeType.Delete,
121
- start: removeStart,
122
- length: removeEnd - removeStart,
123
- });
124
- }
125
- }
126
- }
127
- }
128
- // Only add SVGR webpack config if svgrOptions is true or an object
129
- if (config.svgrOptions === true || typeof config.svgrOptions === 'object') {
130
- let svgrOptions = '';
131
- if (config.svgrOptions === true) {
132
- svgrOptions = `{
133
- svgo: false,
134
- titleProp: true,
135
- ref: true,
136
- }`;
137
- }
138
- else if (typeof config.svgrOptions === 'object') {
139
- const options = Object.entries(config.svgrOptions)
140
- .map(([key, value]) => ` ${key}: ${value}`)
141
- .join(',\n');
142
- svgrOptions = `{\n${options}\n }`;
143
- }
144
- const svgrWebpackFunction = `(config) => {
145
- const originalWebpack = config.webpack;
146
- // @ts-ignore
147
- config.webpack = (webpackConfig, ctx) => {
148
- // Add SVGR support
149
- webpackConfig.module.rules.push({
150
- test: /\.svg$/,
151
- issuer: { not: /\.(css|scss|sass)$/ },
152
- resourceQuery: {
153
- not: [
154
- /__next_metadata__/,
155
- /__next_metadata_route__/,
156
- /__next_metadata_image_meta__/,
157
- ],
158
- },
159
- use: [
160
- {
161
- loader: require.resolve('@svgr/webpack'),
162
- options: ${svgrOptions},
163
- },
164
- {
165
- loader: require.resolve('file-loader'),
166
- options: {
167
- name: 'static/media/[name].[hash].[ext]',
168
- },
169
- },
170
- ],
171
- });
172
- return originalWebpack
173
- ? originalWebpack(webpackConfig, ctx)
174
- : webpackConfig;
175
- };
176
- return config;
177
- };`;
178
- const pluginsArrayDeclarations = (0, tsquery_1.tsquery)(ast, 'VariableDeclaration:has(Identifier[name=plugins]) ArrayLiteralExpression');
179
- if (pluginsArrayDeclarations.length > 0) {
180
- const pluginsArray = pluginsArrayDeclarations[0];
181
- const pluginsStatement = pluginsArray.parent.parent;
182
- changes.push({
183
- type: devkit_1.ChangeType.Insert,
184
- index: pluginsStatement.getEnd(),
185
- text: `\n\n// Add SVGR webpack config function\n// @ts-ignore\nconst withSvgr = ${svgrWebpackFunction};`,
186
- });
187
- }
188
- const composePluginsCalls = (0, tsquery_1.tsquery)(ast, 'CallExpression[expression.name=composePlugins]');
189
- if (composePluginsCalls.length > 0) {
190
- const composeCall = composePluginsCalls[0];
191
- const spreadArg = composeCall.arguments.find((arg) => ts.isSpreadElement(arg));
192
- if (spreadArg) {
193
- changes.push({
194
- type: devkit_1.ChangeType.Insert,
195
- index: spreadArg.getEnd(),
196
- text: ', withSvgr',
197
- });
198
- }
199
- }
200
- }
201
- content = (0, devkit_1.applyChangesToString)(content, changes);
202
- tree.write(nextConfigPath, content);
203
- }
204
- await (0, devkit_1.formatFiles)(tree);
205
- // Add file-loader as a dev dependency since it's now required for SVGR
206
- return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
207
- 'file-loader': '^6.2.0',
208
- });
209
- }