feat(rsbuild): add inferred targets plugin (#29192)
## Current Behavior There is currently no way to execute Rsbuild targets via Nx. ## Expected Behavior Add a `@nx/rsbuild/plugin` to infer targets based on the `rsbuild.config` files in the workspace. Also add an `init` generator to allow for `nx init` in existing rsbuild projects.
This commit is contained in:
parent
7fca6e236a
commit
ee91b63b42
@ -9889,7 +9889,25 @@
|
|||||||
"id": "rsbuild",
|
"id": "rsbuild",
|
||||||
"path": "/nx-api/rsbuild",
|
"path": "/nx-api/rsbuild",
|
||||||
"name": "rsbuild",
|
"name": "rsbuild",
|
||||||
"children": [],
|
"children": [
|
||||||
|
{
|
||||||
|
"id": "generators",
|
||||||
|
"path": "/nx-api/rsbuild/generators",
|
||||||
|
"name": "generators",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"id": "init",
|
||||||
|
"path": "/nx-api/rsbuild/generators/init",
|
||||||
|
"name": "init",
|
||||||
|
"children": [],
|
||||||
|
"isExternal": false,
|
||||||
|
"disableCollapsible": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"isExternal": false,
|
||||||
|
"disableCollapsible": false
|
||||||
|
}
|
||||||
|
],
|
||||||
"isExternal": false,
|
"isExternal": false,
|
||||||
"disableCollapsible": false
|
"disableCollapsible": false
|
||||||
},
|
},
|
||||||
|
|||||||
@ -2900,7 +2900,17 @@
|
|||||||
"root": "/packages/rsbuild",
|
"root": "/packages/rsbuild",
|
||||||
"source": "/packages/rsbuild/src",
|
"source": "/packages/rsbuild/src",
|
||||||
"executors": {},
|
"executors": {},
|
||||||
"generators": {},
|
"generators": {
|
||||||
|
"/nx-api/rsbuild/generators/init": {
|
||||||
|
"description": "Initialize the `@nx/rsbuild` plugin.",
|
||||||
|
"file": "generated/packages/rsbuild/generators/init.json",
|
||||||
|
"hidden": true,
|
||||||
|
"name": "init",
|
||||||
|
"originalFilePath": "/packages/rsbuild/src/generators/init/schema.json",
|
||||||
|
"path": "/nx-api/rsbuild/generators/init",
|
||||||
|
"type": "generator"
|
||||||
|
}
|
||||||
|
},
|
||||||
"path": "/nx-api/rsbuild"
|
"path": "/nx-api/rsbuild"
|
||||||
},
|
},
|
||||||
"rspack": {
|
"rspack": {
|
||||||
|
|||||||
@ -2869,7 +2869,17 @@
|
|||||||
"description": "The Nx Plugin for Rsbuild contains an Nx plugin, executors and utilities that support building applications using Rsbuild.",
|
"description": "The Nx Plugin for Rsbuild contains an Nx plugin, executors and utilities that support building applications using Rsbuild.",
|
||||||
"documents": [],
|
"documents": [],
|
||||||
"executors": [],
|
"executors": [],
|
||||||
"generators": [],
|
"generators": [
|
||||||
|
{
|
||||||
|
"description": "Initialize the `@nx/rsbuild` plugin.",
|
||||||
|
"file": "generated/packages/rsbuild/generators/init.json",
|
||||||
|
"hidden": true,
|
||||||
|
"name": "init",
|
||||||
|
"originalFilePath": "/packages/rsbuild/src/generators/init/schema.json",
|
||||||
|
"path": "rsbuild/generators/init",
|
||||||
|
"type": "generator"
|
||||||
|
}
|
||||||
|
],
|
||||||
"githubRoot": "https://github.com/nrwl/nx/blob/master",
|
"githubRoot": "https://github.com/nrwl/nx/blob/master",
|
||||||
"name": "rsbuild",
|
"name": "rsbuild",
|
||||||
"packageName": "@nx/rsbuild",
|
"packageName": "@nx/rsbuild",
|
||||||
|
|||||||
44
docs/generated/packages/rsbuild/generators/init.json
Normal file
44
docs/generated/packages/rsbuild/generators/init.json
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"name": "init",
|
||||||
|
"factory": "./src/generators/init/init#initGeneratorInternal",
|
||||||
|
"schema": {
|
||||||
|
"$schema": "http://json-schema.org/schema",
|
||||||
|
"$id": "Init",
|
||||||
|
"title": "Nx Rsbuild Init Generator",
|
||||||
|
"type": "object",
|
||||||
|
"description": "Rsbuild init generator.",
|
||||||
|
"properties": {
|
||||||
|
"rootProject": { "type": "boolean", "x-priority": "internal" },
|
||||||
|
"keepExistingVersions": {
|
||||||
|
"type": "boolean",
|
||||||
|
"x-priority": "internal",
|
||||||
|
"description": "Keep existing dependencies versions",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"updatePackageScripts": {
|
||||||
|
"type": "boolean",
|
||||||
|
"x-priority": "internal",
|
||||||
|
"description": "Update package scripts",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"skipFormat": {
|
||||||
|
"description": "Skip formatting files.",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"skipPackageJson": {
|
||||||
|
"description": "Do not add dependencies to `package.json`.",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [],
|
||||||
|
"presets": []
|
||||||
|
},
|
||||||
|
"description": "Initialize the `@nx/rsbuild` plugin.",
|
||||||
|
"aliases": ["ng-add"],
|
||||||
|
"hidden": true,
|
||||||
|
"implementation": "/packages/rsbuild/src/generators/init/init#initGeneratorInternal.ts",
|
||||||
|
"path": "/packages/rsbuild/src/generators/init/schema.json",
|
||||||
|
"type": "generator"
|
||||||
|
}
|
||||||
@ -686,6 +686,8 @@
|
|||||||
- [configuration](/nx-api/rollup/generators/configuration)
|
- [configuration](/nx-api/rollup/generators/configuration)
|
||||||
- [convert-to-inferred](/nx-api/rollup/generators/convert-to-inferred)
|
- [convert-to-inferred](/nx-api/rollup/generators/convert-to-inferred)
|
||||||
- [rsbuild](/nx-api/rsbuild)
|
- [rsbuild](/nx-api/rsbuild)
|
||||||
|
- [generators](/nx-api/rsbuild/generators)
|
||||||
|
- [init](/nx-api/rsbuild/generators/init)
|
||||||
- [rspack](/nx-api/rspack)
|
- [rspack](/nx-api/rspack)
|
||||||
- [documents](/nx-api/rspack/documents)
|
- [documents](/nx-api/rspack/documents)
|
||||||
- [Overview](/nx-api/rspack/documents/overview)
|
- [Overview](/nx-api/rspack/documents/overview)
|
||||||
|
|||||||
@ -102,6 +102,7 @@
|
|||||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||||
"@rollup/plugin-url": "^8.0.2",
|
"@rollup/plugin-url": "^8.0.2",
|
||||||
"@rspack/core": "^1.1.5",
|
"@rspack/core": "^1.1.5",
|
||||||
|
"@rsbuild/core": "1.1.8",
|
||||||
"@rspack/dev-server": "1.0.9",
|
"@rspack/dev-server": "1.0.9",
|
||||||
"@rspack/plugin-minify": "^0.7.5",
|
"@rspack/plugin-minify": "^0.7.5",
|
||||||
"@rspack/plugin-react-refresh": "^1.0.0",
|
"@rspack/plugin-react-refresh": "^1.0.0",
|
||||||
|
|||||||
@ -179,6 +179,7 @@ const npmPackageToPluginMap: Record<string, `@nx/${string}`> = {
|
|||||||
nuxt: '@nx/nuxt',
|
nuxt: '@nx/nuxt',
|
||||||
'react-native': '@nx/react-native',
|
'react-native': '@nx/react-native',
|
||||||
'@remix-run/dev': '@nx/remix',
|
'@remix-run/dev': '@nx/remix',
|
||||||
|
'@rsbuild/core': '@nx/rsbuild',
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function detectPlugins(
|
export async function detectPlugins(
|
||||||
|
|||||||
@ -1223,6 +1223,7 @@ module.exports = withNx(
|
|||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"types": "./dist/index.esm.d.ts",
|
"types": "./dist/index.esm.d.ts",
|
||||||
|
"version": "0.0.1",
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|||||||
13
packages/rsbuild/generators.json
Normal file
13
packages/rsbuild/generators.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "Nx Rsbuild",
|
||||||
|
"version": "0.1",
|
||||||
|
"generators": {
|
||||||
|
"init": {
|
||||||
|
"factory": "./src/generators/init/init#initGeneratorInternal",
|
||||||
|
"schema": "./src/generators/init/schema.json",
|
||||||
|
"description": "Initialize the `@nx/rsbuild` plugin.",
|
||||||
|
"aliases": ["ng-add"],
|
||||||
|
"hidden": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -26,9 +26,14 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "https://nx.dev",
|
"homepage": "https://nx.dev",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
"generators": "./generators.json",
|
||||||
"executors": "./executors.json",
|
"executors": "./executors.json",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0",
|
||||||
|
"@nx/devkit": "file:../devkit",
|
||||||
|
"@nx/js": "file:../js",
|
||||||
|
"@rsbuild/core": "1.1.8",
|
||||||
|
"minimatch": "9.0.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {},
|
"peerDependencies": {},
|
||||||
"nx-migrations": {
|
"nx-migrations": {
|
||||||
|
|||||||
1
packages/rsbuild/plugin.ts
Normal file
1
packages/rsbuild/plugin.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { createNodesV2, RsbuildPluginOptions } from './src/plugins/plugin';
|
||||||
75
packages/rsbuild/src/generators/init/init.ts
Normal file
75
packages/rsbuild/src/generators/init/init.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import {
|
||||||
|
type Tree,
|
||||||
|
type GeneratorCallback,
|
||||||
|
readNxJson,
|
||||||
|
createProjectGraphAsync,
|
||||||
|
addDependenciesToPackageJson,
|
||||||
|
formatFiles,
|
||||||
|
runTasksInSerial,
|
||||||
|
} from '@nx/devkit';
|
||||||
|
import { addPlugin } from '@nx/devkit/src/utils/add-plugin';
|
||||||
|
import { InitGeneratorSchema } from './schema';
|
||||||
|
import { createNodesV2 } from '../../plugins/plugin';
|
||||||
|
import { nxVersion, rsbuildVersion } from '../../utils/versions';
|
||||||
|
|
||||||
|
export function updateDependencies(tree: Tree, schema: InitGeneratorSchema) {
|
||||||
|
return addDependenciesToPackageJson(
|
||||||
|
tree,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
'@nx/rsbuild': nxVersion,
|
||||||
|
'@rsbuild/core': rsbuildVersion,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
schema.keepExistingVersions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initGenerator(tree: Tree, schema: InitGeneratorSchema) {
|
||||||
|
return initGeneratorInternal(tree, { addPlugin: false, ...schema });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function initGeneratorInternal(
|
||||||
|
tree: Tree,
|
||||||
|
schema: InitGeneratorSchema
|
||||||
|
) {
|
||||||
|
const nxJson = readNxJson(tree);
|
||||||
|
const addPluginDefault =
|
||||||
|
process.env.NX_ADD_PLUGINS !== 'false' &&
|
||||||
|
nxJson.useInferencePlugins !== false;
|
||||||
|
schema.addPlugin ??= addPluginDefault;
|
||||||
|
|
||||||
|
if (schema.addPlugin) {
|
||||||
|
await addPlugin(
|
||||||
|
tree,
|
||||||
|
await createProjectGraphAsync(),
|
||||||
|
'@nx/rsbuild/plugin',
|
||||||
|
createNodesV2,
|
||||||
|
{
|
||||||
|
buildTargetName: ['build', 'rsbuild:build', 'rsbuild-build'],
|
||||||
|
devTargetName: ['dev', 'rsbuild:dev', 'rsbuild-dev'],
|
||||||
|
previewTargetName: ['preview', 'rsbuild:preview', 'rsbuild-preview'],
|
||||||
|
inspectTargetName: ['inspect', 'rsbuild:inspect', 'rsbuild-inspect'],
|
||||||
|
typecheckTargetName: [
|
||||||
|
'typecheck',
|
||||||
|
'rsbuild:typecheck',
|
||||||
|
'rsbuild-typecheck',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
schema.updatePackageScripts
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const tasks: GeneratorCallback[] = [];
|
||||||
|
if (!schema.skipPackageJson) {
|
||||||
|
tasks.push(updateDependencies(tree, schema));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!schema.skipFormat) {
|
||||||
|
await formatFiles(tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
return runTasksInSerial(...tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default initGenerator;
|
||||||
7
packages/rsbuild/src/generators/init/schema.d.ts
vendored
Normal file
7
packages/rsbuild/src/generators/init/schema.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export interface InitGeneratorSchema {
|
||||||
|
keepExistingVersions?: boolean;
|
||||||
|
updatePackageScripts?: boolean;
|
||||||
|
addPlugin?: boolean;
|
||||||
|
skipFormat?: boolean;
|
||||||
|
skipPackageJson?: boolean;
|
||||||
|
}
|
||||||
36
packages/rsbuild/src/generators/init/schema.json
Normal file
36
packages/rsbuild/src/generators/init/schema.json
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/schema",
|
||||||
|
"$id": "Init",
|
||||||
|
"title": "Nx Rsbuild Init Generator",
|
||||||
|
"type": "object",
|
||||||
|
"description": "Rsbuild init generator.",
|
||||||
|
"properties": {
|
||||||
|
"rootProject": {
|
||||||
|
"type": "boolean",
|
||||||
|
"x-priority": "internal"
|
||||||
|
},
|
||||||
|
"keepExistingVersions": {
|
||||||
|
"type": "boolean",
|
||||||
|
"x-priority": "internal",
|
||||||
|
"description": "Keep existing dependencies versions",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"updatePackageScripts": {
|
||||||
|
"type": "boolean",
|
||||||
|
"x-priority": "internal",
|
||||||
|
"description": "Update package scripts",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"skipFormat": {
|
||||||
|
"description": "Skip formatting files.",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"skipPackageJson": {
|
||||||
|
"description": "Do not add dependencies to `package.json`.",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
}
|
||||||
142
packages/rsbuild/src/plugins/plugin.spec.ts
Normal file
142
packages/rsbuild/src/plugins/plugin.spec.ts
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import { type CreateNodesContext } from '@nx/devkit';
|
||||||
|
import { createNodesV2 } from './plugin';
|
||||||
|
import { TempFs } from 'nx/src/internal-testing-utils/temp-fs';
|
||||||
|
|
||||||
|
jest.mock('@rsbuild/core', () => ({
|
||||||
|
...jest.requireActual('@rsbuild/core'),
|
||||||
|
loadConfig: jest.fn().mockResolvedValue({
|
||||||
|
filePath: 'my-app/rsbuild.config.ts',
|
||||||
|
content: {},
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('@nx/js/src/utils/typescript/ts-solution-setup', () => ({
|
||||||
|
...jest.requireActual('@nx/js/src/utils/typescript/ts-solution-setup'),
|
||||||
|
isUsingTsSolutionSetup: jest.fn().mockReturnValue(false),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('@nx/rsbuild/plugin', () => {
|
||||||
|
let createNodesFunction = createNodesV2[1];
|
||||||
|
let context: CreateNodesContext;
|
||||||
|
let tempFs: TempFs;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tempFs = new TempFs('rsbuild-test');
|
||||||
|
context = {
|
||||||
|
configFiles: [],
|
||||||
|
nxJsonConfiguration: {
|
||||||
|
namedInputs: {
|
||||||
|
default: ['{projectRoot}/**/*'],
|
||||||
|
production: ['!{projectRoot}/**/*.spec.ts'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
workspaceRoot: tempFs.tempDir,
|
||||||
|
};
|
||||||
|
|
||||||
|
tempFs.createFileSync(
|
||||||
|
'my-app/project.json',
|
||||||
|
JSON.stringify({ name: 'my-app' })
|
||||||
|
);
|
||||||
|
tempFs.createFileSync('my-app/rsbuild.config.ts', `export default {};`);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
tempFs.cleanup();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create nodes', async () => {
|
||||||
|
const nodes = await createNodesFunction(
|
||||||
|
['my-app/rsbuild.config.ts'],
|
||||||
|
{
|
||||||
|
buildTargetName: 'build-something',
|
||||||
|
devTargetName: 'dev-serve',
|
||||||
|
previewTargetName: 'preview-serve',
|
||||||
|
inspectTargetName: 'inspect-serve',
|
||||||
|
typecheckTargetName: 'typecheck-app',
|
||||||
|
},
|
||||||
|
context
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(nodes).toMatchInlineSnapshot(`
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"my-app/rsbuild.config.ts",
|
||||||
|
{
|
||||||
|
"projects": {
|
||||||
|
"my-app": {
|
||||||
|
"metadata": {},
|
||||||
|
"root": "my-app",
|
||||||
|
"targets": {
|
||||||
|
"build-something": {
|
||||||
|
"cache": true,
|
||||||
|
"command": "rsbuild build",
|
||||||
|
"dependsOn": [
|
||||||
|
"^build-something",
|
||||||
|
],
|
||||||
|
"inputs": [
|
||||||
|
"production",
|
||||||
|
"^production",
|
||||||
|
{
|
||||||
|
"externalDependencies": [
|
||||||
|
"@rsbuild/core",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"description": "Run Rsbuild build",
|
||||||
|
"help": {
|
||||||
|
"command": "npx rsbuild build --help",
|
||||||
|
"example": {
|
||||||
|
"options": {
|
||||||
|
"watch": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"technologies": [
|
||||||
|
"rsbuild",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"args": [
|
||||||
|
"--mode=production",
|
||||||
|
],
|
||||||
|
"cwd": "my-app",
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
"{workspaceRoot}/dist/{projectRoot}",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"dev-serve": {
|
||||||
|
"command": "rsbuild dev",
|
||||||
|
"options": {
|
||||||
|
"args": [
|
||||||
|
"--mode=development",
|
||||||
|
],
|
||||||
|
"cwd": "my-app",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"inspect-serve": {
|
||||||
|
"command": "rsbuild inspect",
|
||||||
|
"options": {
|
||||||
|
"cwd": "my-app",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"preview-serve": {
|
||||||
|
"command": "rsbuild preview",
|
||||||
|
"options": {
|
||||||
|
"args": [
|
||||||
|
"--mode=production",
|
||||||
|
],
|
||||||
|
"cwd": "my-app",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
||||||
295
packages/rsbuild/src/plugins/plugin.ts
Normal file
295
packages/rsbuild/src/plugins/plugin.ts
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
import {
|
||||||
|
type ProjectConfiguration,
|
||||||
|
type TargetConfiguration,
|
||||||
|
readJsonFile,
|
||||||
|
writeJsonFile,
|
||||||
|
CreateNodesV2,
|
||||||
|
CreateNodesContext,
|
||||||
|
createNodesFromFiles,
|
||||||
|
joinPathFragments,
|
||||||
|
getPackageManagerCommand,
|
||||||
|
detectPackageManager,
|
||||||
|
} from '@nx/devkit';
|
||||||
|
import { getNamedInputs } from '@nx/devkit/src/utils/get-named-inputs';
|
||||||
|
import { hashObject } from 'nx/src/hasher/file-hasher';
|
||||||
|
import { workspaceDataDirectory } from 'nx/src/utils/cache-directory';
|
||||||
|
import { isUsingTsSolutionSetup as _isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
|
import { calculateHashForCreateNodes } from '@nx/devkit/src/utils/calculate-hash-for-create-nodes';
|
||||||
|
import { getLockFileName } from '@nx/js';
|
||||||
|
import { existsSync, readdirSync } from 'fs';
|
||||||
|
import { join, dirname, isAbsolute, relative } from 'path';
|
||||||
|
import { minimatch } from 'minimatch';
|
||||||
|
import { loadConfig, type RsbuildConfig } from '@rsbuild/core';
|
||||||
|
|
||||||
|
const pmc = getPackageManagerCommand();
|
||||||
|
|
||||||
|
export interface RsbuildPluginOptions {
|
||||||
|
buildTargetName?: string;
|
||||||
|
devTargetName?: string;
|
||||||
|
previewTargetName?: string;
|
||||||
|
inspectTargetName?: string;
|
||||||
|
typecheckTargetName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type RsbuildTargets = Pick<ProjectConfiguration, 'targets' | 'metadata'>;
|
||||||
|
|
||||||
|
function readTargetsCache(cachePath: string): Record<string, RsbuildTargets> {
|
||||||
|
return existsSync(cachePath) ? readJsonFile(cachePath) : {};
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeTargetsCache(
|
||||||
|
cachePath,
|
||||||
|
results?: Record<string, RsbuildTargets>
|
||||||
|
) {
|
||||||
|
writeJsonFile(cachePath, results);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rsbuildConfigGlob = '**/rsbuild.config.{js,ts,mjs,mts,cjs,cts}';
|
||||||
|
|
||||||
|
export const createNodesV2: CreateNodesV2<RsbuildPluginOptions> = [
|
||||||
|
rsbuildConfigGlob,
|
||||||
|
async (configFilePaths, options, context) => {
|
||||||
|
const optionsHash = hashObject(options);
|
||||||
|
const cachePath = join(
|
||||||
|
workspaceDataDirectory,
|
||||||
|
`rsbuild-${optionsHash}.hash`
|
||||||
|
);
|
||||||
|
const targetsCache = readTargetsCache(cachePath);
|
||||||
|
const isUsingTsSolutionSetup = _isUsingTsSolutionSetup();
|
||||||
|
try {
|
||||||
|
return await createNodesFromFiles(
|
||||||
|
(configFile, options, context) =>
|
||||||
|
createNodesInternal(
|
||||||
|
configFile,
|
||||||
|
options,
|
||||||
|
context,
|
||||||
|
targetsCache,
|
||||||
|
isUsingTsSolutionSetup
|
||||||
|
),
|
||||||
|
configFilePaths,
|
||||||
|
options,
|
||||||
|
context
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
writeTargetsCache(cachePath, targetsCache);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
async function createNodesInternal(
|
||||||
|
configFilePath: string,
|
||||||
|
options: RsbuildPluginOptions,
|
||||||
|
context: CreateNodesContext,
|
||||||
|
targetsCache: Record<string, RsbuildTargets>,
|
||||||
|
isUsingTsSolutionSetup: boolean
|
||||||
|
) {
|
||||||
|
const projectRoot = dirname(configFilePath);
|
||||||
|
// Do not create a project if package.json and project.json isn't there.
|
||||||
|
const siblingFiles = readdirSync(join(context.workspaceRoot, projectRoot));
|
||||||
|
if (
|
||||||
|
!siblingFiles.includes('package.json') &&
|
||||||
|
!siblingFiles.includes('project.json')
|
||||||
|
) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const tsConfigFiles =
|
||||||
|
siblingFiles.filter((p) => minimatch(p, 'tsconfig*{.json,.*.json}')) ?? [];
|
||||||
|
|
||||||
|
const normalizedOptions = normalizeOptions(options);
|
||||||
|
const hash = await calculateHashForCreateNodes(
|
||||||
|
projectRoot,
|
||||||
|
normalizedOptions,
|
||||||
|
context,
|
||||||
|
[getLockFileName(detectPackageManager(context.workspaceRoot))]
|
||||||
|
);
|
||||||
|
|
||||||
|
targetsCache[hash] ??= await createRsbuildTargets(
|
||||||
|
configFilePath,
|
||||||
|
projectRoot,
|
||||||
|
normalizedOptions,
|
||||||
|
tsConfigFiles,
|
||||||
|
isUsingTsSolutionSetup,
|
||||||
|
context
|
||||||
|
);
|
||||||
|
|
||||||
|
const { targets, metadata } = targetsCache[hash];
|
||||||
|
|
||||||
|
return {
|
||||||
|
projects: {
|
||||||
|
[projectRoot]: {
|
||||||
|
root: projectRoot,
|
||||||
|
targets,
|
||||||
|
metadata,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createRsbuildTargets(
|
||||||
|
configFilePath: string,
|
||||||
|
projectRoot: string,
|
||||||
|
options: RsbuildPluginOptions,
|
||||||
|
tsConfigFiles: string[],
|
||||||
|
isUsingTsSolutionSetup: boolean,
|
||||||
|
context: CreateNodesContext
|
||||||
|
): Promise<RsbuildTargets> {
|
||||||
|
const absoluteConfigFilePath = joinPathFragments(
|
||||||
|
context.workspaceRoot,
|
||||||
|
configFilePath
|
||||||
|
);
|
||||||
|
|
||||||
|
const rsbuildConfig = await loadConfig({
|
||||||
|
path: absoluteConfigFilePath,
|
||||||
|
});
|
||||||
|
if (!rsbuildConfig.filePath) {
|
||||||
|
return { targets: {}, metadata: {} };
|
||||||
|
}
|
||||||
|
|
||||||
|
const namedInputs = getNamedInputs(projectRoot, context);
|
||||||
|
const { buildOutputs } = getOutputs(
|
||||||
|
rsbuildConfig.content,
|
||||||
|
projectRoot,
|
||||||
|
context.workspaceRoot
|
||||||
|
);
|
||||||
|
|
||||||
|
const targets: Record<string, TargetConfiguration> = {};
|
||||||
|
|
||||||
|
targets[options.buildTargetName] = {
|
||||||
|
command: `rsbuild build`,
|
||||||
|
options: { cwd: projectRoot, args: ['--mode=production'] },
|
||||||
|
cache: true,
|
||||||
|
dependsOn: [`^${options.buildTargetName}`],
|
||||||
|
inputs: [
|
||||||
|
...('production' in namedInputs
|
||||||
|
? ['production', '^production']
|
||||||
|
: ['default', '^default']),
|
||||||
|
{
|
||||||
|
externalDependencies: ['@rsbuild/core'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
outputs: buildOutputs,
|
||||||
|
metadata: {
|
||||||
|
technologies: ['rsbuild'],
|
||||||
|
description: `Run Rsbuild build`,
|
||||||
|
help: {
|
||||||
|
command: `${pmc.exec} rsbuild build --help`,
|
||||||
|
example: {
|
||||||
|
options: {
|
||||||
|
watch: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
targets[options.devTargetName] = {
|
||||||
|
command: `rsbuild dev`,
|
||||||
|
options: {
|
||||||
|
cwd: projectRoot,
|
||||||
|
args: ['--mode=development'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
targets[options.previewTargetName] = {
|
||||||
|
command: `rsbuild preview`,
|
||||||
|
options: {
|
||||||
|
cwd: projectRoot,
|
||||||
|
args: ['--mode=production'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
targets[options.inspectTargetName] = {
|
||||||
|
command: `rsbuild inspect`,
|
||||||
|
options: {
|
||||||
|
cwd: projectRoot,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (tsConfigFiles.length) {
|
||||||
|
const tsConfigToUse =
|
||||||
|
['tsconfig.app.json', 'tsconfig.lib.json', 'tsconfig.json'].find((t) =>
|
||||||
|
tsConfigFiles.includes(t)
|
||||||
|
) ?? tsConfigFiles[0];
|
||||||
|
targets[options.typecheckTargetName] = {
|
||||||
|
cache: true,
|
||||||
|
inputs: [
|
||||||
|
...('production' in namedInputs
|
||||||
|
? ['production', '^production']
|
||||||
|
: ['default', '^default']),
|
||||||
|
{ externalDependencies: ['typescript'] },
|
||||||
|
],
|
||||||
|
command: isUsingTsSolutionSetup
|
||||||
|
? `tsc --build --emitDeclarationOnly --pretty --verbose`
|
||||||
|
: `tsc --noEmit -p ${tsConfigToUse}`,
|
||||||
|
options: { cwd: joinPathFragments(projectRoot) },
|
||||||
|
metadata: {
|
||||||
|
description: `Run Typechecking`,
|
||||||
|
help: {
|
||||||
|
command: `${pmc.exec} tsc --help -p ${tsConfigToUse}`,
|
||||||
|
example: {
|
||||||
|
options: {
|
||||||
|
noEmit: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return { targets, metadata: {} };
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOutputs(
|
||||||
|
rsbuildConfig: RsbuildConfig,
|
||||||
|
projectRoot: string,
|
||||||
|
workspaceRoot: string
|
||||||
|
): { buildOutputs: string[] } {
|
||||||
|
const buildOutputPath = normalizeOutputPath(
|
||||||
|
rsbuildConfig?.output?.distPath?.root
|
||||||
|
? dirname(rsbuildConfig?.output.distPath.root)
|
||||||
|
: undefined,
|
||||||
|
projectRoot,
|
||||||
|
workspaceRoot,
|
||||||
|
'dist'
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
buildOutputs: [buildOutputPath],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeOutputPath(
|
||||||
|
outputPath: string | undefined,
|
||||||
|
projectRoot: string,
|
||||||
|
workspaceRoot: string,
|
||||||
|
path: 'dist'
|
||||||
|
): string | undefined {
|
||||||
|
if (!outputPath) {
|
||||||
|
if (projectRoot === '.') {
|
||||||
|
return `{projectRoot}/${path}`;
|
||||||
|
} else {
|
||||||
|
return `{workspaceRoot}/${path}/{projectRoot}`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isAbsolute(outputPath)) {
|
||||||
|
return `{workspaceRoot}/${relative(workspaceRoot, outputPath)}`;
|
||||||
|
} else {
|
||||||
|
if (outputPath.startsWith('..')) {
|
||||||
|
return join('{workspaceRoot}', join(projectRoot, outputPath));
|
||||||
|
} else {
|
||||||
|
return join('{projectRoot}', outputPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeOptions(options: RsbuildPluginOptions): RsbuildPluginOptions {
|
||||||
|
options ??= {};
|
||||||
|
options.buildTargetName ??= 'build';
|
||||||
|
options.devTargetName ??= 'dev';
|
||||||
|
options.previewTargetName ??= 'preview';
|
||||||
|
options.inspectTargetName ??= 'inspect';
|
||||||
|
options.typecheckTargetName ??= 'typecheck';
|
||||||
|
return options;
|
||||||
|
}
|
||||||
2
packages/rsbuild/src/utils/versions.ts
Normal file
2
packages/rsbuild/src/utils/versions.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export const nxVersion = require('../../package.json').version;
|
||||||
|
export const rsbuildVersion = '1.1.8';
|
||||||
36
pnpm-lock.yaml
generated
36
pnpm-lock.yaml
generated
@ -391,6 +391,9 @@ importers:
|
|||||||
'@rollup/plugin-url':
|
'@rollup/plugin-url':
|
||||||
specifier: ^8.0.2
|
specifier: ^8.0.2
|
||||||
version: 8.0.2(rollup@4.22.0)
|
version: 8.0.2(rollup@4.22.0)
|
||||||
|
'@rsbuild/core':
|
||||||
|
specifier: 1.1.8
|
||||||
|
version: 1.1.8
|
||||||
'@rspack/core':
|
'@rspack/core':
|
||||||
specifier: ^1.1.5
|
specifier: ^1.1.5
|
||||||
version: 1.1.5(@swc/helpers@0.5.11)
|
version: 1.1.5(@swc/helpers@0.5.11)
|
||||||
@ -6195,6 +6198,11 @@ packages:
|
|||||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
'@rsbuild/core@1.1.8':
|
||||||
|
resolution: {integrity: sha512-UhP260og3aJcqGWpnRcQXLVapdOZZ09JXaQKY+tE55A7nBw8DQy+qrtTsFZYvVKas1bq8GzhGfLxuglCst4Lnw==}
|
||||||
|
engines: {node: '>=16.7.0'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
'@rspack/binding-darwin-arm64@1.1.3':
|
'@rspack/binding-darwin-arm64@1.1.3':
|
||||||
resolution: {integrity: sha512-gpLUBMDAS/uEcnE+ODy1ILTeyp1oM4QCq8rRhKHuOfsIe1AZ9Mct59v2omIE/r+R4dnbJ0ikIpto9qJZ6P2u1A==}
|
resolution: {integrity: sha512-gpLUBMDAS/uEcnE+ODy1ILTeyp1oM4QCq8rRhKHuOfsIe1AZ9Mct59v2omIE/r+R4dnbJ0ikIpto9qJZ6P2u1A==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
@ -6824,6 +6832,9 @@ packages:
|
|||||||
'@swc/helpers@0.5.11':
|
'@swc/helpers@0.5.11':
|
||||||
resolution: {integrity: sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==}
|
resolution: {integrity: sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==}
|
||||||
|
|
||||||
|
'@swc/helpers@0.5.15':
|
||||||
|
resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
|
||||||
|
|
||||||
'@swc/helpers@0.5.5':
|
'@swc/helpers@0.5.5':
|
||||||
resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==}
|
resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==}
|
||||||
|
|
||||||
@ -9047,6 +9058,9 @@ packages:
|
|||||||
core-js@3.37.1:
|
core-js@3.37.1:
|
||||||
resolution: {integrity: sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==}
|
resolution: {integrity: sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==}
|
||||||
|
|
||||||
|
core-js@3.39.0:
|
||||||
|
resolution: {integrity: sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==}
|
||||||
|
|
||||||
core-util-is@1.0.2:
|
core-util-is@1.0.2:
|
||||||
resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==}
|
resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==}
|
||||||
|
|
||||||
@ -23960,6 +23974,13 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
|
|
||||||
|
'@rsbuild/core@1.1.8':
|
||||||
|
dependencies:
|
||||||
|
'@rspack/core': 1.1.5(@swc/helpers@0.5.15)
|
||||||
|
'@rspack/lite-tapable': 1.0.1
|
||||||
|
'@swc/helpers': 0.5.15
|
||||||
|
core-js: 3.39.0
|
||||||
|
|
||||||
'@rspack/binding-darwin-arm64@1.1.3':
|
'@rspack/binding-darwin-arm64@1.1.3':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@ -24056,6 +24077,15 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@swc/helpers': 0.5.11
|
'@swc/helpers': 0.5.11
|
||||||
|
|
||||||
|
'@rspack/core@1.1.5(@swc/helpers@0.5.15)':
|
||||||
|
dependencies:
|
||||||
|
'@module-federation/runtime-tools': 0.5.1
|
||||||
|
'@rspack/binding': 1.1.5
|
||||||
|
'@rspack/lite-tapable': 1.0.1
|
||||||
|
caniuse-lite: 1.0.30001684
|
||||||
|
optionalDependencies:
|
||||||
|
'@swc/helpers': 0.5.15
|
||||||
|
|
||||||
'@rspack/dev-server@1.0.9(@rspack/core@1.1.5(@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/dev-server@1.0.9(@rspack/core@1.1.5(@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))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rspack/core': 1.1.5(@swc/helpers@0.5.11)
|
'@rspack/core': 1.1.5(@swc/helpers@0.5.11)
|
||||||
@ -24749,6 +24779,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.7.0
|
tslib: 2.7.0
|
||||||
|
|
||||||
|
'@swc/helpers@0.5.15':
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
'@swc/helpers@0.5.5':
|
'@swc/helpers@0.5.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@swc/counter': 0.1.3
|
'@swc/counter': 0.1.3
|
||||||
@ -27569,6 +27603,8 @@ snapshots:
|
|||||||
|
|
||||||
core-js@3.37.1: {}
|
core-js@3.37.1: {}
|
||||||
|
|
||||||
|
core-js@3.39.0: {}
|
||||||
|
|
||||||
core-util-is@1.0.2: {}
|
core-util-is@1.0.2: {}
|
||||||
|
|
||||||
core-util-is@1.0.3: {}
|
core-util-is@1.0.3: {}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user