@nx/angular
Advanced tools
Comparing version
{ | ||
"name": "@nx/angular", | ||
"version": "21.2.0-canary.20250530-b51676a", | ||
"version": "21.2.0-canary.20250603-88c5196", | ||
"private": false, | ||
@@ -61,10 +61,10 @@ "description": "The Nx Plugin for Angular contains executors, generators, and utilities for managing Angular applications and libraries within an Nx workspace. It provides: \n\n- Integration with libraries such as Storybook, Jest, ESLint, Tailwind CSS, Playwright and Cypress. \n\n- Generators to help scaffold code quickly (like: Micro Frontends, Libraries, both internal to your codebase and publishable to npm) \n\n- Single Component Application Modules (SCAMs) \n\n- NgRx helpers. \n\n- Utilities for automatic workspace refactoring.", | ||
"dependencies": { | ||
"@nx/devkit": "21.2.0-canary.20250530-b51676a", | ||
"@nx/eslint": "21.2.0-canary.20250530-b51676a", | ||
"@nx/js": "21.2.0-canary.20250530-b51676a", | ||
"@nx/module-federation": "21.2.0-canary.20250530-b51676a", | ||
"@nx/rspack": "21.2.0-canary.20250530-b51676a", | ||
"@nx/web": "21.2.0-canary.20250530-b51676a", | ||
"@nx/webpack": "21.2.0-canary.20250530-b51676a", | ||
"@nx/workspace": "21.2.0-canary.20250530-b51676a", | ||
"@nx/devkit": "21.2.0-canary.20250603-88c5196", | ||
"@nx/eslint": "21.2.0-canary.20250603-88c5196", | ||
"@nx/js": "21.2.0-canary.20250603-88c5196", | ||
"@nx/module-federation": "21.2.0-canary.20250603-88c5196", | ||
"@nx/rspack": "21.2.0-canary.20250603-88c5196", | ||
"@nx/web": "21.2.0-canary.20250603-88c5196", | ||
"@nx/webpack": "21.2.0-canary.20250603-88c5196", | ||
"@nx/workspace": "21.2.0-canary.20250603-88c5196", | ||
"@phenomnomnominal/tsquery": "~5.0.1", | ||
@@ -71,0 +71,0 @@ "@typescript-eslint/type-utils": "^8.0.0", |
@@ -1,4 +0,4 @@ | ||
import { type Tree, GeneratorCallback } from '@nx/devkit'; | ||
import { type GeneratorCallback, type Tree } from '@nx/devkit'; | ||
import type { ConvertToRspackSchema } from './schema'; | ||
export declare function convertToRspack(tree: Tree, schema: ConvertToRspackSchema): Promise<GeneratorCallback>; | ||
export default convertToRspack; |
@@ -5,2 +5,7 @@ "use strict"; | ||
const devkit_1 = require("@nx/devkit"); | ||
const executor_options_utils_1 = require("@nx/devkit/src/generators/executor-options-utils"); | ||
const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs"); | ||
const enquirer_1 = require("enquirer"); | ||
const path_1 = require("path"); | ||
const posix_1 = require("path/posix"); | ||
const versions_1 = require("../../utils/versions"); | ||
@@ -11,6 +16,2 @@ const create_config_1 = require("./lib/create-config"); | ||
const validate_supported_executor_1 = require("./lib/validate-supported-executor"); | ||
const posix_1 = require("path/posix"); | ||
const path_1 = require("path"); | ||
const executor_options_utils_1 = require("@nx/devkit/src/generators/executor-options-utils"); | ||
const enquirer_1 = require("enquirer"); | ||
const SUPPORTED_EXECUTORS = [ | ||
@@ -169,6 +170,2 @@ '@angular-devkit/build-angular:browser', | ||
} | ||
if (options.outputs) { | ||
// handled by the Rspack inference plugin | ||
delete options.outputs; | ||
} | ||
for (const [key, value] of Object.entries(options)) { | ||
@@ -253,4 +250,5 @@ let optionName = key; | ||
const configurationOptions = {}; | ||
const buildTargetNames = []; | ||
const serveTargetNames = []; | ||
let buildTarget; | ||
let serveTarget; | ||
const targetsToRemove = []; | ||
let customWebpackConfigPath; | ||
@@ -269,3 +267,4 @@ (0, validate_supported_executor_1.validateSupportedBuildExecutor)(Object.values(project.targets)); | ||
} | ||
buildTargetNames.push(targetName); | ||
buildTarget = { name: targetName, config: target }; | ||
targetsToRemove.push(targetName); | ||
} | ||
@@ -277,3 +276,3 @@ else if (target.executor === '@angular-devkit/build-angular:server' || | ||
createConfigOptions.server = './src/main.server.ts'; | ||
buildTargetNames.push(targetName); | ||
targetsToRemove.push(targetName); | ||
} | ||
@@ -286,3 +285,3 @@ else if (target.executor === '@angular-devkit/build-angular:dev-server' || | ||
handleDevServerTargetOptions(tree, target.options, createConfigOptions.devServer, project.root); | ||
if (target.options.port !== DEFAULT_PORT) { | ||
if (target.options.port && target.options.port !== DEFAULT_PORT) { | ||
projectServePort = target.options.port; | ||
@@ -298,3 +297,4 @@ } | ||
} | ||
serveTargetNames.push(targetName); | ||
serveTarget = { name: targetName, config: target }; | ||
targetsToRemove.push(targetName); | ||
} | ||
@@ -320,7 +320,7 @@ else if (target.executor === '@angular-devkit/build-angular:prerender') { | ||
} | ||
buildTargetNames.push(targetName); | ||
targetsToRemove.push(targetName); | ||
} | ||
else if (target.executor === '@angular-devkit/build-angular:app-shell') { | ||
createConfigOptions.appShell = true; | ||
buildTargetNames.push(targetName); | ||
targetsToRemove.push(targetName); | ||
} | ||
@@ -333,11 +333,7 @@ } | ||
(0, update_tsconfig_1.updateTsconfig)(tree, project.root); | ||
for (const targetName of [...buildTargetNames, ...serveTargetNames]) { | ||
for (const targetName of targetsToRemove) { | ||
delete project.targets[targetName]; | ||
} | ||
if (projectServePort !== DEFAULT_PORT) { | ||
project.targets.serve ??= {}; | ||
project.targets.serve.options ??= {}; | ||
project.targets.serve.options.port = projectServePort; | ||
} | ||
(0, devkit_1.updateProjectConfiguration)(tree, projectName, project); | ||
// ensure plugin is registered | ||
const { rspackInitGenerator } = (0, devkit_1.ensurePackage)('@nx/rspack', versions_1.nxVersion); | ||
@@ -348,2 +344,155 @@ await rspackInitGenerator(tree, { | ||
}); | ||
// find the inferred target names | ||
const nxJson = (0, devkit_1.readNxJson)(tree); | ||
let inferredBuildTargetName = 'build'; | ||
let inferredServeTargetName = 'serve'; | ||
const pluginRegistration = nxJson.plugins.find((p) => typeof p === 'string' ? false : p.plugin === '@nx/rspack/plugin'); | ||
if (pluginRegistration) { | ||
inferredBuildTargetName = | ||
pluginRegistration.options.buildTargetName ?? inferredBuildTargetName; | ||
inferredServeTargetName = | ||
pluginRegistration.options.serveTargetName ?? inferredServeTargetName; | ||
} | ||
if (buildTarget) { | ||
// these are all replaced by the inferred task | ||
delete buildTarget.config.options; | ||
delete buildTarget.config.configurations; | ||
delete buildTarget.config.defaultConfiguration; | ||
delete buildTarget.config.executor; | ||
const shouldOverrideInputs = (inputs) => { | ||
if (!inputs?.length) { | ||
return false; | ||
} | ||
if (inputs.length === 2) { | ||
// check whether the existing inputs would match the inferred task | ||
// inputs with the exception of the @rspack/cli external dependency | ||
// which webpack tasks wouldn't have | ||
const namedInputs = (0, get_named_inputs_1.getNamedInputs)(project.root, { | ||
nxJsonConfiguration: nxJson, | ||
configFiles: [], | ||
workspaceRoot: devkit_1.workspaceRoot, | ||
}); | ||
if ('production' in namedInputs) { | ||
return !['production', '^production'].every((input) => inputs.includes(input)); | ||
} | ||
return !['default', '^default'].every((input) => inputs.includes(input)); | ||
} | ||
return true; | ||
}; | ||
if (shouldOverrideInputs(buildTarget.config.inputs)) { | ||
// keep existing inputs and add the @rspack/cli external dependency | ||
buildTarget.config.inputs = [ | ||
...buildTarget.config.inputs, | ||
{ externalDependencies: ['@rspack/cli'] }, | ||
]; | ||
} | ||
else { | ||
delete buildTarget.config.inputs; | ||
} | ||
if (buildTarget.config.cache) { | ||
delete buildTarget.config.cache; | ||
} | ||
if (buildTarget.config.dependsOn?.length === 1 && | ||
buildTarget.config.dependsOn[0] === `^${buildTarget.name}`) { | ||
delete buildTarget.config.dependsOn; | ||
} | ||
else if (buildTarget.config.dependsOn) { | ||
buildTarget.config.dependsOn = buildTarget.config.dependsOn.map((dep) => dep === `^${buildTarget.name}` ? `^${inferredBuildTargetName}` : dep); | ||
} | ||
const newOutputPath = (0, devkit_1.joinPathFragments)(project.root, createConfigOptions.outputPath.base); | ||
const shouldOverrideOutputs = (outputs) => { | ||
if (!outputs?.length) { | ||
// this means the target was wrongly configured, so, we don't override | ||
// anything and let the inferred outputs be used | ||
return false; | ||
} | ||
if (outputs.length === 1) { | ||
if (outputs[0] === '{options.outputPath}') { | ||
// the inferred task output is created after the createConfig | ||
// outputPath option, so we don't need to keep this | ||
return false; | ||
} | ||
const normalizedOutputPath = outputs[0] | ||
.replace('{workspaceRoot}/', '') | ||
.replace('{projectRoot}', project.root) | ||
.replace('{projectName}', ''); | ||
if (normalizedOutputPath === newOutputPath || | ||
normalizedOutputPath.replace(/\/browser\/?$/, '') === newOutputPath) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
}; | ||
const normalizeOutput = (path, workspaceRoot, projectRoot) => { | ||
const fullProjectRoot = (0, path_1.resolve)(workspaceRoot, projectRoot); | ||
const fullPath = (0, path_1.resolve)(workspaceRoot, path); | ||
const pathRelativeToProjectRoot = (0, devkit_1.normalizePath)((0, path_1.relative)(fullProjectRoot, fullPath)); | ||
if (pathRelativeToProjectRoot.startsWith('..')) { | ||
return (0, devkit_1.joinPathFragments)('{workspaceRoot}', (0, path_1.relative)(workspaceRoot, fullPath)); | ||
} | ||
return (0, devkit_1.joinPathFragments)('{projectRoot}', pathRelativeToProjectRoot); | ||
}; | ||
if (shouldOverrideOutputs(buildTarget.config.outputs)) { | ||
buildTarget.config.outputs = buildTarget.config.outputs.map((output) => { | ||
if (output === '{options.outputPath}') { | ||
// the target won't have an outputPath option, so we replace it with the new output path | ||
return normalizeOutput(newOutputPath, devkit_1.workspaceRoot, project.root); | ||
} | ||
const normalizedOutputPath = output | ||
.replace('{workspaceRoot}/', '') | ||
.replace('{projectRoot}', project.root) | ||
.replace('{projectName}', ''); | ||
if (/\/browser\/?$/.test(normalizedOutputPath) && | ||
normalizedOutputPath.replace(/\/browser\/?$/, '') === newOutputPath) { | ||
return normalizeOutput(newOutputPath, devkit_1.workspaceRoot, project.root); | ||
} | ||
return output; | ||
}); | ||
} | ||
else { | ||
delete buildTarget.config.outputs; | ||
} | ||
if (buildTarget.config.syncGenerators?.length === 1 && | ||
buildTarget.config.syncGenerators[0] === '@nx/js:typescript-sync') { | ||
delete buildTarget.config.syncGenerators; | ||
} | ||
else if (buildTarget.config.syncGenerators?.length) { | ||
buildTarget.config.syncGenerators = Array.from(new Set([ | ||
...buildTarget.config.syncGenerators, | ||
'@nx/js:typescript-sync', | ||
])); | ||
} | ||
if (Object.keys(buildTarget.config).length) { | ||
// there's extra target metadata left that wouldn't be inferred, we keep it | ||
project.targets[inferredBuildTargetName] = buildTarget.config; | ||
} | ||
} | ||
if (serveTarget) { | ||
delete serveTarget.config.options; | ||
delete serveTarget.config.configurations; | ||
delete serveTarget.config.defaultConfiguration; | ||
delete serveTarget.config.executor; | ||
if (serveTarget.config.continuous) { | ||
delete serveTarget.config.continuous; | ||
} | ||
if (serveTarget.config.syncGenerators?.length === 1 && | ||
serveTarget.config.syncGenerators[0] === '@nx/js:typescript-sync') { | ||
delete serveTarget.config.syncGenerators; | ||
} | ||
else if (serveTarget.config.syncGenerators?.length) { | ||
serveTarget.config.syncGenerators = Array.from(new Set([ | ||
...serveTarget.config.syncGenerators, | ||
'@nx/js:typescript-sync', | ||
])); | ||
} | ||
if (projectServePort !== DEFAULT_PORT) { | ||
serveTarget.config.options = {}; | ||
serveTarget.config.options.port = projectServePort; | ||
} | ||
if (Object.keys(serveTarget.config).length) { | ||
// there's extra target metadata left that wouldn't be inferred, we keep it | ||
project.targets[inferredServeTargetName] = serveTarget.config; | ||
} | ||
} | ||
(0, devkit_1.updateProjectConfiguration)(tree, projectName, project); | ||
// This is needed to prevent a circular execution of the build target | ||
@@ -350,0 +499,0 @@ const rootPkgJson = (0, devkit_1.readJson)(tree, 'package.json'); |
1503214
0.5%27538
0.54%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed