feat(rspack): add convert-to-inferred generator (#29012)
- feat(module-federation): migrate to latest - feat(rspack): add convert to legacy plugin - feat(rspack): add convert-to-inferred generator <!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> Our current rspack configs rely on executor usage. But there is no automated method to convert the config to use inferred targets ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> Add convert-to-inferred generator ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
This commit is contained in:
parent
02b8bbeffe
commit
5cc88b87a2
@ -9901,6 +9901,22 @@
|
||||
"children": [],
|
||||
"isExternal": false,
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"id": "convert-config-to-rspack-plugin",
|
||||
"path": "/nx-api/rspack/generators/convert-config-to-rspack-plugin",
|
||||
"name": "convert-config-to-rspack-plugin",
|
||||
"children": [],
|
||||
"isExternal": false,
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"id": "convert-to-inferred",
|
||||
"path": "/nx-api/rspack/generators/convert-to-inferred",
|
||||
"name": "convert-to-inferred",
|
||||
"children": [],
|
||||
"isExternal": false,
|
||||
"disableCollapsible": false
|
||||
}
|
||||
],
|
||||
"isExternal": false,
|
||||
|
||||
@ -3012,6 +3012,24 @@
|
||||
"originalFilePath": "/packages/rspack/src/generators/convert-webpack/schema.json",
|
||||
"path": "/nx-api/rspack/generators/convert-webpack",
|
||||
"type": "generator"
|
||||
},
|
||||
"/nx-api/rspack/generators/convert-config-to-rspack-plugin": {
|
||||
"description": "Convert the project to use the `NxAppRspackPlugin` and `NxReactRspackPlugin`.",
|
||||
"file": "generated/packages/rspack/generators/convert-config-to-rspack-plugin.json",
|
||||
"hidden": false,
|
||||
"name": "convert-config-to-rspack-plugin",
|
||||
"originalFilePath": "/packages/rspack/src/generators/convert-config-to-rspack-plugin/schema.json",
|
||||
"path": "/nx-api/rspack/generators/convert-config-to-rspack-plugin",
|
||||
"type": "generator"
|
||||
},
|
||||
"/nx-api/rspack/generators/convert-to-inferred": {
|
||||
"description": "Convert existing Rspack project(s) using `@nx/rspack:rspack` executor to use `@nx/rspack/plugin`.",
|
||||
"file": "generated/packages/rspack/generators/convert-to-inferred.json",
|
||||
"hidden": false,
|
||||
"name": "convert-to-inferred",
|
||||
"originalFilePath": "/packages/rspack/src/generators/convert-to-inferred/schema.json",
|
||||
"path": "/nx-api/rspack/generators/convert-to-inferred",
|
||||
"type": "generator"
|
||||
}
|
||||
},
|
||||
"path": "/nx-api/rspack"
|
||||
|
||||
@ -2981,6 +2981,24 @@
|
||||
"originalFilePath": "/packages/rspack/src/generators/convert-webpack/schema.json",
|
||||
"path": "rspack/generators/convert-webpack",
|
||||
"type": "generator"
|
||||
},
|
||||
{
|
||||
"description": "Convert the project to use the `NxAppRspackPlugin` and `NxReactRspackPlugin`.",
|
||||
"file": "generated/packages/rspack/generators/convert-config-to-rspack-plugin.json",
|
||||
"hidden": false,
|
||||
"name": "convert-config-to-rspack-plugin",
|
||||
"originalFilePath": "/packages/rspack/src/generators/convert-config-to-rspack-plugin/schema.json",
|
||||
"path": "rspack/generators/convert-config-to-rspack-plugin",
|
||||
"type": "generator"
|
||||
},
|
||||
{
|
||||
"description": "Convert existing Rspack project(s) using `@nx/rspack:rspack` executor to use `@nx/rspack/plugin`.",
|
||||
"file": "generated/packages/rspack/generators/convert-to-inferred.json",
|
||||
"hidden": false,
|
||||
"name": "convert-to-inferred",
|
||||
"originalFilePath": "/packages/rspack/src/generators/convert-to-inferred/schema.json",
|
||||
"path": "rspack/generators/convert-to-inferred",
|
||||
"type": "generator"
|
||||
}
|
||||
],
|
||||
"githubRoot": "https://github.com/nrwl/nx/blob/master",
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "convert-config-to-rspack-plugin",
|
||||
"factory": "./src/generators/convert-config-to-rspack-plugin/convert-config-to-rspack-plugin",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/schema",
|
||||
"$id": "NxRspackConvertConfigToRspackPlugin",
|
||||
"description": "Convert existing Rspack project(s) using `@nx/rspack:rspack` executor that uses `withNx` to use `NxAppRspackPlugin`. Defaults to migrating all projects. Pass '--project' to migrate only one target.",
|
||||
"title": "Convert Rspack project using withNx to NxAppRspackPlugin",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project": {
|
||||
"type": "string",
|
||||
"description": "The project to convert from using the `@nx/rspack:rspack` executor and `withNx` plugin to use `NxAppRspackPlugin`.",
|
||||
"x-priority": "important"
|
||||
},
|
||||
"skipFormat": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to format files at the end of the migration.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"presets": []
|
||||
},
|
||||
"description": "Convert the project to use the `NxAppRspackPlugin` and `NxReactRspackPlugin`.",
|
||||
"implementation": "/packages/rspack/src/generators/convert-config-to-rspack-plugin/convert-config-to-rspack-plugin.ts",
|
||||
"aliases": [],
|
||||
"hidden": false,
|
||||
"path": "/packages/rspack/src/generators/convert-config-to-rspack-plugin/schema.json",
|
||||
"type": "generator"
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "convert-to-inferred",
|
||||
"factory": "./src/generators/convert-to-inferred/convert-to-inferred#convertToInferred",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/schema",
|
||||
"$id": "NxWebpackConvertToInferred",
|
||||
"description": "Convert existing Webpack project(s) using `@nx/webpack:wepack` executor to use `@nx/webpack/plugin`.",
|
||||
"title": "Convert a Webpack project from executor to plugin",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project": {
|
||||
"type": "string",
|
||||
"description": "The project to convert from using the `@nx/webpack:webpack` executor to use `@nx/webpack/plugin`. If not provided, all projects using the `@nx/webpack:webpack` executor will be converted.",
|
||||
"x-priority": "important"
|
||||
},
|
||||
"skipFormat": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to format files.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"presets": []
|
||||
},
|
||||
"description": "Convert existing Rspack project(s) using `@nx/rspack:rspack` executor to use `@nx/rspack/plugin`.",
|
||||
"implementation": "/packages/rspack/src/generators/convert-to-inferred/convert-to-inferred#convertToInferred.ts",
|
||||
"aliases": [],
|
||||
"hidden": false,
|
||||
"path": "/packages/rspack/src/generators/convert-to-inferred/schema.json",
|
||||
"type": "generator"
|
||||
}
|
||||
@ -697,6 +697,8 @@
|
||||
- [preset](/nx-api/rspack/generators/preset)
|
||||
- [application](/nx-api/rspack/generators/application)
|
||||
- [convert-webpack](/nx-api/rspack/generators/convert-webpack)
|
||||
- [convert-config-to-rspack-plugin](/nx-api/rspack/generators/convert-config-to-rspack-plugin)
|
||||
- [convert-to-inferred](/nx-api/rspack/generators/convert-to-inferred)
|
||||
- [storybook](/nx-api/storybook)
|
||||
- [documents](/nx-api/storybook/documents)
|
||||
- [Overview](/nx-api/storybook/documents/overview)
|
||||
|
||||
@ -88,6 +88,7 @@
|
||||
"@nx/vite": "20.2.0-beta.2",
|
||||
"@nx/web": "20.2.0-beta.2",
|
||||
"@nx/webpack": "20.2.0-beta.2",
|
||||
"@nx/rspack": "20.2.0-beta.2",
|
||||
"@phenomnomnominal/tsquery": "~5.0.1",
|
||||
"@playwright/test": "^1.36.1",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
|
||||
|
||||
@ -31,6 +31,16 @@
|
||||
"factory": "./src/generators/convert-webpack/convert-webpack",
|
||||
"schema": "./src/generators/convert-webpack/schema.json",
|
||||
"description": "Convert a webpack application to use rspack."
|
||||
},
|
||||
"convert-config-to-rspack-plugin": {
|
||||
"factory": "./src/generators/convert-config-to-rspack-plugin/convert-config-to-rspack-plugin",
|
||||
"schema": "./src/generators/convert-config-to-rspack-plugin/schema.json",
|
||||
"description": "Convert the project to use the `NxAppRspackPlugin` and `NxReactRspackPlugin`."
|
||||
},
|
||||
"convert-to-inferred": {
|
||||
"factory": "./src/generators/convert-to-inferred/convert-to-inferred#convertToInferred",
|
||||
"schema": "./src/generators/convert-to-inferred/schema.json",
|
||||
"description": "Convert existing Rspack project(s) using `@nx/rspack:rspack` executor to use `@nx/rspack/plugin`."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ export interface RspackExecutorSchema {
|
||||
progress?: boolean;
|
||||
publicPath?: string;
|
||||
rebaseRootRelative?: boolean;
|
||||
rspackConfig: string;
|
||||
rspackConfig?: string;
|
||||
runtimeChunk?: boolean;
|
||||
scripts?: Array<ExtraEntryPointClass | string>;
|
||||
skipTypeChecking?: boolean;
|
||||
|
||||
@ -0,0 +1,437 @@
|
||||
import {
|
||||
ProjectConfiguration,
|
||||
Tree,
|
||||
addProjectConfiguration,
|
||||
} from '@nx/devkit';
|
||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
||||
import convertConfigToRspackPluginGenerator from './convert-config-to-rspack-plugin';
|
||||
|
||||
interface CreateProjectOptions {
|
||||
name: string;
|
||||
root: string;
|
||||
targetName: string;
|
||||
targetOptions: Record<string, unknown>;
|
||||
additionalTargets?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
const defaultOptions: CreateProjectOptions = {
|
||||
name: 'my-app',
|
||||
root: 'my-app',
|
||||
targetName: 'build',
|
||||
targetOptions: {},
|
||||
};
|
||||
|
||||
function createProject(tree: Tree, options: Partial<CreateProjectOptions>) {
|
||||
const projectOpts = {
|
||||
...defaultOptions,
|
||||
...options,
|
||||
targetOptions: {
|
||||
...defaultOptions.targetOptions,
|
||||
...options?.targetOptions,
|
||||
},
|
||||
};
|
||||
const project: ProjectConfiguration = {
|
||||
name: projectOpts.name,
|
||||
root: projectOpts.root,
|
||||
targets: {
|
||||
build: {
|
||||
executor: '@nx/rspack:rspack',
|
||||
options: {
|
||||
rspackConfig: `${projectOpts.root}/rspack.config.js`,
|
||||
...projectOpts.targetOptions,
|
||||
},
|
||||
},
|
||||
...options.additionalTargets,
|
||||
},
|
||||
};
|
||||
|
||||
addProjectConfiguration(tree, project.name, project);
|
||||
|
||||
return project;
|
||||
}
|
||||
|
||||
describe('convertConfigToRspackPluginGenerator', () => {
|
||||
let tree: Tree;
|
||||
|
||||
beforeEach(() => {
|
||||
tree = createTreeWithEmptyWorkspace();
|
||||
});
|
||||
|
||||
it('should migrate the rspack config of the specified project', async () => {
|
||||
const project = createProject(tree, {
|
||||
name: 'my-app',
|
||||
root: 'my-app',
|
||||
});
|
||||
|
||||
createProject(tree, {
|
||||
name: 'another-app',
|
||||
root: 'another-app',
|
||||
});
|
||||
|
||||
tree.write(
|
||||
'another-app/rspack.config.js',
|
||||
`
|
||||
const { composePlugins, withNx } = require('@nx/rspack');
|
||||
const { withReact } = require('@nx/rspack');
|
||||
|
||||
// Nx plugins for rspack.
|
||||
module.exports = composePlugins(
|
||||
withNx(),
|
||||
withReact({
|
||||
// Uncomment this line if you don't want to use SVGR
|
||||
// See: https://react-svgr.com/
|
||||
// svgr: false
|
||||
}),
|
||||
(config) => {
|
||||
return config;
|
||||
}
|
||||
);
|
||||
`
|
||||
);
|
||||
|
||||
tree.write(
|
||||
`${project.name}/rspack.config.js`,
|
||||
`
|
||||
const { composePlugins, withNx } = require('@nx/rspack');
|
||||
const { withReact } = require('@nx/rspack');
|
||||
|
||||
// Nx plugins for rspack.
|
||||
module.exports = composePlugins(
|
||||
withNx(),
|
||||
withReact({
|
||||
// Uncomment this line if you don't want to use SVGR
|
||||
// See: https://react-svgr.com/
|
||||
// svgr: false
|
||||
}),
|
||||
(config) => {
|
||||
return config;
|
||||
}
|
||||
);
|
||||
`
|
||||
);
|
||||
|
||||
await convertConfigToRspackPluginGenerator(tree, {
|
||||
project: project.name,
|
||||
});
|
||||
expect(tree.read(`${project.name}/rspack.config.js`, 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
|
||||
const { NxReactRspackPlugin } = require('@nx/rspack/react-plugin');
|
||||
const { useLegacyNxPlugin } = require('@nx/rspack');
|
||||
|
||||
// This file was migrated using @nx/rspack:convert-config-to-rspack-plugin from your './rspack.config.old.js'
|
||||
// Please check that the options here are correct as they were moved from the old rspack.config.js to this file.
|
||||
const options = {};
|
||||
|
||||
/**
|
||||
* @type{import('@rspack/core').RspackOptionsNormalized}
|
||||
*/
|
||||
module.exports = async () => ({
|
||||
plugins: [
|
||||
new NxAppRspackPlugin(),
|
||||
new NxReactRspackPlugin({
|
||||
// Uncomment this line if you don't want to use SVGR
|
||||
// See: https://react-svgr.com/
|
||||
// svgr: false
|
||||
}),
|
||||
// NOTE: useLegacyNxPlugin ensures that the non-standard Rspack configuration file previously used still works.
|
||||
// To remove its usage, move options such as "plugins" into this file as standard Rspack configuration options.
|
||||
// To enhance configurations after Nx plugins have applied, you can add a new plugin with the \\\`apply\\\` method.
|
||||
// e.g. \\\`{ apply: (compiler) => { /* modify compiler.options */ }\\\`
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
await useLegacyNxPlugin(require('./rspack.config.old'), options),
|
||||
],
|
||||
});
|
||||
"
|
||||
`);
|
||||
|
||||
expect(tree.read(`${project.name}/rspack.config.old.js`, 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"const { composePlugins } = require('@nx/rspack');
|
||||
// Nx plugins for rspack.
|
||||
module.exports = composePlugins((config) => {
|
||||
return config;
|
||||
});
|
||||
"
|
||||
`);
|
||||
|
||||
expect(tree.read(`another-app/rspack.config.js`, 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"const { composePlugins, withNx } = require('@nx/rspack');
|
||||
const { withReact } = require('@nx/rspack');
|
||||
|
||||
// Nx plugins for rspack.
|
||||
module.exports = composePlugins(
|
||||
withNx(),
|
||||
withReact({
|
||||
// Uncomment this line if you don't want to use SVGR
|
||||
// See: https://react-svgr.com/
|
||||
// svgr: false
|
||||
}),
|
||||
(config) => {
|
||||
return config;
|
||||
}
|
||||
);
|
||||
"
|
||||
`);
|
||||
|
||||
expect(tree.exists(`${project.name}/rspack.config.old.js`)).toBe(true);
|
||||
expect(tree.exists(`another-app/rspack.config.old.js`)).toBe(false);
|
||||
});
|
||||
|
||||
it('should update project.json adding the standardRspackConfigFunction option', async () => {
|
||||
const project = createProject(tree, {
|
||||
name: 'my-app',
|
||||
root: 'my-app',
|
||||
});
|
||||
|
||||
tree.write(
|
||||
`${project.name}/rspack.config.js`,
|
||||
`
|
||||
const { composePlugins, withNx } = require('@nx/rspack');
|
||||
const { withReact } = require('@nx/rspack');
|
||||
|
||||
// Nx plugins for rspack.
|
||||
module.exports = composePlugins(
|
||||
withNx(),
|
||||
withReact({
|
||||
// Uncomment this line if you don't want to use SVGR
|
||||
// See: https://react-svgr.com/
|
||||
// svgr: false
|
||||
}),
|
||||
(config) => {
|
||||
return config;
|
||||
}
|
||||
);
|
||||
`
|
||||
);
|
||||
|
||||
await convertConfigToRspackPluginGenerator(tree, {
|
||||
project: project.name,
|
||||
});
|
||||
|
||||
expect(tree.read(`${project.name}/project.json`, 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"{
|
||||
"name": "my-app",
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/rspack:rspack",
|
||||
"options": {
|
||||
"rspackConfig": "my-app/rspack.config.js",
|
||||
"standardRspackConfigFunction": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should throw an error if no projects are found', async () => {
|
||||
const project = createProject(tree, {
|
||||
name: 'my-app',
|
||||
root: 'my-app',
|
||||
});
|
||||
|
||||
await expect(
|
||||
convertConfigToRspackPluginGenerator(tree, {
|
||||
project: project.name,
|
||||
})
|
||||
).rejects.toThrowError('Could not find any projects to migrate.');
|
||||
});
|
||||
|
||||
it('should not migrate a rspack config that does not use withNx', async () => {
|
||||
const project = createProject(tree, {
|
||||
name: 'my-app',
|
||||
root: 'my-app',
|
||||
});
|
||||
|
||||
tree.write(`${project.name}/rspack.config.js`, `module.exports = {};`);
|
||||
|
||||
await expect(
|
||||
convertConfigToRspackPluginGenerator(tree, {
|
||||
project: project.name,
|
||||
})
|
||||
).rejects.toThrowError('Could not find any projects to migrate.');
|
||||
|
||||
expect(
|
||||
tree.read(`${project.name}/rspack.config.js`, 'utf-8')
|
||||
).toMatchInlineSnapshot(`"module.exports = {};"`);
|
||||
});
|
||||
|
||||
it('should throw an error if the project is using Module federation', async () => {
|
||||
const project = createProject(tree, {
|
||||
name: 'my-app',
|
||||
root: 'my-app',
|
||||
additionalTargets: {
|
||||
serve: {
|
||||
executor: '@nx/rspack:module-federation-dev-server',
|
||||
options: {
|
||||
buildTarget: 'my-app:build',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await expect(
|
||||
convertConfigToRspackPluginGenerator(tree, { project: project.name })
|
||||
).rejects.toThrowError(
|
||||
`The project ${project.name} is using Module Federation. At the moment, we don't support migrating projects that use Module Federation.`
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw an error if the project is a Nest project', async () => {
|
||||
const project = createProject(tree, {
|
||||
name: 'my-app',
|
||||
root: 'my-app',
|
||||
additionalTargets: {
|
||||
serve: {
|
||||
executor: '@nx/js:node',
|
||||
options: {
|
||||
buildTarget: 'my-app:build',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await expect(
|
||||
convertConfigToRspackPluginGenerator(tree, { project: project.name })
|
||||
).rejects.toThrowError(
|
||||
`The project ${project.name} is using the '@nx/js:node' executor. At the moment, we do not support migrating such projects.`
|
||||
);
|
||||
});
|
||||
|
||||
it('should not migrate a rspack config that is already using NxAppRspackPlugin', async () => {
|
||||
const project = createProject(tree, {
|
||||
name: 'my-app',
|
||||
root: 'my-app',
|
||||
});
|
||||
|
||||
tree.write(
|
||||
`${project.name}/rspack.config.js`,
|
||||
`
|
||||
const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
new NxAppRspackPlugin(),
|
||||
],
|
||||
};
|
||||
`
|
||||
);
|
||||
|
||||
await expect(
|
||||
convertConfigToRspackPluginGenerator(tree, { project: project.name })
|
||||
).rejects.toThrowError(`Could not find any projects to migrate.`);
|
||||
expect(tree.read(`${project.name}/rspack.config.js`, 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"
|
||||
const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
new NxAppRspackPlugin(),
|
||||
],
|
||||
};
|
||||
"
|
||||
`);
|
||||
expect(tree.exists(`${project.name}/rspack.config.old.js`)).toBe(false);
|
||||
});
|
||||
|
||||
it('should convert absolute options paths to relative paths during the conversion', async () => {
|
||||
const project = createProject(tree, {
|
||||
name: 'my-app',
|
||||
root: 'apps/my-app',
|
||||
});
|
||||
|
||||
tree.write(
|
||||
`${project.root}/rspack.config.js`,
|
||||
`
|
||||
const { composePlugins, withNx } = require('@nx/rspack');
|
||||
const { withReact } = require('@nx/rspack');
|
||||
|
||||
// Nx plugins for rspack.
|
||||
module.exports = composePlugins(
|
||||
withNx({
|
||||
assets: ["apps/${project.name}/src/favicon.ico","apps/${project.name}/src/assets"],
|
||||
styles: ["apps/${project.name}/src/styles.scss"],
|
||||
scripts: ["apps/${project.name}/src/scripts.js"],
|
||||
tsConfig: "apps/${project.name}/tsconfig.app.json",
|
||||
fileReplacements: [
|
||||
{
|
||||
replace: "apps/${project.name}/src/environments/environment.ts",
|
||||
with: "apps/${project.name}/src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
additionalEntryPoints: [
|
||||
{
|
||||
entryPath: "apps/${project.name}/src/polyfills.ts",
|
||||
}
|
||||
]
|
||||
}),
|
||||
withReact({
|
||||
// Uncomment this line if you don't want to use SVGR
|
||||
// See: https://react-svgr.com/
|
||||
// svgr: false
|
||||
}),
|
||||
(config) => {
|
||||
return config;
|
||||
}
|
||||
);
|
||||
`
|
||||
);
|
||||
|
||||
await convertConfigToRspackPluginGenerator(tree, {
|
||||
project: project.name,
|
||||
});
|
||||
expect(tree.read(`${project.root}/rspack.config.js`, 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
|
||||
const { NxReactRspackPlugin } = require('@nx/rspack/react-plugin');
|
||||
const { useLegacyNxPlugin } = require('@nx/rspack');
|
||||
|
||||
// This file was migrated using @nx/rspack:convert-config-to-rspack-plugin from your './rspack.config.old.js'
|
||||
// Please check that the options here are correct as they were moved from the old rspack.config.js to this file.
|
||||
const options = {
|
||||
assets: ['./src/favicon.ico', './src/assets'],
|
||||
styles: ['./src/styles.scss'],
|
||||
scripts: ['./src/scripts.js'],
|
||||
tsConfig: './tsconfig.app.json',
|
||||
fileReplacements: [
|
||||
{
|
||||
replace: './src/environments/environment.ts',
|
||||
with: './src/environments/environment.prod.ts',
|
||||
},
|
||||
],
|
||||
additionalEntryPoints: [
|
||||
{
|
||||
entryPath: './src/polyfills.ts',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @type{import('@rspack/core').RspackOptionsNormalized}
|
||||
*/
|
||||
module.exports = async () => ({
|
||||
plugins: [
|
||||
new NxAppRspackPlugin(options),
|
||||
new NxReactRspackPlugin({
|
||||
// Uncomment this line if you don't want to use SVGR
|
||||
// See: https://react-svgr.com/
|
||||
// svgr: false
|
||||
}),
|
||||
// NOTE: useLegacyNxPlugin ensures that the non-standard Rspack configuration file previously used still works.
|
||||
// To remove its usage, move options such as "plugins" into this file as standard Rspack configuration options.
|
||||
// To enhance configurations after Nx plugins have applied, you can add a new plugin with the \\\`apply\\\` method.
|
||||
// e.g. \\\`{ apply: (compiler) => { /* modify compiler.options */ }\\\`
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
await useLegacyNxPlugin(require('./rspack.config.old'), options),
|
||||
],
|
||||
});
|
||||
"
|
||||
`);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,139 @@
|
||||
import {
|
||||
formatFiles,
|
||||
getProjects,
|
||||
stripIndents,
|
||||
Tree,
|
||||
joinPathFragments,
|
||||
updateProjectConfiguration,
|
||||
ProjectConfiguration,
|
||||
} from '@nx/devkit';
|
||||
import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils';
|
||||
import { RspackExecutorSchema } from '../../executors/rspack/schema';
|
||||
import { extractRspackOptions } from './lib/extract-rspack-options';
|
||||
import { normalizePathOptions } from './lib/normalize-path-options';
|
||||
import { parse } from 'path';
|
||||
import { validateProject } from './lib/validate-project';
|
||||
|
||||
interface Schema {
|
||||
project?: string;
|
||||
skipFormat?: boolean;
|
||||
}
|
||||
|
||||
// Make text JSON compatible
|
||||
const preprocessText = (text: string) => {
|
||||
return text
|
||||
.replace(/(\w+):/g, '"$1":') // Quote property names
|
||||
.replace(/'/g, '"') // Convert single quotes to double quotes
|
||||
.replace(/,(\s*[}\]])/g, '$1') // Remove trailing commas
|
||||
.replace(/(\r\n|\n|\r|\t)/gm, ''); // Remove newlines and tabs
|
||||
};
|
||||
|
||||
export async function convertConfigToRspackPluginGenerator(
|
||||
tree: Tree,
|
||||
options: Schema
|
||||
) {
|
||||
let migrated = 0;
|
||||
|
||||
const projects = getProjects(tree);
|
||||
forEachExecutorOptions<RspackExecutorSchema>(
|
||||
tree,
|
||||
'@nx/rspack:rspack',
|
||||
(currentTargetOptions, projectName, targetName, configurationName) => {
|
||||
if (options.project && projectName !== options.project) {
|
||||
return;
|
||||
}
|
||||
if (!configurationName) {
|
||||
const project = projects.get(projectName);
|
||||
const target = project.targets[targetName];
|
||||
|
||||
const hasError = validateProject(tree, project);
|
||||
if (hasError) {
|
||||
throw new Error(hasError);
|
||||
}
|
||||
|
||||
const rspackConfigPath = currentTargetOptions?.rspackConfig || '';
|
||||
|
||||
if (rspackConfigPath && tree.exists(rspackConfigPath)) {
|
||||
let { withNxConfig: rspackOptions, withReactConfig } =
|
||||
extractRspackOptions(tree, rspackConfigPath);
|
||||
|
||||
// if rspackOptions === undefined
|
||||
// withNx was not found in the rspack.config.js file so we should skip this project
|
||||
if (rspackOptions !== undefined) {
|
||||
let parsedOptions = {};
|
||||
if (rspackOptions) {
|
||||
parsedOptions = JSON.parse(
|
||||
preprocessText(rspackOptions.getText())
|
||||
);
|
||||
parsedOptions = normalizePathOptions(project.root, parsedOptions);
|
||||
}
|
||||
|
||||
target.options.standardRspackConfigFunction = true;
|
||||
|
||||
updateProjectConfiguration(tree, projectName, project);
|
||||
|
||||
const { dir, name, ext } = parse(rspackConfigPath);
|
||||
|
||||
tree.rename(
|
||||
rspackConfigPath,
|
||||
`${joinPathFragments(dir, `${name}.old${ext}`)}`
|
||||
);
|
||||
|
||||
tree.write(
|
||||
rspackConfigPath,
|
||||
stripIndents`
|
||||
const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
|
||||
const { NxReactRspackPlugin } = require('@nx/rspack/react-plugin');
|
||||
const { useLegacyNxPlugin } = require('@nx/rspack');
|
||||
|
||||
// This file was migrated using @nx/rspack:convert-config-to-rspack-plugin from your './rspack.config.old.js'
|
||||
// Please check that the options here are correct as they were moved from the old rspack.config.js to this file.
|
||||
const options = ${
|
||||
rspackOptions ? JSON.stringify(parsedOptions, null, 2) : '{}'
|
||||
};
|
||||
|
||||
/**
|
||||
* @type{import('@rspack/core').RspackOptionsNormalized}
|
||||
*/
|
||||
module.exports = async () => ({
|
||||
plugins: [
|
||||
${
|
||||
rspackOptions
|
||||
? 'new NxAppRspackPlugin(options)'
|
||||
: 'new NxAppRspackPlugin()'
|
||||
},
|
||||
${
|
||||
withReactConfig
|
||||
? `new NxReactRspackPlugin(${withReactConfig.getText()})`
|
||||
: `new NxReactRspackPlugin({
|
||||
// Uncomment this line if you don't want to use SVGR
|
||||
// See: https://react-svgr.com/
|
||||
// svgr: false
|
||||
})`
|
||||
},
|
||||
// NOTE: useLegacyNxPlugin ensures that the non-standard Rspack configuration file previously used still works.
|
||||
// To remove its usage, move options such as "plugins" into this file as standard Rspack configuration options.
|
||||
// To enhance configurations after Nx plugins have applied, you can add a new plugin with the \`apply\` method.
|
||||
// e.g. \`{ apply: (compiler) => { /* modify compiler.options */ }\`
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
await useLegacyNxPlugin(require('./rspack.config.old'), options),
|
||||
],
|
||||
});
|
||||
`
|
||||
);
|
||||
migrated++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
if (migrated === 0) {
|
||||
throw new Error('Could not find any projects to migrate.');
|
||||
}
|
||||
|
||||
if (!options.skipFormat) {
|
||||
await formatFiles(tree);
|
||||
}
|
||||
}
|
||||
|
||||
export default convertConfigToRspackPluginGenerator;
|
||||
@ -0,0 +1,176 @@
|
||||
import { Tree } from '@nx/devkit';
|
||||
import { tsquery } from '@phenomnomnominal/tsquery';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
export function extractRspackOptions(tree: Tree, rspackConfigPath: string) {
|
||||
const source = tree.read(rspackConfigPath).toString('utf-8');
|
||||
const ast = tsquery.ast(source);
|
||||
|
||||
const withNxQuery = 'CallExpression:has(Identifier[name="withNx"])';
|
||||
const withReactQuery = 'CallExpression:has(Identifier[name="withReact"])';
|
||||
const withWebQuery = 'CallExpression:has(Identifier[name="withWeb"])';
|
||||
|
||||
const withNxCall = tsquery(ast, withNxQuery) as ts.CallExpression[];
|
||||
|
||||
const withReactCall = tsquery(ast, withReactQuery) as ts.CallExpression[];
|
||||
|
||||
const withWebCall = tsquery(ast, withWebQuery) as ts.CallExpression[];
|
||||
|
||||
// If the config is empty set to empty string to avoid undefined. Undefined is used to check if the withNx exists inside of the config file.
|
||||
let withNxConfig: ts.Node | '' | undefined,
|
||||
withReactConfig: ts.Node | '' | undefined;
|
||||
|
||||
withWebCall.forEach((node) => {
|
||||
const argument = node.arguments[0] || '';
|
||||
withNxConfig = argument; // Since withWeb and withNx use the same config object and both should not exist in the same file, we can reuse the withNxConfig variable.
|
||||
});
|
||||
|
||||
withNxCall.forEach((node) => {
|
||||
const argument = node.arguments[0] || ''; // The first argument is the config object
|
||||
withNxConfig = argument;
|
||||
});
|
||||
|
||||
withReactCall.forEach((node) => {
|
||||
const argument = node.arguments[0] || '';
|
||||
withReactConfig = argument;
|
||||
});
|
||||
|
||||
if (withNxConfig !== undefined) {
|
||||
// Only remove the withNx and withReact calls if they exist
|
||||
let updatedSource = removeCallExpressions(source, [
|
||||
'withNx',
|
||||
'withReact',
|
||||
'withWeb',
|
||||
]);
|
||||
updatedSource = removeImportDeclarations(
|
||||
updatedSource,
|
||||
'withNx',
|
||||
'@nx/rspack'
|
||||
);
|
||||
updatedSource = removeImportDeclarations(
|
||||
updatedSource,
|
||||
'withWeb',
|
||||
'@nx/rspack'
|
||||
);
|
||||
updatedSource = removeImportDeclarations(
|
||||
updatedSource,
|
||||
'withReact',
|
||||
'@nx/rspack'
|
||||
);
|
||||
|
||||
tree.write(rspackConfigPath, updatedSource);
|
||||
}
|
||||
|
||||
return { withNxConfig, withReactConfig };
|
||||
}
|
||||
|
||||
function removeCallExpressions(
|
||||
source: string,
|
||||
functionNames: string[]
|
||||
): string {
|
||||
let modifiedSource = source;
|
||||
functionNames.forEach((functionName) => {
|
||||
const callExpressionQuery = `CallExpression:has(Identifier[name="composePlugins"]) > CallExpression:has(Identifier[name="${functionName}"])`;
|
||||
|
||||
modifiedSource = tsquery.replace(
|
||||
modifiedSource,
|
||||
callExpressionQuery,
|
||||
() => {
|
||||
return ''; // Removes the entire CallExpression
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
return modifiedSource;
|
||||
}
|
||||
|
||||
function removeImportDeclarations(
|
||||
source: string,
|
||||
importName: string,
|
||||
moduleName: string
|
||||
) {
|
||||
const sourceFile = tsquery.ast(source);
|
||||
|
||||
const modifiedStatements = sourceFile.statements
|
||||
.map((statement) => {
|
||||
if (!ts.isVariableStatement(statement)) return statement;
|
||||
|
||||
const declarationList = statement.declarationList;
|
||||
const newDeclarations = declarationList.declarations
|
||||
.map((declaration) => {
|
||||
if (
|
||||
!ts.isVariableDeclaration(declaration) ||
|
||||
!declaration.initializer
|
||||
)
|
||||
return declaration;
|
||||
|
||||
if (
|
||||
ts.isCallExpression(declaration.initializer) &&
|
||||
ts.isIdentifier(declaration.initializer.expression)
|
||||
) {
|
||||
const callExpr = declaration.initializer.expression;
|
||||
if (
|
||||
callExpr.text === 'require' &&
|
||||
declaration.initializer.arguments[0]
|
||||
?.getText()
|
||||
.replace(/['"]/g, '') === moduleName
|
||||
) {
|
||||
if (ts.isObjectBindingPattern(declaration.name)) {
|
||||
const bindingElements = declaration.name.elements.filter(
|
||||
(element) => {
|
||||
const elementName = element.name.getText();
|
||||
return elementName !== importName;
|
||||
}
|
||||
);
|
||||
|
||||
if (bindingElements.length > 0) {
|
||||
const newBindingPattern =
|
||||
ts.factory.updateObjectBindingPattern(
|
||||
declaration.name,
|
||||
bindingElements
|
||||
);
|
||||
|
||||
// Update the variable declaration with the new binding pattern without the specified import name
|
||||
return ts.factory.updateVariableDeclaration(
|
||||
declaration,
|
||||
newBindingPattern,
|
||||
declaration.exclamationToken,
|
||||
declaration.type,
|
||||
declaration.initializer
|
||||
);
|
||||
} else {
|
||||
return null; // Remove this declaration entirely if no bindings remain
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return declaration;
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
if (newDeclarations.length > 0) {
|
||||
const newDeclarationList = ts.factory.updateVariableDeclarationList(
|
||||
declarationList,
|
||||
newDeclarations as ts.VariableDeclaration[]
|
||||
);
|
||||
return ts.factory.updateVariableStatement(
|
||||
statement,
|
||||
statement.modifiers,
|
||||
newDeclarationList
|
||||
);
|
||||
} else {
|
||||
return null; // Remove the entire statement
|
||||
}
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
// Use printer to format the source code and rewrite the modified
|
||||
const newSourceFile = ts.factory.updateSourceFile(
|
||||
sourceFile,
|
||||
modifiedStatements as ts.Statement[]
|
||||
);
|
||||
const printer = ts.createPrinter();
|
||||
const formattedSource = printer.printFile(newSourceFile);
|
||||
|
||||
return formattedSource;
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
import { RspackExecutorSchema } from '../../../executors/rspack/schema';
|
||||
import { toProjectRelativePath } from './utils';
|
||||
|
||||
const executorFieldsToNormalize: Array<keyof RspackExecutorSchema> = [
|
||||
'outputPath',
|
||||
'index',
|
||||
'main',
|
||||
'assets',
|
||||
'tsConfig',
|
||||
'styles',
|
||||
'additionalEntryPoints',
|
||||
'scripts',
|
||||
'fileReplacements',
|
||||
'postcssConfig',
|
||||
'stylePreprocessorOptions',
|
||||
'publicPath',
|
||||
];
|
||||
|
||||
export function normalizePathOptions(
|
||||
projectRoot: string,
|
||||
options: Partial<RspackExecutorSchema>
|
||||
) {
|
||||
for (const [key, value] of Object.entries(options)) {
|
||||
if (
|
||||
!executorFieldsToNormalize.includes(key as keyof RspackExecutorSchema)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
options[key] = normalizePath(
|
||||
projectRoot,
|
||||
key as keyof RspackExecutorSchema,
|
||||
value
|
||||
);
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
function normalizePath<K extends keyof RspackExecutorSchema>(
|
||||
projectRoot: string,
|
||||
key: K,
|
||||
value: RspackExecutorSchema[K]
|
||||
) {
|
||||
if (!value) return value;
|
||||
|
||||
switch (key) {
|
||||
case 'assets':
|
||||
return value.map((asset) => {
|
||||
if (typeof asset === 'string') {
|
||||
return toProjectRelativePath(asset, projectRoot);
|
||||
}
|
||||
return {
|
||||
...asset,
|
||||
input: toProjectRelativePath(asset.input, projectRoot),
|
||||
output: toProjectRelativePath(asset.output, projectRoot),
|
||||
};
|
||||
});
|
||||
|
||||
case 'styles':
|
||||
case 'scripts':
|
||||
return value.map((item) => {
|
||||
if (typeof item === 'string') {
|
||||
return toProjectRelativePath(item, projectRoot);
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
input: toProjectRelativePath(item.input, projectRoot),
|
||||
};
|
||||
});
|
||||
|
||||
case 'additionalEntryPoints':
|
||||
return value.map((entry) => {
|
||||
return {
|
||||
...entry,
|
||||
entryPath: toProjectRelativePath(entry.entryPath, projectRoot),
|
||||
};
|
||||
});
|
||||
|
||||
case 'fileReplacements':
|
||||
return value.map((replacement) => {
|
||||
return {
|
||||
replace: toProjectRelativePath(replacement.replace, projectRoot),
|
||||
with: toProjectRelativePath(replacement.with, projectRoot),
|
||||
};
|
||||
});
|
||||
|
||||
default:
|
||||
return Array.isArray(value)
|
||||
? value.map((item) => toProjectRelativePath(item, projectRoot))
|
||||
: toProjectRelativePath(value, projectRoot);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
import { relative, resolve } from 'path/posix';
|
||||
import { workspaceRoot } from '@nx/devkit';
|
||||
|
||||
export function toProjectRelativePath(
|
||||
path: string,
|
||||
projectRoot: string
|
||||
): string {
|
||||
if (projectRoot === '.') {
|
||||
// workspace and project root are the same, we normalize it to ensure it
|
||||
return path.startsWith('.') ? path : `./${path}`;
|
||||
}
|
||||
|
||||
const relativePath = relative(
|
||||
resolve(workspaceRoot, projectRoot),
|
||||
resolve(workspaceRoot, path)
|
||||
);
|
||||
|
||||
return relativePath.startsWith('.') ? relativePath : `./${relativePath}`;
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
import { ProjectConfiguration, Tree } from '@nx/devkit';
|
||||
|
||||
function hasAnotherRspackConfig(tree: Tree, projectRoot: string) {
|
||||
const files = tree.children(projectRoot);
|
||||
const projectJsonString = tree.read(`${projectRoot}/project.json`, 'utf-8');
|
||||
for (const file of files) {
|
||||
if (
|
||||
file !== 'rspack.config.js' &&
|
||||
file.endsWith('.js') &&
|
||||
file.includes('rspack.config') &&
|
||||
projectJsonString.includes(file) &&
|
||||
tree.exists(`${projectRoot}/rspack.config.js`)
|
||||
) {
|
||||
return 'Cannot convert a project with multiple rspack config files. Please consolidate them into a single rspack.config.js file.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isNestProject(project: ProjectConfiguration) {
|
||||
for (const target in project.targets) {
|
||||
if (project.targets[target].executor === '@nx/js:node') {
|
||||
return `The project ${project.name} is using the '@nx/js:node' executor. At the moment, we do not support migrating such projects.`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the project to ensure it can be migrated
|
||||
*
|
||||
* @param tree The virtual file system
|
||||
* @param project the project configuration object for the project
|
||||
* @returns A string if there is an error, otherwise undefined
|
||||
*/
|
||||
export function validateProject(tree: Tree, project: ProjectConfiguration) {
|
||||
const containsMfeExecutor = Object.keys(project.targets).some((target) => {
|
||||
return ['@nx/rspack:module-federation-dev-server'].includes(
|
||||
project.targets[target].executor
|
||||
);
|
||||
});
|
||||
|
||||
if (containsMfeExecutor) {
|
||||
return `The project ${project.name} is using Module Federation. At the moment, we don't support migrating projects that use Module Federation.`;
|
||||
}
|
||||
|
||||
const hasAnotherConfig = hasAnotherRspackConfig(tree, project.root);
|
||||
return hasAnotherConfig || isNestProject(project);
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/schema",
|
||||
"$id": "NxRspackConvertConfigToRspackPlugin",
|
||||
"description": "Convert existing Rspack project(s) using `@nx/rspack:rspack` executor that uses `withNx` to use `NxAppRspackPlugin`. Defaults to migrating all projects. Pass '--project' to migrate only one target.",
|
||||
"title": "Convert Rspack project using withNx to NxAppRspackPlugin",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project": {
|
||||
"type": "string",
|
||||
"description": "The project to convert from using the `@nx/rspack:rspack` executor and `withNx` plugin to use `NxAppRspackPlugin`.",
|
||||
"x-priority": "important"
|
||||
},
|
||||
"skipFormat": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to format files at the end of the migration.",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,268 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`convert-to-inferred all projects should migrate all projects using the rspack executors 1`] = `
|
||||
"const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
|
||||
const { NxReactRspackPlugin } = require('@nx/rspack/react-plugin');
|
||||
const { useLegacyNxPlugin } = require('@nx/rspack');
|
||||
|
||||
// These options were migrated by @nx/rspack:convert-to-inferred from
|
||||
// the project.json file and merged with the options in this file
|
||||
const configValues = {
|
||||
build: {
|
||||
default: {
|
||||
outputPath: '../../dist/apps/app1',
|
||||
index: './src/index.html',
|
||||
main: './src/main.tsx',
|
||||
tsConfig: './tsconfig.app.json',
|
||||
assets: ['./src/favicon.ico', './src/assets'],
|
||||
styles: ['./src/styles.scss'],
|
||||
},
|
||||
development: {
|
||||
extractLicenses: false,
|
||||
optimization: false,
|
||||
sourceMap: true,
|
||||
vendorChunk: true,
|
||||
},
|
||||
production: {
|
||||
fileReplacements: [
|
||||
{
|
||||
replace: './src/environments/environment.ts',
|
||||
with: './src/environments/environment.prod.ts',
|
||||
},
|
||||
],
|
||||
optimization: true,
|
||||
outputHashing: 'all',
|
||||
sourceMap: false,
|
||||
namedChunks: false,
|
||||
extractLicenses: true,
|
||||
vendorChunk: false,
|
||||
},
|
||||
},
|
||||
serve: {
|
||||
default: {
|
||||
hmr: true,
|
||||
server: {
|
||||
type: 'https',
|
||||
options: { cert: './server.crt', key: './server.key' },
|
||||
},
|
||||
port: 4200,
|
||||
headers: { 'Access-Control-Allow-Origin': '*' },
|
||||
historyApiFallback: {
|
||||
index: '/index.html',
|
||||
disableDotRule: true,
|
||||
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
|
||||
},
|
||||
},
|
||||
development: { open: true },
|
||||
production: { hmr: false },
|
||||
},
|
||||
};
|
||||
|
||||
// Determine the correct configValue to use based on the configuration
|
||||
const configuration = process.env.NX_TASK_TARGET_CONFIGURATION || 'default';
|
||||
|
||||
const buildOptions = {
|
||||
...configValues.build.default,
|
||||
...configValues.build[configuration],
|
||||
};
|
||||
const devServerOptions = {
|
||||
...configValues.serve.default,
|
||||
...configValues.serve[configuration],
|
||||
};
|
||||
|
||||
/**
|
||||
* @type{import('@rspack/core').RspackOptionsNormalized}
|
||||
*/
|
||||
module.exports = async () => ({
|
||||
devServer: devServerOptions,
|
||||
plugins: [
|
||||
new NxAppRspackPlugin(buildOptions),
|
||||
new NxReactRspackPlugin({
|
||||
// Uncomment this line if you don't want to use SVGR
|
||||
// See: https://react-svgr.com/
|
||||
// svgr: false
|
||||
}),
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
await useLegacyNxPlugin(require('./rspack.config.old'), buildOptions),
|
||||
],
|
||||
});
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`convert-to-inferred all projects should migrate all projects using the rspack executors 2`] = `
|
||||
"const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
|
||||
const { NxReactRspackPlugin } = require('@nx/rspack/react-plugin');
|
||||
const { useLegacyNxPlugin } = require('@nx/rspack');
|
||||
|
||||
// These options were migrated by @nx/rspack:convert-to-inferred from
|
||||
// the project.json file and merged with the options in this file
|
||||
const configValues = {
|
||||
build: {
|
||||
default: {
|
||||
outputPath: '../../dist/apps/app2',
|
||||
index: './src/index.html',
|
||||
main: './src/main.tsx',
|
||||
tsConfig: './tsconfig.app.json',
|
||||
assets: ['./src/favicon.ico', './src/assets'],
|
||||
styles: ['./src/styles.scss'],
|
||||
},
|
||||
development: {
|
||||
extractLicenses: false,
|
||||
optimization: false,
|
||||
sourceMap: true,
|
||||
vendorChunk: true,
|
||||
},
|
||||
production: {
|
||||
fileReplacements: [
|
||||
{
|
||||
replace: './src/environments/environment.ts',
|
||||
with: './src/environments/environment.prod.ts',
|
||||
},
|
||||
],
|
||||
optimization: true,
|
||||
outputHashing: 'all',
|
||||
sourceMap: false,
|
||||
namedChunks: false,
|
||||
extractLicenses: true,
|
||||
vendorChunk: false,
|
||||
},
|
||||
},
|
||||
serve: {
|
||||
default: {
|
||||
hmr: true,
|
||||
server: {
|
||||
type: 'https',
|
||||
options: { cert: './server.crt', key: './server.key' },
|
||||
},
|
||||
port: 4200,
|
||||
headers: { 'Access-Control-Allow-Origin': '*' },
|
||||
historyApiFallback: {
|
||||
index: '/index.html',
|
||||
disableDotRule: true,
|
||||
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
|
||||
},
|
||||
},
|
||||
development: { open: true },
|
||||
production: { hmr: false },
|
||||
},
|
||||
};
|
||||
|
||||
// Determine the correct configValue to use based on the configuration
|
||||
const configuration = process.env.NX_TASK_TARGET_CONFIGURATION || 'default';
|
||||
|
||||
const buildOptions = {
|
||||
...configValues.build.default,
|
||||
...configValues.build[configuration],
|
||||
};
|
||||
const devServerOptions = {
|
||||
...configValues.serve.default,
|
||||
...configValues.serve[configuration],
|
||||
};
|
||||
|
||||
/**
|
||||
* @type{import('@rspack/core').RspackOptionsNormalized}
|
||||
*/
|
||||
module.exports = async () => ({
|
||||
devServer: devServerOptions,
|
||||
plugins: [
|
||||
new NxAppRspackPlugin(buildOptions),
|
||||
new NxReactRspackPlugin({
|
||||
// Uncomment this line if you don't want to use SVGR
|
||||
// See: https://react-svgr.com/
|
||||
// svgr: false
|
||||
}),
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
await useLegacyNxPlugin(require('./rspack.config.old'), buildOptions),
|
||||
],
|
||||
});
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`convert-to-inferred all projects should migrate all projects using the rspack executors 3`] = `
|
||||
"const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
|
||||
const { NxReactRspackPlugin } = require('@nx/rspack/react-plugin');
|
||||
const { useLegacyNxPlugin } = require('@nx/rspack');
|
||||
|
||||
// These options were migrated by @nx/rspack:convert-to-inferred from
|
||||
// the project.json file and merged with the options in this file
|
||||
const configValues = {
|
||||
build: {
|
||||
default: {
|
||||
outputPath: '../../dist/apps/app3',
|
||||
index: './src/index.html',
|
||||
main: './src/main.tsx',
|
||||
tsConfig: './tsconfig.app.json',
|
||||
assets: ['./src/favicon.ico', './src/assets'],
|
||||
styles: ['./src/styles.scss'],
|
||||
},
|
||||
development: {
|
||||
extractLicenses: false,
|
||||
optimization: false,
|
||||
sourceMap: true,
|
||||
vendorChunk: true,
|
||||
},
|
||||
production: {
|
||||
fileReplacements: [
|
||||
{
|
||||
replace: './src/environments/environment.ts',
|
||||
with: './src/environments/environment.prod.ts',
|
||||
},
|
||||
],
|
||||
optimization: true,
|
||||
outputHashing: 'all',
|
||||
sourceMap: false,
|
||||
namedChunks: false,
|
||||
extractLicenses: true,
|
||||
vendorChunk: false,
|
||||
},
|
||||
},
|
||||
serve: {
|
||||
default: {
|
||||
hmr: true,
|
||||
server: {
|
||||
type: 'https',
|
||||
options: { cert: './server.crt', key: './server.key' },
|
||||
},
|
||||
port: 4200,
|
||||
headers: { 'Access-Control-Allow-Origin': '*' },
|
||||
historyApiFallback: {
|
||||
index: '/index.html',
|
||||
disableDotRule: true,
|
||||
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
|
||||
},
|
||||
},
|
||||
development: { open: true },
|
||||
production: { hmr: false },
|
||||
},
|
||||
};
|
||||
|
||||
// Determine the correct configValue to use based on the configuration
|
||||
const configuration = process.env.NX_TASK_TARGET_CONFIGURATION || 'default';
|
||||
|
||||
const buildOptions = {
|
||||
...configValues.build.default,
|
||||
...configValues.build[configuration],
|
||||
};
|
||||
const devServerOptions = {
|
||||
...configValues.serve.default,
|
||||
...configValues.serve[configuration],
|
||||
};
|
||||
|
||||
/**
|
||||
* @type{import('@rspack/core').RspackOptionsNormalized}
|
||||
*/
|
||||
module.exports = async () => ({
|
||||
devServer: devServerOptions,
|
||||
plugins: [
|
||||
new NxAppRspackPlugin(buildOptions),
|
||||
new NxReactRspackPlugin({
|
||||
// Uncomment this line if you don't want to use SVGR
|
||||
// See: https://react-svgr.com/
|
||||
// svgr: false
|
||||
}),
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
await useLegacyNxPlugin(require('./rspack.config.old'), buildOptions),
|
||||
],
|
||||
});
|
||||
"
|
||||
`;
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,185 @@
|
||||
import {
|
||||
addDependenciesToPackageJson,
|
||||
createProjectGraphAsync,
|
||||
formatFiles,
|
||||
runTasksInSerial,
|
||||
type ProjectConfiguration,
|
||||
type Tree,
|
||||
} from '@nx/devkit';
|
||||
import { AggregatedLog } from '@nx/devkit/src/generators/plugin-migrations/aggregate-log-util';
|
||||
import {
|
||||
migrateProjectExecutorsToPlugin,
|
||||
NoTargetsToMigrateError,
|
||||
} from '@nx/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator';
|
||||
import { tsquery } from '@phenomnomnominal/tsquery';
|
||||
import * as ts from 'typescript';
|
||||
import { createNodesV2, type RspackPluginOptions } from '../../plugins/plugin';
|
||||
import { rspackCoreVersion } from '../../utils/versions';
|
||||
import {
|
||||
buildPostTargetTransformerFactory,
|
||||
servePostTargetTransformerFactory,
|
||||
type MigrationContext,
|
||||
} from './utils';
|
||||
import { logger as devkitLogger } from 'nx/src/devkit-exports';
|
||||
|
||||
interface Schema {
|
||||
project?: string;
|
||||
skipFormat?: boolean;
|
||||
}
|
||||
|
||||
export async function convertToInferred(tree: Tree, options: Schema) {
|
||||
const projectGraph = await createProjectGraphAsync();
|
||||
const migrationContext: MigrationContext = {
|
||||
logger: new AggregatedLog(),
|
||||
projectGraph,
|
||||
workspaceRoot: tree.root,
|
||||
};
|
||||
|
||||
const logger = createCollectingLogger();
|
||||
|
||||
const migratedProjects =
|
||||
await migrateProjectExecutorsToPlugin<RspackPluginOptions>(
|
||||
tree,
|
||||
projectGraph,
|
||||
'@nx/rspack/plugin',
|
||||
createNodesV2,
|
||||
{
|
||||
buildTargetName: 'build',
|
||||
previewTargetName: 'preview',
|
||||
serveStaticTargetName: 'serve-static',
|
||||
serveTargetName: 'serve',
|
||||
},
|
||||
[
|
||||
{
|
||||
executors: ['@nx/rspack:rspack', '@nrwl/rspack:rspack'],
|
||||
postTargetTransformer:
|
||||
buildPostTargetTransformerFactory(migrationContext),
|
||||
targetPluginOptionMapper: (target) => ({ buildTargetName: target }),
|
||||
skipProjectFilter: skipProjectFilterFactory(tree),
|
||||
},
|
||||
{
|
||||
executors: ['@nx/rspack:dev-server', '@nrwl/rspack:dev-server'],
|
||||
postTargetTransformer:
|
||||
servePostTargetTransformerFactory(migrationContext),
|
||||
targetPluginOptionMapper: (target) => ({ serveTargetName: target }),
|
||||
skipProjectFilter: skipProjectFilterFactory(tree),
|
||||
},
|
||||
],
|
||||
options.project,
|
||||
logger
|
||||
);
|
||||
|
||||
if (migratedProjects.size === 0) {
|
||||
const convertMessage = [...logger.loggedMessages.values()]
|
||||
.flat()
|
||||
.find((v) => v.includes('@nx/rspack:convert-config-to-rspack-plugin'));
|
||||
|
||||
if (convertMessage.length > 0) {
|
||||
logger.flushLogs((message) => !convertMessage.includes(message));
|
||||
throw new Error(convertMessage);
|
||||
} else {
|
||||
logger.flushLogs();
|
||||
throw new NoTargetsToMigrateError();
|
||||
}
|
||||
} else {
|
||||
logger.flushLogs();
|
||||
}
|
||||
|
||||
const installCallback = addDependenciesToPackageJson(
|
||||
tree,
|
||||
{},
|
||||
{ '@rspack/core': rspackCoreVersion },
|
||||
undefined,
|
||||
true
|
||||
);
|
||||
|
||||
if (!options.skipFormat) {
|
||||
await formatFiles(tree);
|
||||
}
|
||||
|
||||
return runTasksInSerial(installCallback, () => {
|
||||
migrationContext.logger.flushLogs();
|
||||
});
|
||||
}
|
||||
|
||||
function skipProjectFilterFactory(tree: Tree) {
|
||||
return function skipProjectFilter(
|
||||
projectConfiguration: ProjectConfiguration
|
||||
): false | string {
|
||||
const buildTarget = Object.values(projectConfiguration.targets).find(
|
||||
(target) =>
|
||||
target.executor === '@nx/rspack:rspack' ||
|
||||
target.executor === '@nrwl/rspack:rspack'
|
||||
);
|
||||
// the projects for which this is called are guaranteed to have a build target
|
||||
const rspackConfigPath = buildTarget.options.rspackConfig;
|
||||
if (!rspackConfigPath) {
|
||||
return `The rspack config path is missing in the project configuration (${projectConfiguration.root}).`;
|
||||
}
|
||||
|
||||
const sourceFile = tsquery.ast(tree.read(rspackConfigPath, 'utf-8'));
|
||||
|
||||
const composePluginsSelector =
|
||||
'CallExpression:has(Identifier[name=composePlugins])';
|
||||
const composePlugins = tsquery<ts.CallExpression>(
|
||||
sourceFile,
|
||||
composePluginsSelector
|
||||
)[0];
|
||||
|
||||
if (composePlugins) {
|
||||
return `The rspack config (${rspackConfigPath}) can only work with the "@nx/rspack:rspack" executor. Run the "@nx/rspack:convert-config-to-rspack-plugin" generator first.`;
|
||||
}
|
||||
|
||||
const nxAppRspackPluginSelector =
|
||||
'PropertyAssignment:has(Identifier[name=plugins]) NewExpression:has(Identifier[name=NxAppRspackPlugin])';
|
||||
const nxAppRspackPlugin = tsquery<ts.NewExpression>(
|
||||
sourceFile,
|
||||
nxAppRspackPluginSelector
|
||||
)[0];
|
||||
|
||||
if (!nxAppRspackPlugin) {
|
||||
return `No "NxAppRspackPlugin" found in the rspack config (${rspackConfigPath}). Its usage is required for the migration to work.`;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
export function createCollectingLogger(): typeof devkitLogger & {
|
||||
loggedMessages: Map<string, string[]>;
|
||||
flushLogs: (filter?: (message: string) => boolean) => void;
|
||||
} {
|
||||
const loggedMessages = new Map<string, string[]>();
|
||||
|
||||
const flushLogs = (filter?: (message: string) => boolean) => {
|
||||
loggedMessages.forEach((messages, method) => {
|
||||
messages.forEach((message) => {
|
||||
if (!filter || filter(message)) {
|
||||
devkitLogger[method](message);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return new Proxy(
|
||||
{ ...devkitLogger, loggedMessages, flushLogs },
|
||||
{
|
||||
get(target, property) {
|
||||
const originalMethod = target[property];
|
||||
|
||||
if (typeof originalMethod === 'function') {
|
||||
return (...args) => {
|
||||
const message = args.join(' ');
|
||||
const propertyString = String(property);
|
||||
if (!loggedMessages.has(message)) {
|
||||
loggedMessages.set(propertyString, []);
|
||||
}
|
||||
loggedMessages.get(propertyString).push(message);
|
||||
};
|
||||
}
|
||||
|
||||
return originalMethod;
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/schema",
|
||||
"$id": "NxWebpackConvertToInferred",
|
||||
"description": "Convert existing Webpack project(s) using `@nx/webpack:wepack` executor to use `@nx/webpack/plugin`.",
|
||||
"title": "Convert a Webpack project from executor to plugin",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project": {
|
||||
"type": "string",
|
||||
"description": "The project to convert from using the `@nx/webpack:webpack` executor to use `@nx/webpack/plugin`. If not provided, all projects using the `@nx/webpack:webpack` executor will be converted.",
|
||||
"x-priority": "important"
|
||||
},
|
||||
"skipFormat": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to format files.",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
import * as ts from 'typescript';
|
||||
|
||||
export function toPropertyAssignment(
|
||||
key: string,
|
||||
value: unknown
|
||||
): ts.PropertyAssignment {
|
||||
if (typeof value === 'string') {
|
||||
return ts.factory.createPropertyAssignment(
|
||||
ts.factory.createStringLiteral(key),
|
||||
ts.factory.createStringLiteral(value)
|
||||
);
|
||||
} else if (typeof value === 'number') {
|
||||
return ts.factory.createPropertyAssignment(
|
||||
ts.factory.createStringLiteral(key),
|
||||
ts.factory.createNumericLiteral(value)
|
||||
);
|
||||
} else if (typeof value === 'boolean') {
|
||||
return ts.factory.createPropertyAssignment(
|
||||
ts.factory.createStringLiteral(key),
|
||||
value ? ts.factory.createTrue() : ts.factory.createFalse()
|
||||
);
|
||||
} else if (Array.isArray(value)) {
|
||||
return ts.factory.createPropertyAssignment(
|
||||
ts.factory.createStringLiteral(key),
|
||||
ts.factory.createArrayLiteralExpression(
|
||||
value.map((item) => toExpression(item))
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return ts.factory.createPropertyAssignment(
|
||||
ts.factory.createStringLiteral(key),
|
||||
ts.factory.createObjectLiteralExpression(
|
||||
Object.entries(value).map(([key, value]) =>
|
||||
toPropertyAssignment(key, value)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function toExpression(value: unknown): ts.Expression {
|
||||
if (typeof value === 'string') {
|
||||
return ts.factory.createStringLiteral(value);
|
||||
} else if (typeof value === 'number') {
|
||||
return ts.factory.createNumericLiteral(value);
|
||||
} else if (typeof value === 'boolean') {
|
||||
return value ? ts.factory.createTrue() : ts.factory.createFalse();
|
||||
} else if (Array.isArray(value)) {
|
||||
return ts.factory.createArrayLiteralExpression(
|
||||
value.map((item) => toExpression(item))
|
||||
);
|
||||
} else {
|
||||
return ts.factory.createObjectLiteralExpression(
|
||||
Object.entries(value).map(([key, value]) =>
|
||||
toPropertyAssignment(key, value)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,397 @@
|
||||
import type { TargetConfiguration, Tree } from '@nx/devkit';
|
||||
import {
|
||||
processTargetOutputs,
|
||||
toProjectRelativePath,
|
||||
} from '@nx/devkit/src/generators/plugin-migrations/plugin-migration-utils';
|
||||
import { tsquery } from '@phenomnomnominal/tsquery';
|
||||
import * as ts from 'typescript';
|
||||
import type { RspackExecutorSchema } from '../../../executors/rspack/schema';
|
||||
import type { NxAppRspackPluginOptions } from '../../../plugins/utils/models';
|
||||
import { toPropertyAssignment } from './ast';
|
||||
import type { MigrationContext, TransformerContext } from './types';
|
||||
|
||||
export function buildPostTargetTransformerFactory(
|
||||
migrationContext: MigrationContext
|
||||
) {
|
||||
return function buildPostTargetTransformer(
|
||||
target: TargetConfiguration,
|
||||
tree: Tree,
|
||||
projectDetails: { projectName: string; root: string },
|
||||
inferredTarget: TargetConfiguration
|
||||
): TargetConfiguration {
|
||||
const context: TransformerContext = {
|
||||
...migrationContext,
|
||||
projectName: projectDetails.projectName,
|
||||
projectRoot: projectDetails.root,
|
||||
};
|
||||
|
||||
const { pluginOptions, rspackConfigPath } = processOptions(target, context);
|
||||
|
||||
updateRspackConfig(tree, rspackConfigPath, pluginOptions);
|
||||
|
||||
if (target.outputs) {
|
||||
processTargetOutputs(target, [], inferredTarget, {
|
||||
projectName: projectDetails.projectName,
|
||||
projectRoot: projectDetails.root,
|
||||
});
|
||||
}
|
||||
|
||||
return target;
|
||||
};
|
||||
}
|
||||
|
||||
type ExtractedOptions = {
|
||||
default: NxAppRspackPluginOptions;
|
||||
[configName: string]: NxAppRspackPluginOptions;
|
||||
};
|
||||
|
||||
function processOptions(
|
||||
target: TargetConfiguration<RspackExecutorSchema>,
|
||||
context: TransformerContext
|
||||
): {
|
||||
pluginOptions: ExtractedOptions;
|
||||
rspackConfigPath: string;
|
||||
} {
|
||||
const rspackConfig = target.options.rspackConfig;
|
||||
delete target.options.rspackConfig;
|
||||
|
||||
const pluginOptions: ExtractedOptions = {
|
||||
default: extractPluginOptions(target.options, context),
|
||||
};
|
||||
|
||||
if (target.configurations && Object.keys(target.configurations).length) {
|
||||
for (const [configName, config] of Object.entries(target.configurations)) {
|
||||
pluginOptions[configName] = extractPluginOptions(
|
||||
config,
|
||||
context,
|
||||
configName
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return { pluginOptions, rspackConfigPath: rspackConfig };
|
||||
}
|
||||
|
||||
const pathOptions = new Set([
|
||||
'index',
|
||||
'main',
|
||||
'outputPath',
|
||||
'polyfills',
|
||||
'postcssConfig',
|
||||
'tsConfig',
|
||||
]);
|
||||
const assetsOptions = new Set(['assets', 'scripts', 'styles']);
|
||||
|
||||
function extractPluginOptions(
|
||||
options: RspackExecutorSchema,
|
||||
context: TransformerContext,
|
||||
configName?: string
|
||||
): NxAppRspackPluginOptions {
|
||||
const pluginOptions: NxAppRspackPluginOptions = {};
|
||||
|
||||
for (const [key, value] of Object.entries(options)) {
|
||||
if (pathOptions.has(key)) {
|
||||
pluginOptions[key] = toProjectRelativePath(value, context.projectRoot);
|
||||
delete options[key];
|
||||
} else if (assetsOptions.has(key)) {
|
||||
pluginOptions[key] = value.map((asset: string | { input: string }) => {
|
||||
if (typeof asset === 'string') {
|
||||
return toProjectRelativePath(asset, context.projectRoot);
|
||||
}
|
||||
|
||||
asset.input = toProjectRelativePath(asset.input, context.projectRoot);
|
||||
return asset;
|
||||
});
|
||||
delete options[key];
|
||||
} else if (key === 'fileReplacements') {
|
||||
pluginOptions.fileReplacements = value.map(
|
||||
(replacement: { replace: string; with: string }) => ({
|
||||
replace: toProjectRelativePath(
|
||||
replacement.replace,
|
||||
context.projectRoot
|
||||
),
|
||||
with: toProjectRelativePath(replacement.with, context.projectRoot),
|
||||
})
|
||||
);
|
||||
delete options.fileReplacements;
|
||||
} else if (key === 'additionalEntryPoints') {
|
||||
pluginOptions.additionalEntryPoints = value.map((entryPoint) => {
|
||||
entryPoint.entryPath = toProjectRelativePath(
|
||||
entryPoint.entryPath,
|
||||
context.projectRoot
|
||||
);
|
||||
return entryPoint;
|
||||
});
|
||||
delete options.additionalEntryPoints;
|
||||
} else if (key === 'memoryLimit') {
|
||||
pluginOptions.memoryLimit = value;
|
||||
const serveMemoryLimit = getMemoryLimitFromServeTarget(
|
||||
context,
|
||||
configName
|
||||
);
|
||||
if (serveMemoryLimit) {
|
||||
pluginOptions.memoryLimit = Math.max(serveMemoryLimit, value);
|
||||
context.logger.addLog({
|
||||
executorName: '@nx/rspack:rspack',
|
||||
log: `The "memoryLimit" option was set in both the serve and build configurations. The migration set the higher value to the build configuration and removed the option from the serve configuration.`,
|
||||
project: context.projectName,
|
||||
});
|
||||
}
|
||||
delete options.memoryLimit;
|
||||
} else if (key === 'standardRspackConfigFunction') {
|
||||
delete options.standardRspackConfigFunction;
|
||||
} else {
|
||||
pluginOptions[key] = value;
|
||||
delete options[key];
|
||||
}
|
||||
}
|
||||
|
||||
return pluginOptions;
|
||||
}
|
||||
|
||||
function updateRspackConfig(
|
||||
tree: Tree,
|
||||
rspackConfig: string,
|
||||
pluginOptions: ExtractedOptions
|
||||
): void {
|
||||
let sourceFile: ts.SourceFile;
|
||||
let rspackConfigText: string;
|
||||
|
||||
const updateSources = () => {
|
||||
rspackConfigText = tree.read(rspackConfig, 'utf-8');
|
||||
sourceFile = tsquery.ast(rspackConfigText);
|
||||
};
|
||||
updateSources();
|
||||
|
||||
setOptionsInRspackConfig(
|
||||
tree,
|
||||
rspackConfigText,
|
||||
sourceFile,
|
||||
rspackConfig,
|
||||
pluginOptions
|
||||
);
|
||||
updateSources();
|
||||
|
||||
setOptionsInNxRspackPlugin(tree, rspackConfigText, sourceFile, rspackConfig);
|
||||
updateSources();
|
||||
|
||||
setOptionsInLegacyNxPlugin(tree, rspackConfigText, sourceFile, rspackConfig);
|
||||
}
|
||||
|
||||
function setOptionsInRspackConfig(
|
||||
tree: Tree,
|
||||
text: string,
|
||||
sourceFile: ts.SourceFile,
|
||||
rspackConfig: string,
|
||||
pluginOptions: ExtractedOptions
|
||||
): void {
|
||||
const { default: defaultOptions, ...configurationOptions } = pluginOptions;
|
||||
|
||||
const optionsSelector =
|
||||
'VariableStatement:has(VariableDeclaration:has(Identifier[name=options]))';
|
||||
const optionsVariable = tsquery<ts.VariableStatement>(
|
||||
sourceFile,
|
||||
optionsSelector
|
||||
)[0];
|
||||
|
||||
// This is assuming the `options` variable will be available since it's what the
|
||||
// `convert-config-to-rspack-plugin` generates
|
||||
|
||||
let defaultOptionsObject: ts.ObjectLiteralExpression;
|
||||
const optionsObject = tsquery<ts.ObjectLiteralExpression>(
|
||||
optionsVariable,
|
||||
'ObjectLiteralExpression'
|
||||
)[0];
|
||||
if (optionsObject.properties.length === 0) {
|
||||
defaultOptionsObject = ts.factory.createObjectLiteralExpression(
|
||||
Object.entries(defaultOptions).map(([key, value]) =>
|
||||
toPropertyAssignment(key, value)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
// filter out the default options that are already in the options object
|
||||
// the existing options override the options from the project.json file
|
||||
const filteredDefaultOptions = Object.entries(defaultOptions).filter(
|
||||
([key]) =>
|
||||
!optionsObject.properties.some(
|
||||
(property) =>
|
||||
ts.isPropertyAssignment(property) &&
|
||||
ts.isIdentifier(property.name) &&
|
||||
property.name.text === key
|
||||
)
|
||||
);
|
||||
defaultOptionsObject = ts.factory.createObjectLiteralExpression([
|
||||
...optionsObject.properties,
|
||||
...filteredDefaultOptions.map(([key, value]) =>
|
||||
toPropertyAssignment(key, value)
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* const configValues = {
|
||||
* build: {
|
||||
* default: { ... },
|
||||
* configuration1: { ... },
|
||||
* configuration2: { ... },
|
||||
* }
|
||||
*/
|
||||
const configValuesVariable = ts.factory.createVariableStatement(
|
||||
undefined,
|
||||
ts.factory.createVariableDeclarationList(
|
||||
[
|
||||
ts.factory.createVariableDeclaration(
|
||||
'configValues',
|
||||
undefined,
|
||||
undefined,
|
||||
ts.factory.createObjectLiteralExpression(
|
||||
[
|
||||
ts.factory.createPropertyAssignment(
|
||||
'build',
|
||||
ts.factory.createObjectLiteralExpression([
|
||||
ts.factory.createPropertyAssignment(
|
||||
'default',
|
||||
defaultOptionsObject
|
||||
),
|
||||
...(configurationOptions
|
||||
? Object.entries(configurationOptions).map(([key, value]) =>
|
||||
ts.factory.createPropertyAssignment(
|
||||
key,
|
||||
ts.factory.createObjectLiteralExpression(
|
||||
Object.entries(value).map(([key, value]) =>
|
||||
toPropertyAssignment(key, value)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
: []),
|
||||
])
|
||||
),
|
||||
],
|
||||
true
|
||||
)
|
||||
),
|
||||
],
|
||||
ts.NodeFlags.Const
|
||||
)
|
||||
);
|
||||
|
||||
text = `${text.slice(0, optionsVariable.getStart())}
|
||||
// These options were migrated by @nx/rspack:convert-to-inferred from
|
||||
// the project.json file and merged with the options in this file
|
||||
${ts
|
||||
.createPrinter()
|
||||
.printNode(ts.EmitHint.Unspecified, configValuesVariable, sourceFile)}
|
||||
|
||||
// Determine the correct configValue to use based on the configuration
|
||||
const configuration = process.env.NX_TASK_TARGET_CONFIGURATION || 'default';
|
||||
|
||||
const buildOptions = {
|
||||
...configValues.build.default,
|
||||
...configValues.build[configuration],
|
||||
};${text.slice(optionsVariable.getEnd())}`;
|
||||
|
||||
// These are comments written by the `convert-config-to-rspack-plugin` that are no longer needed
|
||||
text = text
|
||||
.replace(
|
||||
`// This file was migrated using @nx/rspack:convert-config-to-rspack-plugin from your './rspack.config.old.js'`,
|
||||
''
|
||||
)
|
||||
.replace(
|
||||
'// Please check that the options here are correct as they were moved from the old rspack.config.js to this file.',
|
||||
''
|
||||
);
|
||||
|
||||
tree.write(rspackConfig, text);
|
||||
}
|
||||
|
||||
function setOptionsInNxRspackPlugin(
|
||||
tree: Tree,
|
||||
text: string,
|
||||
sourceFile: ts.SourceFile,
|
||||
rspackConfig: string
|
||||
): void {
|
||||
const nxAppRspackPluginSelector =
|
||||
'PropertyAssignment:has(Identifier[name=plugins]) NewExpression:has(Identifier[name=NxAppRspackPlugin])';
|
||||
const nxAppRspackPlugin = tsquery<ts.NewExpression>(
|
||||
sourceFile,
|
||||
nxAppRspackPluginSelector
|
||||
)[0];
|
||||
|
||||
// the NxAppRspackPlugin must exists, otherwise, the migration doesn't run and we wouldn't reach this point
|
||||
const updatedNxAppRspackPlugin = ts.factory.updateNewExpression(
|
||||
nxAppRspackPlugin,
|
||||
nxAppRspackPlugin.expression,
|
||||
undefined,
|
||||
[ts.factory.createIdentifier('buildOptions')]
|
||||
);
|
||||
|
||||
text = `${text.slice(0, nxAppRspackPlugin.getStart())}${ts
|
||||
.createPrinter()
|
||||
.printNode(
|
||||
ts.EmitHint.Unspecified,
|
||||
updatedNxAppRspackPlugin,
|
||||
sourceFile
|
||||
)}${text.slice(nxAppRspackPlugin.getEnd())}`;
|
||||
|
||||
tree.write(rspackConfig, text);
|
||||
}
|
||||
|
||||
function setOptionsInLegacyNxPlugin(
|
||||
tree: Tree,
|
||||
text: string,
|
||||
sourceFile: ts.SourceFile,
|
||||
rspackConfig: string
|
||||
): void {
|
||||
const legacyNxPluginSelector =
|
||||
'AwaitExpression CallExpression:has(Identifier[name=useLegacyNxPlugin])';
|
||||
const legacyNxPlugin = tsquery<ts.CallExpression>(
|
||||
sourceFile,
|
||||
legacyNxPluginSelector
|
||||
)[0];
|
||||
|
||||
// we're assuming the `useLegacyNxPlugin` function is being called since it's what the `convert-config-to-rspack-plugin` generates
|
||||
// we've already "ensured" that the `convert-config-to-rspack-plugin` was run by checking for the `NxAppRspackPlugin` in the project validation
|
||||
const updatedLegacyNxPlugin = ts.factory.updateCallExpression(
|
||||
legacyNxPlugin,
|
||||
legacyNxPlugin.expression,
|
||||
undefined,
|
||||
[legacyNxPlugin.arguments[0], ts.factory.createIdentifier('buildOptions')]
|
||||
);
|
||||
|
||||
text = `${text.slice(0, legacyNxPlugin.getStart())}${ts
|
||||
.createPrinter()
|
||||
.printNode(
|
||||
ts.EmitHint.Unspecified,
|
||||
updatedLegacyNxPlugin,
|
||||
sourceFile
|
||||
)}${text.slice(legacyNxPlugin.getEnd())}`;
|
||||
|
||||
tree.write(rspackConfig, text);
|
||||
}
|
||||
|
||||
function getMemoryLimitFromServeTarget(
|
||||
context: TransformerContext,
|
||||
configName: string | undefined
|
||||
): number | undefined {
|
||||
const { targets } = context.projectGraph.nodes[context.projectName].data;
|
||||
|
||||
const serveTarget = Object.values(targets).find(
|
||||
(target) =>
|
||||
target.executor === '@nx/rspack:dev-server' ||
|
||||
target.executor === '@nrwl/web:dev-server'
|
||||
);
|
||||
|
||||
if (!serveTarget) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (configName && serveTarget.configurations?.[configName]) {
|
||||
return (
|
||||
serveTarget.configurations[configName].options?.memoryLimit ??
|
||||
serveTarget.options?.memoryLimit
|
||||
);
|
||||
}
|
||||
|
||||
return serveTarget.options?.memoryLimit;
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
export * from './build-post-target-transformer';
|
||||
export * from './serve-post-target-transformer';
|
||||
export * from './types';
|
||||
@ -0,0 +1,376 @@
|
||||
import {
|
||||
parseTargetString,
|
||||
readJson,
|
||||
readTargetOptions,
|
||||
type ExecutorContext,
|
||||
type ProjectsConfigurations,
|
||||
type TargetConfiguration,
|
||||
type Tree,
|
||||
} from '@nx/devkit';
|
||||
import {
|
||||
processTargetOutputs,
|
||||
toProjectRelativePath,
|
||||
} from '@nx/devkit/src/generators/plugin-migrations/plugin-migration-utils';
|
||||
import { tsquery } from '@phenomnomnominal/tsquery';
|
||||
import { basename, resolve } from 'path';
|
||||
import * as ts from 'typescript';
|
||||
import type { RspackOptionsNormalized } from '@rspack/core';
|
||||
import { buildServePath } from '../../../executors/dev-server/lib/serve-path';
|
||||
import type { DevServerExecutorSchema as DevServerExecutorOptions } from '../../../executors/dev-server/schema';
|
||||
import { toPropertyAssignment } from './ast';
|
||||
import type { MigrationContext, TransformerContext } from './types';
|
||||
|
||||
export function servePostTargetTransformerFactory(
|
||||
migrationContext: MigrationContext
|
||||
) {
|
||||
return async function servePostTargetTransformer(
|
||||
target: TargetConfiguration,
|
||||
tree: Tree,
|
||||
projectDetails: { projectName: string; root: string },
|
||||
inferredTarget: TargetConfiguration
|
||||
): Promise<TargetConfiguration> {
|
||||
const context: TransformerContext = {
|
||||
...migrationContext,
|
||||
projectName: projectDetails.projectName,
|
||||
projectRoot: projectDetails.root,
|
||||
};
|
||||
|
||||
const { devServerOptions, rspackConfigPath } = await processOptions(
|
||||
tree,
|
||||
target,
|
||||
context
|
||||
);
|
||||
|
||||
updateRspackConfig(tree, rspackConfigPath, devServerOptions, context);
|
||||
|
||||
if (target.outputs) {
|
||||
processTargetOutputs(target, [], inferredTarget, {
|
||||
projectName: projectDetails.projectName,
|
||||
projectRoot: projectDetails.root,
|
||||
});
|
||||
}
|
||||
|
||||
return target;
|
||||
};
|
||||
}
|
||||
|
||||
type RspackConfigDevServerOptions = RspackOptionsNormalized['devServer'];
|
||||
type ExtractedOptions = {
|
||||
default: RspackConfigDevServerOptions;
|
||||
[configName: string]: RspackConfigDevServerOptions;
|
||||
};
|
||||
|
||||
async function processOptions(
|
||||
tree: Tree,
|
||||
target: TargetConfiguration<DevServerExecutorOptions>,
|
||||
context: TransformerContext
|
||||
): Promise<{
|
||||
devServerOptions: ExtractedOptions;
|
||||
rspackConfigPath: string;
|
||||
}> {
|
||||
const executorContext = {
|
||||
cwd: process.cwd(),
|
||||
nxJsonConfiguration: readJson(tree, 'nx.json'),
|
||||
projectGraph: context.projectGraph,
|
||||
projectName: context.projectName,
|
||||
projectsConfigurations: Object.entries(context.projectGraph.nodes).reduce(
|
||||
(acc, [projectName, project]) => {
|
||||
acc.projects[projectName] = project.data;
|
||||
return acc;
|
||||
},
|
||||
{ version: 1, projects: {} } as ProjectsConfigurations
|
||||
),
|
||||
root: context.workspaceRoot,
|
||||
} as ExecutorContext;
|
||||
const buildTarget = parseTargetString(
|
||||
target.options.buildTarget,
|
||||
executorContext
|
||||
);
|
||||
const buildOptions = readTargetOptions(buildTarget, executorContext);
|
||||
|
||||
// it must exist, we validated it in the project filter
|
||||
const rspackConfigPath = buildOptions.rspackConfig;
|
||||
|
||||
const defaultOptions = extractDevServerOptions(target.options, context);
|
||||
applyDefaults(defaultOptions, buildOptions);
|
||||
const devServerOptions: ExtractedOptions = {
|
||||
default: defaultOptions,
|
||||
};
|
||||
|
||||
if (target.configurations && Object.keys(target.configurations).length) {
|
||||
for (const [configName, config] of Object.entries(target.configurations)) {
|
||||
devServerOptions[configName] = extractDevServerOptions(config, context);
|
||||
}
|
||||
}
|
||||
|
||||
return { devServerOptions, rspackConfigPath: rspackConfigPath };
|
||||
}
|
||||
|
||||
function extractDevServerOptions(
|
||||
options: DevServerExecutorOptions,
|
||||
context: TransformerContext
|
||||
): RspackConfigDevServerOptions {
|
||||
const devServerOptions: RspackConfigDevServerOptions = {};
|
||||
|
||||
for (const [key, value] of Object.entries(options)) {
|
||||
if (key === 'ssl' || key === 'sslCert' || key === 'sslKey') {
|
||||
if (key === 'ssl' || 'ssl' in options) {
|
||||
if (options.ssl) {
|
||||
devServerOptions.server = { type: 'https' };
|
||||
|
||||
if (options.sslCert && options.sslKey) {
|
||||
devServerOptions.server.options = {};
|
||||
devServerOptions.server.options.cert = toProjectRelativePath(
|
||||
options.sslCert,
|
||||
context.projectRoot
|
||||
);
|
||||
devServerOptions.server.options.key = toProjectRelativePath(
|
||||
options.sslKey,
|
||||
context.projectRoot
|
||||
);
|
||||
} else if (options.sslCert) {
|
||||
context.logger.addLog({
|
||||
executorName: '@nx/rspack:dev-server',
|
||||
log: 'The "sslCert" option was set but "sslKey" was missing and "ssl" was set to "true". This means that "sslCert" was ignored by the executor. It has been removed from the options.',
|
||||
project: context.projectName,
|
||||
});
|
||||
} else if (options.sslKey) {
|
||||
context.logger.addLog({
|
||||
executorName: '@nx/rspack:dev-server',
|
||||
log: 'The "sslKey" option was set but "sslCert" was missing and "ssl" was set to "true". This means that "sslKey" was ignored by the executor. It has been removed from the options.',
|
||||
project: context.projectName,
|
||||
});
|
||||
}
|
||||
} else if (options.sslCert || options.sslKey) {
|
||||
context.logger.addLog({
|
||||
executorName: '@nx/rspack:dev-server',
|
||||
log: 'The "sslCert" and/or "sslKey" were set with "ssl" set to "false". This means they were ignored by the executor. They have been removed from the options.',
|
||||
project: context.projectName,
|
||||
});
|
||||
}
|
||||
delete options.ssl;
|
||||
delete options.sslCert;
|
||||
delete options.sslKey;
|
||||
} else if (options.sslCert || options.sslKey) {
|
||||
context.logger.addLog({
|
||||
executorName: '@nx/rspack:dev-server',
|
||||
log: 'The "sslCert" and/or "sslKey" were set but the "ssl" was not set. This means they were ignored by the executor. They have been removed from the options.',
|
||||
project: context.projectName,
|
||||
});
|
||||
delete options.sslCert;
|
||||
delete options.sslKey;
|
||||
}
|
||||
} else if (key === 'buildTarget') {
|
||||
delete options.buildTarget;
|
||||
} else {
|
||||
devServerOptions[key] = value;
|
||||
delete options[key];
|
||||
}
|
||||
}
|
||||
|
||||
return devServerOptions;
|
||||
}
|
||||
|
||||
function applyDefaults(
|
||||
options: RspackConfigDevServerOptions,
|
||||
buildOptions: any
|
||||
) {
|
||||
if (options.port === undefined) {
|
||||
options.port = 4200;
|
||||
}
|
||||
|
||||
options.headers = { 'Access-Control-Allow-Origin': '*' };
|
||||
|
||||
const servePath = buildServePath(buildOptions);
|
||||
options.historyApiFallback = {
|
||||
index: buildOptions.index && `${servePath}${basename(buildOptions.index)}`,
|
||||
disableDotRule: true,
|
||||
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
|
||||
};
|
||||
}
|
||||
|
||||
function getProxyConfig(root: string, proxyConfig: string) {
|
||||
const proxyPath = resolve(root, proxyConfig);
|
||||
return require(proxyPath);
|
||||
}
|
||||
|
||||
function updateRspackConfig(
|
||||
tree: Tree,
|
||||
rspackConfigPath: string,
|
||||
devServerOptions: ExtractedOptions,
|
||||
context: TransformerContext
|
||||
): void {
|
||||
let sourceFile: ts.SourceFile;
|
||||
let rspackConfigText: string;
|
||||
|
||||
const updateSources = () => {
|
||||
rspackConfigText = tree.read(rspackConfigPath, 'utf-8');
|
||||
sourceFile = tsquery.ast(rspackConfigText);
|
||||
};
|
||||
updateSources();
|
||||
|
||||
setOptionsInRspackConfig(
|
||||
tree,
|
||||
rspackConfigText,
|
||||
sourceFile,
|
||||
rspackConfigPath,
|
||||
devServerOptions
|
||||
);
|
||||
updateSources();
|
||||
|
||||
setDevServerOptionsInRspackConfig(
|
||||
tree,
|
||||
rspackConfigText,
|
||||
sourceFile,
|
||||
rspackConfigPath,
|
||||
context
|
||||
);
|
||||
}
|
||||
|
||||
function setOptionsInRspackConfig(
|
||||
tree: Tree,
|
||||
text: string,
|
||||
sourceFile: ts.SourceFile,
|
||||
rspackConfigPath: string,
|
||||
devServerOptions: ExtractedOptions
|
||||
) {
|
||||
const { default: defaultOptions, ...configurationOptions } = devServerOptions;
|
||||
|
||||
const configValuesSelector =
|
||||
'VariableDeclaration:has(Identifier[name=configValues]) ObjectLiteralExpression';
|
||||
const configValuesObject = tsquery<ts.ObjectLiteralExpression>(
|
||||
sourceFile,
|
||||
configValuesSelector
|
||||
)[0];
|
||||
|
||||
// configValues must exist at this point, we added it when processing the build target
|
||||
|
||||
/**
|
||||
* const configValues = {
|
||||
* ...
|
||||
* serve: {
|
||||
* default: { ... },
|
||||
* configuration1: { ... },
|
||||
* ...
|
||||
* },
|
||||
*/
|
||||
const updatedConfigValuesObject = ts.factory.updateObjectLiteralExpression(
|
||||
configValuesObject,
|
||||
[
|
||||
...configValuesObject.properties,
|
||||
ts.factory.createPropertyAssignment(
|
||||
'serve',
|
||||
ts.factory.createObjectLiteralExpression([
|
||||
ts.factory.createPropertyAssignment(
|
||||
'default',
|
||||
ts.factory.createObjectLiteralExpression(
|
||||
Object.entries(defaultOptions).map(([key, value]) =>
|
||||
toPropertyAssignment(key, value)
|
||||
)
|
||||
)
|
||||
),
|
||||
...(configurationOptions
|
||||
? Object.entries(configurationOptions).map(([key, value]) =>
|
||||
ts.factory.createPropertyAssignment(
|
||||
key,
|
||||
ts.factory.createObjectLiteralExpression(
|
||||
Object.entries(value).map(([key, value]) =>
|
||||
toPropertyAssignment(key, value)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
: []),
|
||||
])
|
||||
),
|
||||
]
|
||||
);
|
||||
|
||||
text = `${text.slice(0, configValuesObject.getStart())}${ts
|
||||
.createPrinter()
|
||||
.printNode(
|
||||
ts.EmitHint.Unspecified,
|
||||
updatedConfigValuesObject,
|
||||
sourceFile
|
||||
)}${text.slice(configValuesObject.getEnd())}`;
|
||||
|
||||
tree.write(rspackConfigPath, text);
|
||||
|
||||
sourceFile = tsquery.ast(text);
|
||||
const buildOptionsSelector =
|
||||
'VariableStatement:has(VariableDeclaration:has(Identifier[name=buildOptions]))';
|
||||
const buildOptionsStatement = tsquery<ts.VariableStatement>(
|
||||
sourceFile,
|
||||
buildOptionsSelector
|
||||
)[0];
|
||||
|
||||
text = `${text.slice(0, buildOptionsStatement.getEnd())}
|
||||
const devServerOptions = {
|
||||
...configValues.serve.default,
|
||||
...configValues.serve[configuration],
|
||||
};${text.slice(buildOptionsStatement.getEnd())}`;
|
||||
|
||||
tree.write(rspackConfigPath, text);
|
||||
}
|
||||
|
||||
function setDevServerOptionsInRspackConfig(
|
||||
tree: Tree,
|
||||
text: string,
|
||||
sourceFile: ts.SourceFile,
|
||||
rspackConfigPath: string,
|
||||
context: TransformerContext
|
||||
) {
|
||||
const rspackConfigDevServerSelector =
|
||||
'ObjectLiteralExpression > PropertyAssignment:has(Identifier[name=devServer])';
|
||||
const rspackConfigDevServer = tsquery<ts.PropertyAssignment>(
|
||||
sourceFile,
|
||||
rspackConfigDevServerSelector
|
||||
)[0];
|
||||
if (rspackConfigDevServer) {
|
||||
context.logger.addLog({
|
||||
executorName: '@nx/rspack:dev-server',
|
||||
log: `The "devServer" option is already set in the rspack config. The migration doesn't support updating it. Please review it and make any necessary changes manually.`,
|
||||
project: context.projectName,
|
||||
});
|
||||
|
||||
text = `${text.slice(
|
||||
0,
|
||||
rspackConfigDevServer.getStart()
|
||||
)}// This is the untouched "devServer" option from the original rspack config. Please review it and make any necessary changes manually.
|
||||
${text.slice(rspackConfigDevServer.getStart())}`;
|
||||
|
||||
tree.write(rspackConfigPath, text);
|
||||
|
||||
// If the devServer property already exists, we don't know how to merge the
|
||||
// options, so we leave it as is.
|
||||
return;
|
||||
}
|
||||
|
||||
const rspackConfigSelector =
|
||||
'ObjectLiteralExpression:has(PropertyAssignment:has(Identifier[name=plugins]))';
|
||||
const rspackConfig = tsquery<ts.ObjectLiteralExpression>(
|
||||
sourceFile,
|
||||
rspackConfigSelector
|
||||
)[0];
|
||||
|
||||
const updatedRspackConfig = ts.factory.updateObjectLiteralExpression(
|
||||
rspackConfig,
|
||||
[
|
||||
ts.factory.createPropertyAssignment(
|
||||
'devServer',
|
||||
ts.factory.createIdentifier('devServerOptions')
|
||||
),
|
||||
...rspackConfig.properties,
|
||||
]
|
||||
);
|
||||
|
||||
text = `${text.slice(0, rspackConfig.getStart())}${ts
|
||||
.createPrinter()
|
||||
.printNode(
|
||||
ts.EmitHint.Unspecified,
|
||||
updatedRspackConfig,
|
||||
sourceFile
|
||||
)}${text.slice(rspackConfig.getEnd())}`;
|
||||
|
||||
tree.write(rspackConfigPath, text);
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
import type { ProjectGraph } from '@nx/devkit';
|
||||
import type { AggregatedLog } from '@nx/devkit/src/generators/plugin-migrations/aggregate-log-util';
|
||||
|
||||
export type MigrationContext = {
|
||||
logger: AggregatedLog;
|
||||
projectGraph: ProjectGraph;
|
||||
workspaceRoot: string;
|
||||
};
|
||||
|
||||
export type TransformerContext = MigrationContext & {
|
||||
projectName: string;
|
||||
projectRoot: string;
|
||||
};
|
||||
@ -4,3 +4,4 @@ export * from './utils/config';
|
||||
export * from './utils/with-nx';
|
||||
export * from './utils/with-react';
|
||||
export * from './utils/with-web';
|
||||
export * from './plugins/use-legacy-nx-plugin/use-legacy-nx-plugin';
|
||||
|
||||
@ -6,7 +6,6 @@ import type {
|
||||
import { normalizeOptions } from '../utils/plugins/normalize-options';
|
||||
import { applyBaseConfig } from '../utils/apply-base-config';
|
||||
import { applyWebConfig } from '../utils/apply-web-config';
|
||||
import { deleteOutputDir } from '../utils/delete-output-path';
|
||||
|
||||
/**
|
||||
* This plugin provides features to build Node and Web applications.
|
||||
@ -48,9 +47,5 @@ export class NxAppRspackPlugin {
|
||||
useNormalizedEntry: true,
|
||||
});
|
||||
}
|
||||
|
||||
if (this.options.deleteOutputPath) {
|
||||
deleteOutputDir(this.options.root, this.options.outputPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
import {
|
||||
type ExecutorContext,
|
||||
readCachedProjectGraph,
|
||||
readProjectsConfigurationFromProjectGraph,
|
||||
workspaceRoot,
|
||||
} from '@nx/devkit';
|
||||
import type { NxRspackExecutionContext } from '../../utils/config';
|
||||
import type { NxAppRspackPluginOptions } from '../utils/models';
|
||||
import type { Compiler, Configuration } from '@rspack/core';
|
||||
import { normalizeOptions } from '../utils/plugins/normalize-options';
|
||||
import { readNxJson } from 'nx/src/config/configuration';
|
||||
|
||||
/**
|
||||
* This function is used to wrap the legacy plugin function to be used with the `composePlugins` function.
|
||||
* Initially the rspack config would be passed to the legacy plugin function and the options would be passed as a second argument.
|
||||
* example:
|
||||
* module.exports = composePlugins(
|
||||
withNx(),
|
||||
(config) => {
|
||||
return config;
|
||||
}
|
||||
);
|
||||
|
||||
Since composePlugins is async, this function is used to wrap the legacy plugin function to be async.
|
||||
Using the nxUseLegacyPlugin function, the first argument is the legacy plugin function and the second argument is the options.
|
||||
The context options are created and passed to the legacy plugin function.
|
||||
|
||||
module.exports = async () => ({
|
||||
plugins: [
|
||||
...otherPlugins,
|
||||
await nxUseLegacyPlugin(require({path}), options),
|
||||
],
|
||||
});
|
||||
* @param fn The legacy plugin function usually from `combinedPlugins`
|
||||
* @param executorOptions The options passed usually inside the executor or the config file
|
||||
* @returns Rspack configuration
|
||||
*/
|
||||
export async function useLegacyNxPlugin(
|
||||
fn: (
|
||||
config: Configuration,
|
||||
ctx: NxRspackExecutionContext
|
||||
) => Promise<Configuration>,
|
||||
executorOptions: NxAppRspackPluginOptions
|
||||
) {
|
||||
if (global.NX_GRAPH_CREATION) {
|
||||
return;
|
||||
}
|
||||
const options = normalizeOptions(executorOptions);
|
||||
|
||||
const projectGraph = readCachedProjectGraph();
|
||||
const projectName = process.env.NX_TASK_TARGET_PROJECT;
|
||||
const project = projectGraph.nodes[projectName];
|
||||
const targetName = process.env.NX_TASK_TARGET_TARGET;
|
||||
|
||||
const context: ExecutorContext = {
|
||||
cwd: process.cwd(),
|
||||
isVerbose: process.env.NX_VERBOSE_LOGGING === 'true',
|
||||
root: workspaceRoot,
|
||||
projectGraph,
|
||||
projectsConfigurations:
|
||||
readProjectsConfigurationFromProjectGraph(projectGraph),
|
||||
nxJsonConfiguration: readNxJson(workspaceRoot),
|
||||
target: project.data.targets[targetName],
|
||||
targetName: targetName,
|
||||
projectName: projectName,
|
||||
};
|
||||
|
||||
const configuration = process.env.NX_TASK_TARGET_CONFIGURATION;
|
||||
const ctx: NxRspackExecutionContext = {
|
||||
context,
|
||||
options: options as NxRspackExecutionContext['options'],
|
||||
configuration,
|
||||
};
|
||||
return {
|
||||
apply(compiler: Compiler) {
|
||||
compiler.hooks.beforeCompile.tapPromise('NxLegacyAsyncPlugin', () => {
|
||||
return new Promise<void>((resolve) => {
|
||||
fn(compiler.options as Configuration, ctx).then((updated) => {
|
||||
// Merge options back shallowly since it's a fully functional configuration.
|
||||
// Most likely, the user modified the config in place, but this guarantees that updates are applied if users did something like:
|
||||
// `return { ...config, plugins: [...config.plugins, new MyPlugin()] }`
|
||||
Object.assign(compiler.options, updated);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -112,6 +112,7 @@ function applyNxIndependentConfig(
|
||||
hashFunction: config.output?.hashFunction ?? 'xxhash64',
|
||||
// Disabled for performance
|
||||
pathinfo: config.output?.pathinfo ?? false,
|
||||
clean: options.deleteOutputPath,
|
||||
};
|
||||
|
||||
config.watch = options.watch;
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
import { rmSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
|
||||
/**
|
||||
* Delete an output directory, but error out if it's the root of the project.
|
||||
*/
|
||||
export function deleteOutputDir(root: string, outputPath: string) {
|
||||
const resolvedOutputPath = resolve(root, outputPath);
|
||||
if (resolvedOutputPath === root) {
|
||||
throw new Error('Output path MUST not be project root directory!');
|
||||
}
|
||||
|
||||
rmSync(resolvedOutputPath, { recursive: true, force: true });
|
||||
}
|
||||
@ -17,7 +17,9 @@ export async function createCompiler(
|
||||
): Promise<Compiler | MultiCompiler> {
|
||||
const config = await getRspackConfigs(options, context);
|
||||
|
||||
validateConfig(config);
|
||||
if (!options.standardRspackConfigFunction) {
|
||||
validateConfig(config);
|
||||
}
|
||||
|
||||
return rspack(config);
|
||||
}
|
||||
|
||||
416
pnpm-lock.yaml
generated
416
pnpm-lock.yaml
generated
@ -340,6 +340,9 @@ importers:
|
||||
'@nx/react':
|
||||
specifier: 20.2.0-beta.2
|
||||
version: 20.2.0-beta.2(@babel/traverse@7.25.6)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@types/node@20.16.10)(@zkochan/js-yaml@0.0.7)(eslint@8.57.0)(nx@20.2.0-beta.2(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.4)(verdaccio@5.32.2(encoding@0.1.13)(typanion@3.14.0))(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
'@nx/rspack':
|
||||
specifier: 20.2.0-beta.2
|
||||
version: 20.2.0-beta.2(qqfm4c7f7lave6shde5djyndcy)
|
||||
'@nx/storybook':
|
||||
specifier: 20.2.0-beta.2
|
||||
version: 20.2.0-beta.2(@babel/traverse@7.25.6)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@types/node@20.16.10)(@zkochan/js-yaml@0.0.7)(cypress@13.13.0)(eslint@8.57.0)(nx@20.2.0-beta.2(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.5.4)(verdaccio@5.32.2(encoding@0.1.13)(typanion@3.14.0))
|
||||
@ -1011,7 +1014,7 @@ importers:
|
||||
version: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)
|
||||
webpack-dev-server:
|
||||
specifier: 5.0.4
|
||||
version: 5.0.4(webpack-cli@5.1.4)(webpack@5.88.0)
|
||||
version: 5.0.4(webpack-cli@5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0))(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
webpack-merge:
|
||||
specifier: ^5.8.0
|
||||
version: 5.10.0
|
||||
@ -3711,12 +3714,21 @@ packages:
|
||||
'@mediapipe/tasks-vision@0.10.8':
|
||||
resolution: {integrity: sha512-Rp7ll8BHrKB3wXaRFKhrltwZl1CiXGdibPxuWXvqGnKTnv8fqa/nvftYNuSbf+pbJWKYCXdBtYTITdAUTGGh0Q==}
|
||||
|
||||
'@module-federation/bridge-react-webpack-plugin@0.6.11':
|
||||
resolution: {integrity: sha512-VUD7g1RIom7KtQaO7bcPd7sCzsO6jeRVwOSx5smFr9K6FpkWeiwWtJmhyuhc0uzstzVdkOk77pqMP0xmrXpV+g==}
|
||||
|
||||
'@module-federation/bridge-react-webpack-plugin@0.6.9':
|
||||
resolution: {integrity: sha512-KXTPO0vkrtHEIcthU3TIQEkPxoytcmdyNXRwOojZEVQhqEefykAek48ndFiVTmyOu2LW2EuzP49Le8zY7nESWQ==}
|
||||
|
||||
'@module-federation/bridge-react-webpack-plugin@0.7.6':
|
||||
resolution: {integrity: sha512-eD1JZDQ+h5WLdA58MmAE1DzLwvFaGJeeam3Tswc/sEUb4QGT86X4Fme+dMTBRYRoAq/tRYql3DlVTFhdmrUVzg==}
|
||||
|
||||
'@module-federation/data-prefetch@0.6.11':
|
||||
resolution: {integrity: sha512-cNCk1YJJal2RvMKu2S413GVHlEUMYbzzzJbWBzZXwcW3DupOeLGs2ENvl32whAvF1RyOlf6LRYcypqE22LUxBQ==}
|
||||
peerDependencies:
|
||||
react: '>=16.9.0'
|
||||
react-dom: '>=16.9.0'
|
||||
|
||||
'@module-federation/data-prefetch@0.6.9':
|
||||
resolution: {integrity: sha512-rpHxfHNkIiPA441GzXI6TMYjSrUjRWDwxJTvRQopX/P0jK5vKtNwT1UBTNF2DJkbtO1idljfhbrIufEg0OY72w==}
|
||||
peerDependencies:
|
||||
@ -3729,6 +3741,15 @@ packages:
|
||||
react: '>=16.9.0'
|
||||
react-dom: '>=16.9.0'
|
||||
|
||||
'@module-federation/dts-plugin@0.6.11':
|
||||
resolution: {integrity: sha512-BRKfLuDuFou/Mg3MlatZN67HSIJ/M4t7mpxeYl93bu7q+87zzD+wUSrY+I+pGz+VEmN/LJ5TujMW4jS3XOP2Pw==}
|
||||
peerDependencies:
|
||||
typescript: ^4.9.0 || ^5.0.0
|
||||
vue-tsc: '>=1.0.24'
|
||||
peerDependenciesMeta:
|
||||
vue-tsc:
|
||||
optional: true
|
||||
|
||||
'@module-federation/dts-plugin@0.6.9':
|
||||
resolution: {integrity: sha512-uiMjjEFcMlOvRtNu8/tt7sJ5y7WTosTVym0V7lMQjgoeX0QesvZqRhgzw5gQcPcFvbk54RwTUI2rS8OEGScCFw==}
|
||||
peerDependencies:
|
||||
@ -3747,6 +3768,20 @@ packages:
|
||||
vue-tsc:
|
||||
optional: true
|
||||
|
||||
'@module-federation/enhanced@0.6.11':
|
||||
resolution: {integrity: sha512-billwprfdc/ehPFdwCNTdm0685pry0qvlhrT9UEYjqHDMHanXTWNQJJLqf5Tz8OzA2/ex6+y8yMcdeKJs+nXEQ==}
|
||||
peerDependencies:
|
||||
typescript: ^4.9.0 || ^5.0.0
|
||||
vue-tsc: '>=1.0.24'
|
||||
webpack: ^5.0.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
vue-tsc:
|
||||
optional: true
|
||||
webpack:
|
||||
optional: true
|
||||
|
||||
'@module-federation/enhanced@0.6.9':
|
||||
resolution: {integrity: sha512-4bEGQSE6zJ2FMdBTOrRiVjNNzWhUqzWEJGWbsr0bpLNAl4BVx2ah5MyKTrSYqaW//BRA2qc8rmrIreaIawr3kQ==}
|
||||
peerDependencies:
|
||||
@ -3778,18 +3813,50 @@ packages:
|
||||
'@module-federation/error-codes@0.7.6':
|
||||
resolution: {integrity: sha512-XVzX/sRFj1h5JvOOVMoFppxq0t1t3o/AlEICHgWX+dybIwJgz9g4gihZOWVZfz5/xsKGcUwdH5X7Z2nkuYhJEw==}
|
||||
|
||||
'@module-federation/managers@0.6.11':
|
||||
resolution: {integrity: sha512-HVw9eFTHCegRlWSmNbHXAnY19XHSj19RHHpjZ1Oo71DaHgjJAPJlg4izifcdWt0w+ObAQLOH1DacjYKMIT4W6Q==}
|
||||
|
||||
'@module-federation/managers@0.6.9':
|
||||
resolution: {integrity: sha512-q3AOQXcWWpdUZI1gDIi9j/UqcP+FJBYXj/e4pNp3QAteJwS/Ve9UP3y0hW27bIbAWZSSajWsYbf/+YLnktA/kQ==}
|
||||
|
||||
'@module-federation/managers@0.7.6':
|
||||
resolution: {integrity: sha512-NW0LJ6TL13oN004D9e50EalcGZyTYHHgyaeKOc90Omb/HMeHxjyhHx7wl1TLRwVN2E5Rk+IO0JrwgrdlNMfAzg==}
|
||||
|
||||
'@module-federation/manifest@0.6.11':
|
||||
resolution: {integrity: sha512-HLtGulXJQUdOAAXhkDhNOnTld1EsnjNr2GEscsKNmP42vEEqEm6A6jL8hdKS/hrDZJmPOps7XcEv426+jMTDpA==}
|
||||
|
||||
'@module-federation/manifest@0.6.9':
|
||||
resolution: {integrity: sha512-JMSPDpHODXOmTyJes8GJ950mbN7tqjQzqgFVUubDOVFOmlC0/MYaRzRPmkApz6d8nUfMbLZYzxNSaBHx8GP0/Q==}
|
||||
|
||||
'@module-federation/manifest@0.7.6':
|
||||
resolution: {integrity: sha512-xBrFwLjDMUjKRnp+P4X29ZNyhgXSsp+SfrBxVsKJpEESOHalDoNClbo6gXvZAvkBZyo9sY3SJhAwduDwNkg04w==}
|
||||
|
||||
'@module-federation/node@2.5.21':
|
||||
resolution: {integrity: sha512-RSSWlndPZtKOX0mmQkHUc4xmWl18oRZOV58S5Xm1X3YOSDxywLtOXcxaYRfUqufBGdEA+zeDaFryfE8feC61Qw==}
|
||||
peerDependencies:
|
||||
next: '*'
|
||||
react: ^16||^17||^18
|
||||
react-dom: ^16||^17||^18
|
||||
webpack: ^5.40.0
|
||||
peerDependenciesMeta:
|
||||
next:
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
react-dom:
|
||||
optional: true
|
||||
|
||||
'@module-federation/rspack@0.6.11':
|
||||
resolution: {integrity: sha512-l2AH5J1oDvChc61dOJTPBBiJGD+wwcqRVbbjTYTCtZdxFgY6uBhTj0zOLWaSLlXO5DNkr5PyuPH1HCfGWlDwPA==}
|
||||
peerDependencies:
|
||||
typescript: ^4.9.0 || ^5.0.0
|
||||
vue-tsc: '>=1.0.24'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
vue-tsc:
|
||||
optional: true
|
||||
|
||||
'@module-federation/rspack@0.6.9':
|
||||
resolution: {integrity: sha512-N5yBqN8ijSRZKd0kbIvpZNil0y8rFa8cREKI1QsW1+EYUKwOUBFwF55tFdTmNCKmpZqSEBtcNjRGZXknsYPQxg==}
|
||||
peerDependencies:
|
||||
@ -3815,6 +3882,9 @@ packages:
|
||||
'@module-federation/runtime-tools@0.5.1':
|
||||
resolution: {integrity: sha512-nfBedkoZ3/SWyO0hnmaxuz0R0iGPSikHZOAZ0N/dVSQaIzlffUo35B5nlC2wgWIc0JdMZfkwkjZRrnuuDIJbzg==}
|
||||
|
||||
'@module-federation/runtime-tools@0.6.11':
|
||||
resolution: {integrity: sha512-MGdCLaFfFyW6hTEaPKs8yEvOd9zvpaLADUL7WEaqWQ6XVt9GVATGDwA0muZT4+OFjtGsOgj5h5NGjZgIJxruSA==}
|
||||
|
||||
'@module-federation/runtime-tools@0.6.9':
|
||||
resolution: {integrity: sha512-AhsEBXo8IW1ATMKS1xfJaxBiHu9n5z6WUOAIWdPpWXXBJhTFgOs0K1xAod0xLJY4YH/B5cwEcHRPN3FEs2/0Ww==}
|
||||
|
||||
@ -3824,6 +3894,9 @@ packages:
|
||||
'@module-federation/runtime@0.5.1':
|
||||
resolution: {integrity: sha512-xgiMUWwGLWDrvZc9JibuEbXIbhXg6z2oUkemogSvQ4LKvrl/n0kbqP1Blk669mXzyWbqtSp6PpvNdwaE1aN5xQ==}
|
||||
|
||||
'@module-federation/runtime@0.6.11':
|
||||
resolution: {integrity: sha512-UTuavwCybLftAe4VT7cCqj+BVNlZwda/xmqIPAeYX14o7gkYFyA6zkxOQqfNCaDnTMR/KBk6EvE49yA6/ht9UQ==}
|
||||
|
||||
'@module-federation/runtime@0.6.9':
|
||||
resolution: {integrity: sha512-G1x+6jyW5sW1X+TtWaKigGhwqiHE8MESvi3ntE9ICxwELAGBonmsqDqnLSrdEy6poBKslvPANPJr0Nn9pvW9lg==}
|
||||
|
||||
@ -3833,21 +3906,45 @@ packages:
|
||||
'@module-federation/sdk@0.5.1':
|
||||
resolution: {integrity: sha512-exvchtjNURJJkpqjQ3/opdbfeT2wPKvrbnGnyRkrwW5o3FH1LaST1tkiNviT6OXTexGaVc2DahbdniQHVtQ7pA==}
|
||||
|
||||
'@module-federation/sdk@0.6.11':
|
||||
resolution: {integrity: sha512-Fj2ws9yL6mGAki9GdurcrIhdSg0L2Kfw7L6Dej/DidzAU4bwa3MT0s+87BPuOYFgm2UTMN3g+UrElC2NhsuulQ==}
|
||||
|
||||
'@module-federation/sdk@0.6.9':
|
||||
resolution: {integrity: sha512-xmTxb9LgncxPGsBrN6AT/+aHnFGv8swbeNl0PcSeVbXTGLu3Gp7j+5J+AhJoWNB++SLguRwBd8LjB1d8mNKLDg==}
|
||||
|
||||
'@module-federation/sdk@0.7.6':
|
||||
resolution: {integrity: sha512-MFE+RtsHnutZOCp2eKpa3A/yzZ8tOPmjX7QRdVnB2qqR9JA2SH3ZP5+cYq76tzFQZvU1BCWAQVNMvqGOW2yVZQ==}
|
||||
|
||||
'@module-federation/third-party-dts-extractor@0.6.11':
|
||||
resolution: {integrity: sha512-KEHF71/qmEhME1XK/0XpMHKaSRjwmINpul9iu5Z4UBNtoMIydq6SH41DsWF3HxAManhqe+ZwCxyoSn2Yxm5d0Q==}
|
||||
|
||||
'@module-federation/third-party-dts-extractor@0.6.9':
|
||||
resolution: {integrity: sha512-im00IQyX/siJz+SaAmJo6vGmMBig7UYzcrPD1N5NeiZonxdT1RZk9iXUP419UESgovYy4hM6w4qdCq6PMMl2bw==}
|
||||
|
||||
'@module-federation/third-party-dts-extractor@0.7.6':
|
||||
resolution: {integrity: sha512-JME76/rgr41AKXG6kUTQXdQJiMCypN3qHOgPv4VuIag10UdLo/0gdeN6PYronvYmvPOQMfYev80GcEwl4l531A==}
|
||||
|
||||
'@module-federation/utilities@3.1.17':
|
||||
resolution: {integrity: sha512-dmbLxZwgYgtTJ09HvFZCzAPgoRkAEjqQOEcuBZm/+GSHuAwZq6SMaOs7RdTHH0by7VvUm4O+iMQ7zMu/F4vuqw==}
|
||||
peerDependencies:
|
||||
next: '*'
|
||||
react: ^16 || ^17 || ^18
|
||||
react-dom: ^16 || ^17 || ^18
|
||||
webpack: ^5.40.0
|
||||
peerDependenciesMeta:
|
||||
next:
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
react-dom:
|
||||
optional: true
|
||||
|
||||
'@module-federation/webpack-bundler-runtime@0.5.1':
|
||||
resolution: {integrity: sha512-mMhRFH0k2VjwHt3Jol9JkUsmI/4XlrAoBG3E0o7HoyoPYv1UFOWyqAflfANcUPgbYpvqmyLzDcO+3IT36LXnrA==}
|
||||
|
||||
'@module-federation/webpack-bundler-runtime@0.6.11':
|
||||
resolution: {integrity: sha512-s9VtE+cthnCsutl0o48qBRaLP3oQGA1FESLG9dwIHpUN9G7zRtewf0HjlCFFZG3ORRyTKBiJUi5qDWt9ky7XwQ==}
|
||||
|
||||
'@module-federation/webpack-bundler-runtime@0.6.9':
|
||||
resolution: {integrity: sha512-ME1MjNT/a4MFI3HaJDM06olJ+/+H8lk4oDOdwwEZI2JSH3UoqCDrMcjSKCjBNMGzza57AowGobo1LHQeY8yZ8Q==}
|
||||
|
||||
@ -4974,6 +5071,12 @@ packages:
|
||||
'@nx/react@20.2.0-beta.2':
|
||||
resolution: {integrity: sha512-qFHJ72vbuOQ2NMOFtTmnPMRYQBCadWQDsfOycmXEYrTmoGHc30hMiBRo/nD+urHre7IWAi+rlwSeNV3fO4vGXw==}
|
||||
|
||||
'@nx/rspack@20.2.0-beta.2':
|
||||
resolution: {integrity: sha512-dBzne7y4GuQlA53aD2Rfpai/tmyWiY53EaB1dc3pwapNRY3srWlGVUa4GgiqjdDsBULvt10+AHn1P8qFjZ/MHQ==}
|
||||
peerDependencies:
|
||||
'@module-federation/enhanced': ~0.6.0
|
||||
'@module-federation/node': ~2.5.10
|
||||
|
||||
'@nx/storybook@20.2.0-beta.2':
|
||||
resolution: {integrity: sha512-yUkdQ6G0YOVmLvX03P03u+oR+ieJilb2xYDs+nYAegFykfjOK+DFBm6/jQct7TnkwUb322ACg7FCupBHCFzpsw==}
|
||||
|
||||
@ -20457,6 +20560,12 @@ snapshots:
|
||||
|
||||
'@mediapipe/tasks-vision@0.10.8': {}
|
||||
|
||||
'@module-federation/bridge-react-webpack-plugin@0.6.11':
|
||||
dependencies:
|
||||
'@module-federation/sdk': 0.6.11
|
||||
'@types/semver': 7.5.8
|
||||
semver: 7.6.3
|
||||
|
||||
'@module-federation/bridge-react-webpack-plugin@0.6.9':
|
||||
dependencies:
|
||||
'@module-federation/sdk': 0.6.9
|
||||
@ -20469,6 +20578,14 @@ snapshots:
|
||||
'@types/semver': 7.5.8
|
||||
semver: 7.6.3
|
||||
|
||||
'@module-federation/data-prefetch@0.6.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@module-federation/runtime': 0.6.11
|
||||
'@module-federation/sdk': 0.6.11
|
||||
fs-extra: 9.1.0
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@module-federation/data-prefetch@0.6.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@module-federation/runtime': 0.6.9
|
||||
@ -20485,6 +20602,30 @@ snapshots:
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@module-federation/dts-plugin@0.6.11(typescript@5.5.4)':
|
||||
dependencies:
|
||||
'@module-federation/managers': 0.6.11
|
||||
'@module-federation/sdk': 0.6.11
|
||||
'@module-federation/third-party-dts-extractor': 0.6.11
|
||||
adm-zip: 0.5.16
|
||||
ansi-colors: 4.1.3
|
||||
axios: 1.7.7
|
||||
chalk: 3.0.0
|
||||
fs-extra: 9.1.0
|
||||
isomorphic-ws: 5.0.0(ws@8.18.0)
|
||||
koa: 2.15.3
|
||||
lodash.clonedeepwith: 4.5.0
|
||||
log4js: 6.9.1
|
||||
node-schedule: 2.1.1
|
||||
rambda: 9.3.0
|
||||
typescript: 5.5.4
|
||||
ws: 8.18.0
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- debug
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
'@module-federation/dts-plugin@0.6.9(typescript@5.5.4)':
|
||||
dependencies:
|
||||
'@module-federation/managers': 0.6.9
|
||||
@ -20534,6 +20675,29 @@ snapshots:
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
'@module-federation/enhanced@0.6.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.4)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))':
|
||||
dependencies:
|
||||
'@module-federation/bridge-react-webpack-plugin': 0.6.11
|
||||
'@module-federation/data-prefetch': 0.6.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@module-federation/dts-plugin': 0.6.11(typescript@5.5.4)
|
||||
'@module-federation/managers': 0.6.11
|
||||
'@module-federation/manifest': 0.6.11(typescript@5.5.4)
|
||||
'@module-federation/rspack': 0.6.11(typescript@5.5.4)
|
||||
'@module-federation/runtime-tools': 0.6.11
|
||||
'@module-federation/sdk': 0.6.11
|
||||
btoa: 1.2.1
|
||||
upath: 2.0.1
|
||||
optionalDependencies:
|
||||
typescript: 5.5.4
|
||||
webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- debug
|
||||
- react
|
||||
- react-dom
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
'@module-federation/enhanced@0.6.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.4)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))':
|
||||
dependencies:
|
||||
'@module-federation/bridge-react-webpack-plugin': 0.6.9
|
||||
@ -20582,6 +20746,12 @@ snapshots:
|
||||
|
||||
'@module-federation/error-codes@0.7.6': {}
|
||||
|
||||
'@module-federation/managers@0.6.11':
|
||||
dependencies:
|
||||
'@module-federation/sdk': 0.6.11
|
||||
find-pkg: 2.0.0
|
||||
fs-extra: 9.1.0
|
||||
|
||||
'@module-federation/managers@0.6.9':
|
||||
dependencies:
|
||||
'@module-federation/sdk': 0.6.9
|
||||
@ -20594,6 +20764,21 @@ snapshots:
|
||||
find-pkg: 2.0.0
|
||||
fs-extra: 9.1.0
|
||||
|
||||
'@module-federation/manifest@0.6.11(typescript@5.5.4)':
|
||||
dependencies:
|
||||
'@module-federation/dts-plugin': 0.6.11(typescript@5.5.4)
|
||||
'@module-federation/managers': 0.6.11
|
||||
'@module-federation/sdk': 0.6.11
|
||||
chalk: 3.0.0
|
||||
find-pkg: 2.0.0
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- debug
|
||||
- supports-color
|
||||
- typescript
|
||||
- utf-8-validate
|
||||
- vue-tsc
|
||||
|
||||
'@module-federation/manifest@0.6.9(typescript@5.5.4)':
|
||||
dependencies:
|
||||
'@module-federation/dts-plugin': 0.6.9(typescript@5.5.4)
|
||||
@ -20624,6 +20809,44 @@ snapshots:
|
||||
- utf-8-validate
|
||||
- vue-tsc
|
||||
|
||||
'@module-federation/node@2.5.21(next@14.2.16(@babel/core@7.25.2)(@playwright/test@1.47.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.4)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))':
|
||||
dependencies:
|
||||
'@module-federation/enhanced': 0.6.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.4)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
'@module-federation/runtime': 0.6.11
|
||||
'@module-federation/sdk': 0.6.11
|
||||
'@module-federation/utilities': 3.1.17(next@14.2.16(@babel/core@7.25.2)(@playwright/test@1.47.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
btoa: 1.2.1
|
||||
encoding: 0.1.13
|
||||
node-fetch: 2.7.0(encoding@0.1.13)
|
||||
webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)
|
||||
optionalDependencies:
|
||||
next: 14.2.16(@babel/core@7.25.2)(@playwright/test@1.47.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- debug
|
||||
- supports-color
|
||||
- typescript
|
||||
- utf-8-validate
|
||||
- vue-tsc
|
||||
|
||||
'@module-federation/rspack@0.6.11(typescript@5.5.4)':
|
||||
dependencies:
|
||||
'@module-federation/bridge-react-webpack-plugin': 0.6.11
|
||||
'@module-federation/dts-plugin': 0.6.11(typescript@5.5.4)
|
||||
'@module-federation/managers': 0.6.11
|
||||
'@module-federation/manifest': 0.6.11(typescript@5.5.4)
|
||||
'@module-federation/runtime-tools': 0.6.11
|
||||
'@module-federation/sdk': 0.6.11
|
||||
optionalDependencies:
|
||||
typescript: 5.5.4
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- debug
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
'@module-federation/rspack@0.6.9(typescript@5.5.4)':
|
||||
dependencies:
|
||||
'@module-federation/bridge-react-webpack-plugin': 0.6.9
|
||||
@ -20661,6 +20884,11 @@ snapshots:
|
||||
'@module-federation/runtime': 0.5.1
|
||||
'@module-federation/webpack-bundler-runtime': 0.5.1
|
||||
|
||||
'@module-federation/runtime-tools@0.6.11':
|
||||
dependencies:
|
||||
'@module-federation/runtime': 0.6.11
|
||||
'@module-federation/webpack-bundler-runtime': 0.6.11
|
||||
|
||||
'@module-federation/runtime-tools@0.6.9':
|
||||
dependencies:
|
||||
'@module-federation/runtime': 0.6.9
|
||||
@ -20675,6 +20903,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@module-federation/sdk': 0.5.1
|
||||
|
||||
'@module-federation/runtime@0.6.11':
|
||||
dependencies:
|
||||
'@module-federation/sdk': 0.6.11
|
||||
|
||||
'@module-federation/runtime@0.6.9':
|
||||
dependencies:
|
||||
'@module-federation/sdk': 0.6.9
|
||||
@ -20686,12 +20918,20 @@ snapshots:
|
||||
|
||||
'@module-federation/sdk@0.5.1': {}
|
||||
|
||||
'@module-federation/sdk@0.6.11': {}
|
||||
|
||||
'@module-federation/sdk@0.6.9': {}
|
||||
|
||||
'@module-federation/sdk@0.7.6':
|
||||
dependencies:
|
||||
isomorphic-rslog: 0.0.6
|
||||
|
||||
'@module-federation/third-party-dts-extractor@0.6.11':
|
||||
dependencies:
|
||||
find-pkg: 2.0.0
|
||||
fs-extra: 9.1.0
|
||||
resolve: 1.22.8
|
||||
|
||||
'@module-federation/third-party-dts-extractor@0.6.9':
|
||||
dependencies:
|
||||
find-pkg: 2.0.0
|
||||
@ -20704,11 +20944,25 @@ snapshots:
|
||||
fs-extra: 9.1.0
|
||||
resolve: 1.22.8
|
||||
|
||||
'@module-federation/utilities@3.1.17(next@14.2.16(@babel/core@7.25.2)(@playwright/test@1.47.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))':
|
||||
dependencies:
|
||||
'@module-federation/sdk': 0.6.11
|
||||
webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)
|
||||
optionalDependencies:
|
||||
next: 14.2.16(@babel/core@7.25.2)(@playwright/test@1.47.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@module-federation/webpack-bundler-runtime@0.5.1':
|
||||
dependencies:
|
||||
'@module-federation/runtime': 0.5.1
|
||||
'@module-federation/sdk': 0.5.1
|
||||
|
||||
'@module-federation/webpack-bundler-runtime@0.6.11':
|
||||
dependencies:
|
||||
'@module-federation/runtime': 0.6.11
|
||||
'@module-federation/sdk': 0.6.11
|
||||
|
||||
'@module-federation/webpack-bundler-runtime@0.6.9':
|
||||
dependencies:
|
||||
'@module-federation/runtime': 0.6.9
|
||||
@ -22225,6 +22479,61 @@ snapshots:
|
||||
- vue-tsc
|
||||
- webpack
|
||||
|
||||
'@nx/rspack@20.2.0-beta.2(qqfm4c7f7lave6shde5djyndcy)':
|
||||
dependencies:
|
||||
'@module-federation/enhanced': 0.7.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.4)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
'@module-federation/node': 2.5.21(next@14.2.16(@babel/core@7.25.2)(@playwright/test@1.47.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.55.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.4)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
'@nx/devkit': 20.2.0-beta.2(nx@20.2.0-beta.2(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.7(@swc/helpers@0.5.11)))
|
||||
'@nx/js': 20.2.0-beta.2(@babel/traverse@7.25.6)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@types/node@20.16.10)(nx@20.2.0-beta.2(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.5.4)(verdaccio@5.32.2(encoding@0.1.13)(typanion@3.14.0))
|
||||
'@nx/web': 20.2.0-beta.2(@babel/traverse@7.25.6)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@types/node@20.16.10)(nx@20.2.0-beta.2(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.5.4)(verdaccio@5.32.2(encoding@0.1.13)(typanion@3.14.0))
|
||||
'@phenomnomnominal/tsquery': 5.0.1(typescript@5.5.4)
|
||||
'@rspack/core': 1.1.2(@swc/helpers@0.5.11)
|
||||
'@rspack/dev-server': 1.0.9(@rspack/core@1.1.2(@swc/helpers@0.5.11))(@types/express@4.17.14)(webpack-cli@5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0))(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
'@rspack/plugin-react-refresh': 1.0.0(react-refresh@0.10.0)
|
||||
autoprefixer: 10.4.13(postcss@8.4.38)
|
||||
browserslist: 4.23.3
|
||||
chalk: 4.1.2
|
||||
css-loader: 6.11.0(@rspack/core@1.1.2(@swc/helpers@0.5.11))(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
enquirer: 2.3.6
|
||||
express: 4.21.0
|
||||
fork-ts-checker-webpack-plugin: 7.2.13(typescript@5.5.4)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
http-proxy-middleware: 3.0.3
|
||||
less-loader: 11.1.0(less@4.1.3)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
license-webpack-plugin: 4.0.2(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
loader-utils: 2.0.3
|
||||
postcss: 8.4.38
|
||||
postcss-import: 14.1.0(postcss@8.4.38)
|
||||
postcss-loader: 8.1.1(@rspack/core@1.1.2(@swc/helpers@0.5.11))(postcss@8.4.38)(typescript@5.5.4)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
sass: 1.55.0
|
||||
sass-loader: 12.6.0(sass@1.55.0)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
source-map-loader: 5.0.0(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
style-loader: 3.3.4(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
tslib: 2.7.0
|
||||
webpack-node-externals: 3.0.0
|
||||
transitivePeerDependencies:
|
||||
- '@babel/traverse'
|
||||
- '@swc-node/register'
|
||||
- '@swc/core'
|
||||
- '@swc/helpers'
|
||||
- '@swc/wasm'
|
||||
- '@types/express'
|
||||
- '@types/node'
|
||||
- bufferutil
|
||||
- debug
|
||||
- fibers
|
||||
- less
|
||||
- node-sass
|
||||
- nx
|
||||
- react-refresh
|
||||
- sass-embedded
|
||||
- supports-color
|
||||
- typescript
|
||||
- utf-8-validate
|
||||
- verdaccio
|
||||
- vue-template-compiler
|
||||
- webpack
|
||||
- webpack-cli
|
||||
|
||||
'@nx/storybook@20.2.0-beta.2(@babel/traverse@7.25.6)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@types/node@20.16.10)(@zkochan/js-yaml@0.0.7)(cypress@13.13.0)(eslint@8.57.0)(nx@20.2.0-beta.2(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.5.4)(verdaccio@5.32.2(encoding@0.1.13)(typanion@3.14.0))':
|
||||
dependencies:
|
||||
'@nx/cypress': 20.2.0-beta.2(@babel/traverse@7.25.6)(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.7(@swc/helpers@0.5.11))(@types/node@20.16.10)(@zkochan/js-yaml@0.0.7)(cypress@13.13.0)(eslint@8.57.0)(nx@20.2.0-beta.2(@swc-node/register@1.9.1(@swc/core@1.5.7(@swc/helpers@0.5.11))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.7(@swc/helpers@0.5.11)))(typescript@5.5.4)(verdaccio@5.32.2(encoding@0.1.13)(typanion@3.14.0))
|
||||
@ -22332,7 +22641,7 @@ snapshots:
|
||||
tsconfig-paths-webpack-plugin: 4.0.0
|
||||
tslib: 2.7.0
|
||||
webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)
|
||||
webpack-dev-server: 5.0.4(webpack-cli@5.1.4)(webpack@5.88.0)
|
||||
webpack-dev-server: 5.0.4(webpack-cli@5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0))(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
webpack-node-externals: 3.0.0
|
||||
webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.5.0(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)))(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
transitivePeerDependencies:
|
||||
@ -22706,7 +23015,7 @@ snapshots:
|
||||
webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)
|
||||
optionalDependencies:
|
||||
type-fest: 3.13.1
|
||||
webpack-dev-server: 5.0.4(webpack-cli@5.1.4)(webpack@5.88.0)
|
||||
webpack-dev-server: 5.0.4(webpack-cli@5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0))(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
webpack-hot-middleware: 2.26.1
|
||||
|
||||
'@pnpm/lockfile-types@6.0.0':
|
||||
@ -23263,7 +23572,7 @@ snapshots:
|
||||
mime-types: 2.1.35
|
||||
p-retry: 4.6.2
|
||||
webpack-dev-middleware: 7.4.2(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
webpack-dev-server: 5.0.4(webpack-cli@5.1.4)(webpack@5.88.0)
|
||||
webpack-dev-server: 5.0.4(webpack-cli@5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0))(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
ws: 8.18.0
|
||||
transitivePeerDependencies:
|
||||
- '@types/express'
|
||||
@ -25523,7 +25832,7 @@ snapshots:
|
||||
webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)
|
||||
webpack-cli: 5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0)
|
||||
optionalDependencies:
|
||||
webpack-dev-server: 5.0.4(webpack-cli@5.1.4)(webpack@5.88.0)
|
||||
webpack-dev-server: 5.0.4(webpack-cli@5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0))(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
|
||||
'@widgetbot/embed-api@1.2.15':
|
||||
dependencies:
|
||||
@ -27812,7 +28121,6 @@ snapshots:
|
||||
encoding@0.1.13:
|
||||
dependencies:
|
||||
iconv-lite: 0.6.3
|
||||
optional: true
|
||||
|
||||
end-of-stream@1.4.4:
|
||||
dependencies:
|
||||
@ -33581,6 +33889,18 @@ snapshots:
|
||||
semver: 7.6.3
|
||||
webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)
|
||||
|
||||
postcss-loader@8.1.1(@rspack/core@1.1.2(@swc/helpers@0.5.11))(postcss@8.4.38)(typescript@5.5.4)(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)):
|
||||
dependencies:
|
||||
cosmiconfig: 9.0.0(typescript@5.5.4)
|
||||
jiti: 1.21.6
|
||||
postcss: 8.4.38
|
||||
semver: 7.6.3
|
||||
optionalDependencies:
|
||||
'@rspack/core': 1.1.2(@swc/helpers@0.5.11)
|
||||
webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
postcss-loader@8.1.1(@rspack/core@1.1.2(@swc/helpers@0.5.11))(postcss@8.4.41)(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.23.0)(webpack-cli@5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0))):
|
||||
dependencies:
|
||||
cosmiconfig: 9.0.0(typescript@5.5.4)
|
||||
@ -37138,7 +37458,7 @@ snapshots:
|
||||
webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)
|
||||
webpack-merge: 5.10.0
|
||||
optionalDependencies:
|
||||
webpack-dev-server: 5.0.4(webpack-cli@5.1.4)(webpack@5.88.0)
|
||||
webpack-dev-server: 5.0.4(webpack-cli@5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0))(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
|
||||
webpack-dev-middleware@6.1.3(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)):
|
||||
dependencies:
|
||||
@ -37172,6 +37492,47 @@ snapshots:
|
||||
optionalDependencies:
|
||||
webpack: 5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.23.0)(webpack-cli@5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0))
|
||||
|
||||
webpack-dev-server@5.0.4(webpack-cli@5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0))(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)):
|
||||
dependencies:
|
||||
'@types/bonjour': 3.5.13
|
||||
'@types/connect-history-api-fallback': 1.5.4
|
||||
'@types/express': 4.17.21
|
||||
'@types/serve-index': 1.9.4
|
||||
'@types/serve-static': 1.15.7
|
||||
'@types/sockjs': 0.3.36
|
||||
'@types/ws': 8.5.12
|
||||
ansi-html-community: 0.0.8
|
||||
bonjour-service: 1.2.1
|
||||
chokidar: 3.6.0
|
||||
colorette: 2.0.20
|
||||
compression: 1.7.4
|
||||
connect-history-api-fallback: 2.0.0
|
||||
default-gateway: 6.0.3
|
||||
express: 4.21.0
|
||||
graceful-fs: 4.2.11
|
||||
html-entities: 2.5.2
|
||||
http-proxy-middleware: 2.0.6(@types/express@4.17.21)
|
||||
ipaddr.js: 2.2.0
|
||||
launch-editor: 2.9.1
|
||||
open: 10.1.0
|
||||
p-retry: 6.2.0
|
||||
rimraf: 5.0.10
|
||||
schema-utils: 4.2.0
|
||||
selfsigned: 2.4.1
|
||||
serve-index: 1.9.1
|
||||
sockjs: 0.3.24
|
||||
spdy: 4.0.2
|
||||
webpack-dev-middleware: 7.4.2(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
ws: 8.18.0
|
||||
optionalDependencies:
|
||||
webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)
|
||||
webpack-cli: 5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0)
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- debug
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
webpack-dev-server@5.0.4(webpack-cli@5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0))(webpack@5.94.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.23.0)(webpack-cli@5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0))):
|
||||
dependencies:
|
||||
'@types/bonjour': 3.5.13
|
||||
@ -37213,47 +37574,6 @@ snapshots:
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
webpack-dev-server@5.0.4(webpack-cli@5.1.4)(webpack@5.88.0):
|
||||
dependencies:
|
||||
'@types/bonjour': 3.5.13
|
||||
'@types/connect-history-api-fallback': 1.5.4
|
||||
'@types/express': 4.17.21
|
||||
'@types/serve-index': 1.9.4
|
||||
'@types/serve-static': 1.15.7
|
||||
'@types/sockjs': 0.3.36
|
||||
'@types/ws': 8.5.12
|
||||
ansi-html-community: 0.0.8
|
||||
bonjour-service: 1.2.1
|
||||
chokidar: 3.6.0
|
||||
colorette: 2.0.20
|
||||
compression: 1.7.4
|
||||
connect-history-api-fallback: 2.0.0
|
||||
default-gateway: 6.0.3
|
||||
express: 4.21.0
|
||||
graceful-fs: 4.2.11
|
||||
html-entities: 2.5.2
|
||||
http-proxy-middleware: 2.0.6(@types/express@4.17.21)
|
||||
ipaddr.js: 2.2.0
|
||||
launch-editor: 2.9.1
|
||||
open: 10.1.0
|
||||
p-retry: 6.2.0
|
||||
rimraf: 5.0.10
|
||||
schema-utils: 4.2.0
|
||||
selfsigned: 2.4.1
|
||||
serve-index: 1.9.1
|
||||
sockjs: 0.3.24
|
||||
spdy: 4.0.2
|
||||
webpack-dev-middleware: 7.4.2(webpack@5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4))
|
||||
ws: 8.18.0
|
||||
optionalDependencies:
|
||||
webpack: 5.88.0(@swc/core@1.5.7(@swc/helpers@0.5.11))(esbuild@0.19.5)(webpack-cli@5.1.4)
|
||||
webpack-cli: 5.1.4(webpack-dev-server@5.0.4)(webpack@5.88.0)
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- debug
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
webpack-hot-middleware@2.26.1:
|
||||
dependencies:
|
||||
ansi-html-community: 0.0.8
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user