- fix(rspack): choosing nest as framework should not result in error #31204 - fix(rspack): add deprecation message for application generator - fix(rspack): ensure application generated projects are added to excludes ## Current Behavior Running the `@nx/rspack:application` generator with `--framework=nest` results in an error due to mix of inferred and executor usage throughout the generation process. ## Expected Behavior Running the generator should pass without failure and create a working project. Deprecate the generator in favour of using project specific packages (@nx/react etc) ## Related Issue(s) Fixes #31204 --------- Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
This commit is contained in:
parent
d3faf53c56
commit
34cf5a243f
@ -7,6 +7,7 @@
|
|||||||
"title": "Application generator for React + rspack",
|
"title": "Application generator for React + rspack",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "React + Rspack application generator.",
|
"description": "React + Rspack application generator.",
|
||||||
|
"x-deprecated": "This generator will be removed in Nx 22. Please use the equivalent generator for your application type instead.",
|
||||||
"examples": [
|
"examples": [
|
||||||
{
|
{
|
||||||
"command": "nx g app myorg/myapp",
|
"command": "nx g app myorg/myapp",
|
||||||
@ -90,6 +91,7 @@
|
|||||||
"aliases": ["app"],
|
"aliases": ["app"],
|
||||||
"x-type": "application",
|
"x-type": "application",
|
||||||
"description": "React application generator.",
|
"description": "React application generator.",
|
||||||
|
"x-deprecated": "This generator will be removed in Nx 22. Please use the equivalent generator for your application type instead.",
|
||||||
"implementation": "/packages/rspack/src/generators/application/application.ts",
|
"implementation": "/packages/rspack/src/generators/application/application.ts",
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"path": "/packages/rspack/src/generators/application/schema.json",
|
"path": "/packages/rspack/src/generators/application/schema.json",
|
||||||
|
|||||||
@ -197,7 +197,9 @@ describe('app', () => {
|
|||||||
"targets": {
|
"targets": {
|
||||||
"build": {
|
"build": {
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"development": {},
|
"development": {
|
||||||
|
"outputHashing": "none",
|
||||||
|
},
|
||||||
"production": {},
|
"production": {},
|
||||||
},
|
},
|
||||||
"defaultConfiguration": "production",
|
"defaultConfiguration": "production",
|
||||||
@ -366,7 +368,9 @@ describe('app', () => {
|
|||||||
"targets": {
|
"targets": {
|
||||||
"build": {
|
"build": {
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"development": {},
|
"development": {
|
||||||
|
"outputHashing": "none",
|
||||||
|
},
|
||||||
"production": {},
|
"production": {},
|
||||||
},
|
},
|
||||||
"defaultConfiguration": "production",
|
"defaultConfiguration": "production",
|
||||||
|
|||||||
@ -31,7 +31,9 @@ describe('node app generator (legacy)', () => {
|
|||||||
expect(project.targets.build).toMatchInlineSnapshot(`
|
expect(project.targets.build).toMatchInlineSnapshot(`
|
||||||
{
|
{
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"development": {},
|
"development": {
|
||||||
|
"outputHashing": "none",
|
||||||
|
},
|
||||||
"production": {},
|
"production": {},
|
||||||
},
|
},
|
||||||
"defaultConfiguration": "production",
|
"defaultConfiguration": "production",
|
||||||
|
|||||||
@ -95,7 +95,9 @@ function getWebpackBuildConfig(
|
|||||||
generatePackageJson: options.isUsingTsSolutionConfig ? undefined : true,
|
generatePackageJson: options.isUsingTsSolutionConfig ? undefined : true,
|
||||||
},
|
},
|
||||||
configurations: {
|
configurations: {
|
||||||
development: {},
|
development: {
|
||||||
|
outputHashing: 'none',
|
||||||
|
},
|
||||||
production: {
|
production: {
|
||||||
...(options.docker && { generateLockfile: true }),
|
...(options.docker && { generateLockfile: true }),
|
||||||
},
|
},
|
||||||
@ -197,7 +199,7 @@ function addProject(tree: Tree, options: NormalizedSchema) {
|
|||||||
addBuildTargetDefaults(tree, '@nx/esbuild:esbuild');
|
addBuildTargetDefaults(tree, '@nx/esbuild:esbuild');
|
||||||
project.targets.build = getEsBuildConfig(project, options);
|
project.targets.build = getEsBuildConfig(project, options);
|
||||||
} else if (options.bundler === 'webpack') {
|
} else if (options.bundler === 'webpack') {
|
||||||
if (!hasWebpackPlugin(tree)) {
|
if (!hasWebpackPlugin(tree) && options.addPlugin === false) {
|
||||||
addBuildTargetDefaults(tree, `@nx/webpack:webpack`);
|
addBuildTargetDefaults(tree, `@nx/webpack:webpack`);
|
||||||
project.targets.build = getWebpackBuildConfig(project, options);
|
project.targets.build = getWebpackBuildConfig(project, options);
|
||||||
} else if (options.isNest) {
|
} else if (options.isNest) {
|
||||||
@ -253,7 +255,8 @@ function addAppFiles(tree: Tree, options: NormalizedSchema) {
|
|||||||
tree,
|
tree,
|
||||||
options.appProjectRoot
|
options.appProjectRoot
|
||||||
),
|
),
|
||||||
webpackPluginOptions: hasWebpackPlugin(tree)
|
webpackPluginOptions:
|
||||||
|
hasWebpackPlugin(tree) && options.addPlugin !== false
|
||||||
? {
|
? {
|
||||||
outputPath: options.isUsingTsSolutionConfig
|
outputPath: options.isUsingTsSolutionConfig
|
||||||
? 'dist'
|
? 'dist'
|
||||||
|
|||||||
@ -25,7 +25,8 @@
|
|||||||
"schema": "./src/generators/application/schema.json",
|
"schema": "./src/generators/application/schema.json",
|
||||||
"aliases": ["app"],
|
"aliases": ["app"],
|
||||||
"x-type": "application",
|
"x-type": "application",
|
||||||
"description": "React application generator."
|
"description": "React application generator.",
|
||||||
|
"x-deprecated": "This generator will be removed in Nx 22. Please use the equivalent generator for your application type instead."
|
||||||
},
|
},
|
||||||
"convert-webpack": {
|
"convert-webpack": {
|
||||||
"alias": "convert-to-rspack",
|
"alias": "convert-to-rspack",
|
||||||
|
|||||||
@ -1,14 +1,82 @@
|
|||||||
import { ensurePackage, formatFiles, runTasksInSerial, Tree } from '@nx/devkit';
|
import {
|
||||||
|
ensurePackage,
|
||||||
|
formatFiles,
|
||||||
|
logger,
|
||||||
|
readNxJson,
|
||||||
|
runTasksInSerial,
|
||||||
|
Tree,
|
||||||
|
updateNxJson,
|
||||||
|
} from '@nx/devkit';
|
||||||
import { version as nxVersion } from 'nx/package.json';
|
import { version as nxVersion } from 'nx/package.json';
|
||||||
import configurationGenerator from '../configuration/configuration';
|
import configurationGenerator from '../configuration/configuration';
|
||||||
import rspackInitGenerator from '../init/init';
|
import rspackInitGenerator from '../init/init';
|
||||||
import { normalizeOptions } from './lib/normalize-options';
|
import { normalizeOptions } from './lib/normalize-options';
|
||||||
import { ApplicationGeneratorSchema } from './schema';
|
import { ApplicationGeneratorSchema, NormalizedSchema } from './schema';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the exclude field for any @nx/rspack/plugin registrations in nx.json
|
||||||
|
*/
|
||||||
|
function updateRspackPluginExclusion(tree: Tree, options: NormalizedSchema) {
|
||||||
|
const nxJson = readNxJson(tree);
|
||||||
|
if (!nxJson.plugins?.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let updated = false;
|
||||||
|
|
||||||
|
// Loop through all plugins to find @nx/rspack/plugin registrations
|
||||||
|
for (let i = 0; i < nxJson.plugins.length; i++) {
|
||||||
|
const plugin = nxJson.plugins[i];
|
||||||
|
const isRspackPlugin =
|
||||||
|
typeof plugin === 'string'
|
||||||
|
? plugin === '@nx/rspack/plugin'
|
||||||
|
: plugin.plugin === '@nx/rspack/plugin';
|
||||||
|
|
||||||
|
if (!isRspackPlugin) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof plugin === 'string') {
|
||||||
|
// Convert string notation to object notation with exclude field
|
||||||
|
nxJson.plugins[i] = {
|
||||||
|
plugin: '@nx/rspack/plugin',
|
||||||
|
exclude: [`${options.appProjectRoot}/**`],
|
||||||
|
};
|
||||||
|
updated = true;
|
||||||
|
} else {
|
||||||
|
// Object notation
|
||||||
|
if (!plugin.exclude) {
|
||||||
|
// Add exclude field if it doesn't exist
|
||||||
|
plugin.exclude = [`${options.appProjectRoot}/**`];
|
||||||
|
updated = true;
|
||||||
|
} else if (Array.isArray(plugin.exclude)) {
|
||||||
|
// Add to existing exclude field if it's an array
|
||||||
|
plugin.exclude.push(`${options.appProjectRoot}/**`);
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updated) {
|
||||||
|
updateNxJson(tree, nxJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(v22) - remove this generator
|
||||||
export default async function (
|
export default async function (
|
||||||
tree: Tree,
|
tree: Tree,
|
||||||
_options: ApplicationGeneratorSchema
|
_options: ApplicationGeneratorSchema
|
||||||
) {
|
) {
|
||||||
|
// Add deprecation warning with alternatives based on framework
|
||||||
|
const framework = _options.framework || 'react'; // Default is react
|
||||||
|
|
||||||
|
logger.warn(
|
||||||
|
`The @nx/rspack:application generator is deprecated and will be removed in Nx 22. ` +
|
||||||
|
`Please use @nx/${
|
||||||
|
framework === 'nest' ? 'nest' : framework === 'web' ? 'web' : 'react'
|
||||||
|
}:application instead.`
|
||||||
|
);
|
||||||
|
|
||||||
const tasks = [];
|
const tasks = [];
|
||||||
const initTask = await rspackInitGenerator(tree, {
|
const initTask = await rspackInitGenerator(tree, {
|
||||||
..._options,
|
..._options,
|
||||||
@ -17,6 +85,10 @@ export default async function (
|
|||||||
|
|
||||||
const options = await normalizeOptions(tree, _options);
|
const options = await normalizeOptions(tree, _options);
|
||||||
|
|
||||||
|
if (framework === 'nest') {
|
||||||
|
updateRspackPluginExclusion(tree, options);
|
||||||
|
}
|
||||||
|
|
||||||
options.style ??= 'css';
|
options.style ??= 'css';
|
||||||
|
|
||||||
if (options.framework === 'nest') {
|
if (options.framework === 'nest') {
|
||||||
@ -37,6 +109,7 @@ export default async function (
|
|||||||
newProject: false,
|
newProject: false,
|
||||||
buildTarget: 'build',
|
buildTarget: 'build',
|
||||||
framework: 'nest',
|
framework: 'nest',
|
||||||
|
addPlugin: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
tasks.push(createAppTask, convertAppTask);
|
tasks.push(createAppTask, convertAppTask);
|
||||||
@ -92,6 +165,7 @@ export default async function (
|
|||||||
buildTarget: 'build',
|
buildTarget: 'build',
|
||||||
serveTarget: 'serve',
|
serveTarget: 'serve',
|
||||||
framework: 'react',
|
framework: 'react',
|
||||||
|
addPlugin: false,
|
||||||
});
|
});
|
||||||
tasks.push(createAppTask, convertAppTask);
|
tasks.push(createAppTask, convertAppTask);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
"title": "Application generator for React + rspack",
|
"title": "Application generator for React + rspack",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "React + Rspack application generator.",
|
"description": "React + Rspack application generator.",
|
||||||
|
"x-deprecated": "This generator will be removed in Nx 22. Please use the equivalent generator for your application type instead.",
|
||||||
"examples": [
|
"examples": [
|
||||||
{
|
{
|
||||||
"command": "nx g app myorg/myapp",
|
"command": "nx g app myorg/myapp",
|
||||||
|
|||||||
@ -190,6 +190,16 @@ export function addOrChangeBuildTarget(
|
|||||||
assets,
|
assets,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const existingProjectConfigurations = {};
|
||||||
|
const buildTarget = project.targets.build;
|
||||||
|
if (buildTarget && buildTarget.configurations) {
|
||||||
|
for (const [configurationName, configuration] of Object.entries(
|
||||||
|
buildTarget.configurations
|
||||||
|
)) {
|
||||||
|
existingProjectConfigurations[configurationName] = configuration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
project.targets ??= {};
|
project.targets ??= {};
|
||||||
|
|
||||||
project.targets[target] = {
|
project.targets[target] = {
|
||||||
@ -199,9 +209,11 @@ export function addOrChangeBuildTarget(
|
|||||||
options: buildOptions,
|
options: buildOptions,
|
||||||
configurations: {
|
configurations: {
|
||||||
development: {
|
development: {
|
||||||
|
...(existingProjectConfigurations['development'] ?? {}),
|
||||||
mode: 'development',
|
mode: 'development',
|
||||||
},
|
},
|
||||||
production: {
|
production: {
|
||||||
|
...(existingProjectConfigurations['production'] ?? {}),
|
||||||
mode: 'production',
|
mode: 'production',
|
||||||
optimization: options.target === 'web' ? true : undefined,
|
optimization: options.target === 'web' ? true : undefined,
|
||||||
sourceMap: false,
|
sourceMap: false,
|
||||||
@ -371,7 +383,7 @@ function generateNestConfig(
|
|||||||
project: ProjectConfiguration,
|
project: ProjectConfiguration,
|
||||||
buildOptions: RspackExecutorSchema
|
buildOptions: RspackExecutorSchema
|
||||||
): string {
|
): string {
|
||||||
if (hasPlugin(tree)) {
|
if (hasPlugin(tree) && options.addPlugin !== false) {
|
||||||
return `
|
return `
|
||||||
const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
|
const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
|
||||||
const rspack = require('@rspack/core');
|
const rspack = require('@rspack/core');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user