diff --git a/e2e/nx-plugin/src/nx-plugin.test.ts b/e2e/nx-plugin/src/nx-plugin.test.ts index 7920a2cdbd505..643db9a454c63 100644 --- a/e2e/nx-plugin/src/nx-plugin.test.ts +++ b/e2e/nx-plugin/src/nx-plugin.test.ts @@ -6,15 +6,20 @@ import { newProject, readJson, readProjectConfig, - readWorkspaceConfig, runCLI, runCLIAsync, uniq, - workspaceConfigName, + updateFile, + createFile, + readFile, + removeFile, } from '@nrwl/e2e/utils'; describe('Nx Plugin', () => { - beforeEach(() => newProject()); + let npmScope: string; + beforeEach(() => { + npmScope = newProject(); + }); it('should be able to generate a Nx Plugin ', async () => { const plugin = uniq('plugin'); @@ -172,6 +177,75 @@ describe('Nx Plugin', () => { }); }, 90000); + describe('local plugins', () => { + const plugin = uniq('plugin'); + beforeEach(() => { + runCLI(`generate @nrwl/nx-plugin:plugin ${plugin} --linter=eslint`); + }); + + it('should be able to infer projects and targets', async () => { + // Cache workspace json, to test inference and restore afterwards + const workspaceJsonContents = readFile('workspace.json'); + removeFile('workspace.json'); + + // Setup project inference + target inference + updateFile( + `libs/${plugin}/src/index.ts`, + `import {basename} from 'path' + + export function registerProjectTargets(f) { + if (basename(f) === 'my-project-file') { + return { + build: { + executor: "@nrwl/workspace:run-commands", + options: { + command: "echo 'custom registered target'" + } + } + } + } + } + + export const projectFilePatterns = ['my-project-file']; + ` + ); + + // Register plugin in nx.json (required for inference) + updateFile(`nx.json`, (nxJson) => { + const nx = JSON.parse(nxJson); + nx.plugins = [`@${npmScope}/${plugin}`]; + return JSON.stringify(nx, null, 2); + }); + + // Create project that should be inferred by Nx + const inferredProject = uniq('inferred'); + createFile(`libs/${inferredProject}/my-project-file`); + + // Attempt to use inferred project w/ Nx + expect(runCLI(`build ${inferredProject}`)).toContain( + 'custom registered target' + ); + + // Restore workspace.json + createFile('workspace.json', workspaceJsonContents); + }); + + it('should be able to use local generators and executors', async () => { + const generator = uniq('generator'); + const generatedProject = uniq('project'); + + runCLI( + `generate @nrwl/nx-plugin:generator ${generator} --project=${plugin}` + ); + + runCLI( + `generate @${npmScope}/${plugin}:${generator} --name ${generatedProject}` + ); + expect(() => checkFilesExist(`libs/${generatedProject}`)).not.toThrow(); + expect(() => runCLI(`build ${generatedProject}`)).not.toThrow(); + }); + }); + describe('--directory', () => { it('should create a plugin in the specified directory', () => { const plugin = uniq('plugin'); diff --git a/package.json b/package.json index 09335be476c2c..f38a15deb003d 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "@storybook/core": "~6.4.12", "@storybook/react": "~6.4.12", "@svgr/webpack": "^6.1.2", - "@swc/core": "^1.2.146", + "@swc/core": "^1.2.152", "@swc-node/register": "^1.4.2", "@testing-library/react": "11.2.6", "@testing-library/react-hooks": "7.0.1", diff --git a/packages/nx/package.json b/packages/nx/package.json index 52ba3612ed59c..87f886cfaa8a9 100644 --- a/packages/nx/package.json +++ b/packages/nx/package.json @@ -28,7 +28,7 @@ }, "homepage": "https://nx.dev", "dependencies": { - "@swc/core": "^1.2.146", + "@swc/core": "^1.2.152", "@swc-node/register": "^1.4.2", "chalk": "4.1.0", "enquirer": "~2.3.6", diff --git a/packages/nx/src/shared/nx-plugin.ts b/packages/nx/src/shared/nx-plugin.ts index ea47a8e42b2a8..18f71f7789e74 100644 --- a/packages/nx/src/shared/nx-plugin.ts +++ b/packages/nx/src/shared/nx-plugin.ts @@ -1,10 +1,18 @@ import { sync } from 'fast-glob'; import { existsSync } from 'fs'; -import { dirname, join } from 'path'; +import * as path from 'path'; + import { appRootPath } from '../utils/app-root'; import { readJsonFile } from '../utils/fileutils'; +import { registerTsProject } from '../utils/register'; +import { PackageJson } from './package-json'; import { ProjectGraphProcessor } from './project-graph'; -import { TargetConfiguration } from './workspace'; +import { Workspaces } from './workspace'; +import { + ProjectConfiguration, + TargetConfiguration, + WorkspaceJsonConfiguration, +} from './workspace.model'; export type ProjectTargetConfigurator = ( file: string @@ -25,30 +33,40 @@ export interface NxPlugin { projectFilePatterns?: string[]; } -function findPluginPackageJson(path: string, plugin: string) { - while (true) { - if (!path.startsWith(appRootPath)) { - throw new Error("Couldn't find a package.json for Nx plugin:" + plugin); - } - if (existsSync(join(path, 'package.json'))) { - return join(path, 'package.json'); - } - path = dirname(path); - } -} - +// Short lived cache (cleared between cmd runs) +// holding resolved nx plugin objects. +// Allows loadNxPlugins to be called multiple times w/o +// executing resolution mulitple times. let nxPluginCache: NxPlugin[] = null; -export function loadNxPlugins(plugins?: string[]): NxPlugin[] { +export function loadNxPlugins( + plugins?: string[], + paths = [appRootPath] +): NxPlugin[] { return plugins?.length ? nxPluginCache || - (nxPluginCache = plugins.map((path) => { - const pluginPath = require.resolve(path, { - paths: [appRootPath], - }); - - const { name } = readJsonFile( - findPluginPackageJson(pluginPath, path) - ); + (nxPluginCache = plugins.map((moduleName) => { + let pluginPath: string; + try { + pluginPath = require.resolve(moduleName, { + paths, + }); + } catch (e) { + if (e.code === 'MODULE_NOT_FOUND') { + const plugin = resolveLocalNxPlugin(moduleName); + const main = readPluginMainFromProjectConfiguration( + plugin.projectConfig + ); + pluginPath = main ? path.join(appRootPath, main) : plugin.path; + } else { + throw e; + } + } + const packageJsonPath = path.join(pluginPath, 'package.json'); + const { name } = + !['.ts', '.js'].some((x) => x === path.extname(pluginPath)) && // Not trying to point to a ts or js file + existsSync(packageJsonPath) // plugin has a package.json + ? readJsonFile(packageJsonPath) // read name from package.json + : { name: path.basename(pluginPath) }; // use the name of the file we point to const plugin = require(pluginPath) as NxPlugin; plugin.name = name; @@ -69,14 +87,151 @@ export function mergePluginTargetsWithNxTargets( } const projectFiles = sync(`+(${plugin.projectFilePatterns.join('|')})`, { - cwd: join(appRootPath, projectRoot), + cwd: path.join(appRootPath, projectRoot), }); for (const projectFile of projectFiles) { newTargets = { ...newTargets, - ...plugin.registerProjectTargets(join(projectRoot, projectFile)), + ...plugin.registerProjectTargets(path.join(projectRoot, projectFile)), }; } } return { ...newTargets, ...targets }; } + +export function readPluginPackageJson( + pluginName: string, + paths = [appRootPath] +): { + path: string; + json: PackageJson; +} { + let packageJsonPath: string; + try { + packageJsonPath = require.resolve(`${pluginName}/package.json`, { + paths, + }); + } catch (e) { + if (e.code === 'MODULE_NOT_FOUND') { + const localPluginPath = resolveLocalNxPlugin(pluginName); + if (localPluginPath) { + const localPluginPackageJson = path.join( + localPluginPath.path, + 'package.json' + ); + return { + path: localPluginPackageJson, + json: readJsonFile(localPluginPackageJson), + }; + } + } + throw e; + } + return { json: readJsonFile(packageJsonPath), path: packageJsonPath }; +} + +/** + * Builds a plugin package and returns the path to output + * @param importPath What is the import path that refers to a potential plugin? + * @returns The path to the built plugin, or null if it doesn't exist + */ +const localPluginCache: Record< + string, + { path: string; projectConfig: ProjectConfiguration } +> = {}; +export function resolveLocalNxPlugin( + importPath: string, + root = appRootPath +): { path: string; projectConfig: ProjectConfiguration } | null { + localPluginCache[importPath] ??= lookupLocalPlugin(importPath, root); + return localPluginCache[importPath]; +} + +let tsNodeAndPathsRegistered = false; +function registerTSTranspiler() { + if (!tsNodeAndPathsRegistered) { + registerTsProject(appRootPath, 'tsconfig.base.json'); + } + tsNodeAndPathsRegistered = true; +} + +function lookupLocalPlugin(importPath: string, root = appRootPath) { + const workspace = new Workspaces(root).readWorkspaceConfiguration({ + _ignorePluginInference: true, + }); + const plugin = findNxProjectForImportPath(importPath, workspace, root); + if (!plugin) { + return null; + } + + if (!tsNodeAndPathsRegistered) { + registerTSTranspiler(); + } + + const projectConfig = workspace.projects[plugin]; + return { path: path.join(root, projectConfig.root), projectConfig }; +} + +function findNxProjectForImportPath( + importPath: string, + workspace: WorkspaceJsonConfiguration, + root = appRootPath +): string | null { + const tsConfigPaths: Record = readTsConfigPaths(root); + const possiblePaths = tsConfigPaths[importPath]?.map((p) => + path.resolve(root, p) + ); + if (tsConfigPaths[importPath]) { + const projectRootMappings = Object.entries(workspace.projects).reduce( + (m, [project, config]) => { + m[path.resolve(root, config.root)] = project; + return m; + }, + {} + ); + for (const root of Object.keys(projectRootMappings)) { + if (possiblePaths.some((p) => p.startsWith(root))) { + return projectRootMappings[root]; + } + } + if (process.env.NX_VERBOSE_LOGGING) { + console.log( + 'Unable to find local plugin', + possiblePaths, + projectRootMappings + ); + } + throw new Error( + 'Unable to resolve local plugin with import path ' + importPath + ); + } +} + +let tsconfigPaths: Record; +function readTsConfigPaths(root: string = appRootPath) { + if (!tsconfigPaths) { + const tsconfigPath: string | null = ['tsconfig.base.json', 'tsconfig.json'] + .map((x) => path.join(root, x)) + .filter((x) => existsSync(x))[0]; + if (!tsconfigPath) { + throw new Error('unable to find tsconfig.base.json or tsconfig.json'); + } + const { compilerOptions } = readJsonFile(tsconfigPath); + tsconfigPaths = compilerOptions?.paths; + } + return tsconfigPaths; +} + +function readPluginMainFromProjectConfiguration( + plugin: ProjectConfiguration +): string | null { + const { main } = + Object.values(plugin.targets).find((x) => + ['@nrwl/js:tsc', '@nrwl/js:swc', '@nrwl/node:package'].includes( + x.executor + ) + )?.options || + plugin.targets?.build?.options || + {}; + return main; +} diff --git a/packages/nx/src/shared/workspace.model.ts b/packages/nx/src/shared/workspace.model.ts new file mode 100644 index 0000000000000..f39f828bef1d6 --- /dev/null +++ b/packages/nx/src/shared/workspace.model.ts @@ -0,0 +1,243 @@ +import { NxJsonConfiguration } from './nx'; +import { TaskGraph } from './tasks'; + +export interface Workspace + extends WorkspaceJsonConfiguration, + NxJsonConfiguration { + projects: Record; +} + +/** + * Workspace configuration + */ +export interface WorkspaceJsonConfiguration { + /** + * Version of the configuration format + */ + version: number; + /** + * Projects' projects + */ + projects: { + [projectName: string]: ProjectConfiguration; + }; +} + +export interface RawWorkspaceJsonConfiguration + extends Omit { + projects: { [projectName: string]: ProjectConfiguration | string }; +} + +/** + * Type of project supported + */ +export type ProjectType = 'library' | 'application'; + +/** + * Project configuration + */ +export interface ProjectConfiguration { + /** + * Project's name. Optional if specified in workspace.json + */ + name?: string; + + /** + * Project's targets + */ + targets?: { [targetName: string]: TargetConfiguration }; + + /** + * Project's location relative to the root of the workspace + */ + root: string; + + /** + * The location of project's sources relative to the root of the workspace + */ + sourceRoot?: string; + + /** + * Project type + */ + projectType?: ProjectType; + + /** + * List of default values used by generators. + * + * These defaults are project specific. + * + * Example: + * + * ``` + * { + * "@nrwl/react": { + * "library": { + * "style": "scss" + * } + * } + * } + * ``` + */ + generators?: { [collectionName: string]: { [generatorName: string]: any } }; + + /** + * List of projects which are added as a dependency + */ + implicitDependencies?: string[]; + + /** + * List of tags used by nx-enforce-module-boundaries / project graph + */ + tags?: string[]; +} + +export interface TargetDependencyConfig { + /** + * This the projects that the targets belong to + * + * 'self': This target depends on another target of the same project + * 'deps': This target depends on targets of the projects of it's deps. + */ + projects: 'self' | 'dependencies'; + + /** + * The name of the target + */ + target: string; +} + +/** + * Target's configuration + */ +export interface TargetConfiguration { + /** + * The executor/builder used to implement the target. + * + * Example: '@nrwl/web:rollup' + */ + executor: string; + + /** + * List of the target's outputs. The outputs will be cached by the Nx computation + * caching engine. + */ + outputs?: string[]; + + /** + * This describes other targets that a target depends on. + */ + dependsOn?: TargetDependencyConfig[]; + + /** + * Target's options. They are passed in to the executor. + */ + options?: any; + + /** + * Sets of options + */ + configurations?: { [config: string]: any }; + + /** + * A default named configuration to use when a target configuration is not provided. + */ + defaultConfiguration?: string; +} + +/** + * A callback function that is executed after changes are made to the file system + */ +export type GeneratorCallback = () => void | Promise; + +/** + * A function that schedules updates to the filesystem to be done atomically + */ +export type Generator = ( + tree, + schema: T +) => void | GeneratorCallback | Promise; + +export interface ExecutorConfig { + schema: any; + hasherFactory?: () => any; + implementationFactory: () => Executor; + batchImplementationFactory?: () => TaskGraphExecutor; +} + +/** + * Implementation of a target of a project + */ +export type Executor = ( + /** + * Options that users configure or pass via the command line + */ + options: T, + context: ExecutorContext +) => + | Promise<{ success: boolean }> + | AsyncIterableIterator<{ success: boolean }>; + +/** + * Implementation of a target of a project that handles multiple projects to be batched + */ +export type TaskGraphExecutor = ( + /** + * Graph of Tasks to be executed + */ + taskGraph: TaskGraph, + /** + * Map of Task IDs to options for the task + */ + options: Record, + /** + * Set of overrides for the overall execution + */ + overrides: T, + context: ExecutorContext +) => Promise>; + +/** + * Context that is passed into an executor + */ +export interface ExecutorContext { + /** + * The root of the workspace + */ + root: string; + + /** + * The name of the project being executed on + */ + projectName?: string; + + /** + * The name of the target being executed + */ + targetName?: string; + + /** + * The name of the configuration being executed + */ + configurationName?: string; + + /** + * The configuration of the target being executed + */ + target?: TargetConfiguration; + + /** + * The full workspace configuration + */ + workspace: WorkspaceJsonConfiguration & NxJsonConfiguration; + + /** + * The current working directory + */ + cwd: string; + + /** + * Enable verbose logging + */ + isVerbose: boolean; +} diff --git a/packages/nx/src/shared/workspace.ts b/packages/nx/src/shared/workspace.ts index 7ceb7a869d11a..ba79a684cd7dc 100644 --- a/packages/nx/src/shared/workspace.ts +++ b/packages/nx/src/shared/workspace.ts @@ -1,159 +1,25 @@ +import { sync as globSync } from 'fast-glob'; import { existsSync, readFileSync } from 'fs'; +import ignore, { Ignore } from 'ignore'; import * as path from 'path'; +import { performance } from 'perf_hooks'; + import { appRootPath } from '../utils/app-root'; import { readJsonFile } from '../utils/fileutils'; -import type { NxJsonConfiguration } from './nx'; -import { TaskGraph } from './tasks'; import { logger } from './logger'; -import { sync as globSync } from 'fast-glob'; -import ignore, { Ignore } from 'ignore'; -import { basename, dirname, join } from 'path'; -import { performance } from 'perf_hooks'; -import { loadNxPlugins } from './nx-plugin'; - -export interface Workspace - extends WorkspaceJsonConfiguration, - NxJsonConfiguration { - projects: Record; -} - -/** - * Workspace configuration - */ -export interface WorkspaceJsonConfiguration { - /** - * Version of the configuration format - */ - version: number; - /** - * Projects' projects - */ - projects: { - [projectName: string]: ProjectConfiguration; - }; -} - -export interface RawWorkspaceJsonConfiguration - extends Omit { - projects: { [projectName: string]: ProjectConfiguration | string }; -} - -/** - * Type of project supported - */ -export type ProjectType = 'library' | 'application'; - -/** - * Project configuration - */ -export interface ProjectConfiguration { - /** - * Project's name. Optional if specified in workspace.json - */ - name?: string; - - /** - * Project's targets - */ - targets?: { [targetName: string]: TargetConfiguration }; - - /** - * Project's location relative to the root of the workspace - */ - root: string; - - /** - * The location of project's sources relative to the root of the workspace - */ - sourceRoot?: string; - - /** - * Project type - */ - projectType?: ProjectType; - - /** - * List of default values used by generators. - * - * These defaults are project specific. - * - * Example: - * - * ``` - * { - * "@nrwl/react": { - * "library": { - * "style": "scss" - * } - * } - * } - * ``` - */ - generators?: { [collectionName: string]: { [generatorName: string]: any } }; - - /** - * List of projects which are added as a dependency - */ - implicitDependencies?: string[]; - - /** - * List of tags used by nx-enforce-module-boundaries / project graph - */ - tags?: string[]; -} - -export interface TargetDependencyConfig { - /** - * This the projects that the targets belong to - * - * 'self': This target depends on another target of the same project - * 'deps': This target depends on targets of the projects of it's deps. - */ - projects: 'self' | 'dependencies'; - - /** - * The name of the target - */ - target: string; -} - -/** - * Target's configuration - */ -export interface TargetConfiguration { - /** - * The executor/builder used to implement the target. - * - * Example: '@nrwl/web:rollup' - */ - executor: string; - - /** - * List of the target's outputs. The outputs will be cached by the Nx computation - * caching engine. - */ - outputs?: string[]; - - /** - * This describes other targets that a target depends on. - */ - dependsOn?: TargetDependencyConfig[]; - - /** - * Target's options. They are passed in to the executor. - */ - options?: any; - - /** - * Sets of options - */ - configurations?: { [config: string]: any }; +import { loadNxPlugins, readPluginPackageJson } from './nx-plugin'; +import { + Executor, + ExecutorConfig, + Generator, + ProjectConfiguration, + TaskGraphExecutor, + WorkspaceJsonConfiguration, +} from './workspace.model'; - /** - * A default named configuration to use when a target configuration is not provided. - */ - defaultConfiguration?: string; -} +import type { NxJsonConfiguration } from './nx'; +import { basename, dirname, join } from 'path'; +export * from './workspace.model'; export function workspaceConfigName(root: string) { if (existsSync(path.join(root, 'angular.json'))) { @@ -165,103 +31,6 @@ export function workspaceConfigName(root: string) { } } -/** - * A callback function that is executed after changes are made to the file system - */ -export type GeneratorCallback = () => void | Promise; - -/** - * A function that schedules updates to the filesystem to be done atomically - */ -export type Generator = ( - tree, - schema: T -) => void | GeneratorCallback | Promise; - -export interface ExecutorConfig { - schema: any; - hasherFactory?: () => any; - implementationFactory: () => Executor; - batchImplementationFactory?: () => TaskGraphExecutor; -} - -/** - * Implementation of a target of a project - */ -export type Executor = ( - /** - * Options that users configure or pass via the command line - */ - options: T, - context: ExecutorContext -) => - | Promise<{ success: boolean }> - | AsyncIterableIterator<{ success: boolean }>; - -/** - * Implementation of a target of a project that handles multiple projects to be batched - */ -export type TaskGraphExecutor = ( - /** - * Graph of Tasks to be executed - */ - taskGraph: TaskGraph, - /** - * Map of Task IDs to options for the task - */ - options: Record, - /** - * Set of overrides for the overall execution - */ - overrides: T, - context: ExecutorContext -) => Promise>; - -/** - * Context that is passed into an executor - */ -export interface ExecutorContext { - /** - * The root of the workspace - */ - root: string; - - /** - * The name of the project being executed on - */ - projectName?: string; - - /** - * The name of the target being executed - */ - targetName?: string; - - /** - * The name of the configuration being executed - */ - configurationName?: string; - - /** - * The configuration of the target being executed - */ - target?: TargetConfiguration; - - /** - * The full workspace configuration - */ - workspace: WorkspaceJsonConfiguration & NxJsonConfiguration; - - /** - * The current working directory - */ - cwd: string; - - /** - * Enable verbose logging - */ - isVerbose: boolean; -} - export class Workspaces { private cachedWorkspaceConfig: WorkspaceJsonConfiguration & NxJsonConfiguration; @@ -290,8 +59,9 @@ export class Workspaces { return wc.defaultProject; } - readWorkspaceConfiguration(): WorkspaceJsonConfiguration & - NxJsonConfiguration { + readWorkspaceConfiguration(opts?: { + _ignorePluginInference?: boolean; + }): WorkspaceJsonConfiguration & NxJsonConfiguration { if (this.cachedWorkspaceConfig) return this.cachedWorkspaceConfig; const nxJsonPath = path.join(this.root, 'nx.json'); const nxJson = readNxJson(nxJsonPath); @@ -304,7 +74,11 @@ export class Workspaces { ? this.readFromWorkspaceJson() : buildWorkspaceConfigurationFromGlobs( nxJson, - globForProjectFiles(this.root, nxJson), + globForProjectFiles( + this.root, + nxJson, + opts?._ignorePluginInference + ), (path) => readJsonFile(join(this.root, path)) ); @@ -407,10 +181,10 @@ export class Workspaces { } private readExecutorsJson(nodeModule: string, executor: string) { - const packageJsonPath = require.resolve(`${nodeModule}/package.json`, { - paths: this.resolvePaths(), - }); - const packageJson = readJsonFile(packageJsonPath); + const { json: packageJson, path: packageJsonPath } = readPluginPackageJson( + nodeModule, + this.resolvePaths() + ); const executorsFile = packageJson.executors ?? packageJson.builders; if (!executorsFile) { @@ -445,13 +219,8 @@ export class Workspaces { paths: this.resolvePaths(), }); } else { - const packageJsonPath = require.resolve( - `${collectionName}/package.json`, - { - paths: this.resolvePaths(), - } - ); - const packageJson = readJsonFile(packageJsonPath); + const { json: packageJson, path: packageJsonPath } = + readPluginPackageJson(collectionName, this.resolvePaths()); const generatorsFile = packageJson.generators ?? packageJson.schematics; if (!generatorsFile) { @@ -707,8 +476,9 @@ function getGlobPatternsFromPackageManagerWorkspaces(root: string): string[] { } export function globForProjectFiles( - root: string, - nxJson?: NxJsonConfiguration + root, + nxJson?: NxJsonConfiguration, + ignorePluginInference = false ) { // Deal w/ Caching const cacheKey = [root, ...(nxJson?.plugins || [])].join(','); @@ -719,9 +489,12 @@ export function globForProjectFiles( const projectGlobPatterns: string[] = [ '**/project.json', ...getGlobPatternsFromPackageManagerWorkspaces(root), - ...getGlobPatternsFromPlugins(nxJson), ]; + if (!ignorePluginInference) { + projectGlobPatterns.push(...getGlobPatternsFromPlugins(nxJson)); + } + const combinedProjectGlobPattern = '{' + projectGlobPatterns.join(',') + '}'; performance.mark('start-glob-for-projects'); @@ -820,7 +593,7 @@ export function inferProjectFromNonStandardFile( export function buildWorkspaceConfigurationFromGlobs( nxJson: NxJsonConfiguration, - projectFiles: string[] = globForProjectFiles(appRootPath, nxJson), // making this parameter allows devkit to pick up newly created projects + projectFiles: string[], // making this parameter allows devkit to pick up newly created projects readJson: (string) => any = readJsonFile // making this an arg allows us to reuse in devkit ): WorkspaceJsonConfiguration { const projects: Record = {}; diff --git a/packages/nx/src/utils/register.ts b/packages/nx/src/utils/register.ts index 4c7d1895b868b..65686786f77d0 100644 --- a/packages/nx/src/utils/register.ts +++ b/packages/nx/src/utils/register.ts @@ -1,5 +1,3 @@ -import { readDefaultTsConfig } from '@swc-node/register/read-default-tsconfig'; -import { register } from '@swc-node/register/register'; import { join } from 'path'; /** @@ -14,22 +12,32 @@ export const registerTsProject = ( path: string, configFilename = 'tsconfig.json' ) => { + // These are requires to prevent it from registering when it shouldn't + const { register } = require('@swc-node/register/register'); + const { + readDefaultTsConfig, + } = require('@swc-node/register/read-default-tsconfig'); + try { - const tsConfig = readDefaultTsConfig(join(path, configFilename)); + const tsConfigPath = join(path, configFilename); + const tsConfig = readDefaultTsConfig(tsConfigPath); register(tsConfig); /** * Load the ts config from the source project */ - const tsconfigPaths = require('tsconfig-paths'); - const tsConfigResult = tsconfigPaths.loadConfig(path); + const tsconfigPaths: typeof import('tsconfig-paths') = require('tsconfig-paths'); + const tsConfigResult = tsconfigPaths.loadConfig(tsConfigPath); /** * Register the custom workspace path mappings with node so that workspace libraries * can be imported and used within project */ - return tsconfigPaths.register({ - baseUrl: tsConfigResult.absoluteBaseUrl, - paths: tsConfigResult.paths, - }); + if (tsConfigResult.resultType === 'success') { + return tsconfigPaths.register({ + baseUrl: tsConfigResult.absoluteBaseUrl, + paths: tsConfigResult.paths, + }); + } } catch (err) {} + return () => {}; }; diff --git a/yarn.lock b/yarn.lock index 8ed9ff0b27ab8..da26a42e08449 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5474,130 +5474,130 @@ resolved "https://registry.yarnpkg.com/@swc/core-android-arm-eabi/-/core-android-arm-eabi-1.2.133.tgz#dea04365897889c6f827ceb544ea241c90f02709" integrity sha512-S6gc8Z1zhkDmMRwjeGp5Wf8zE+Vwc5m3weSltUTxbO27r48X6A8R2egM48ci/muPTPA6mOWQTViTFcq/hEgV2w== -"@swc/core-android-arm-eabi@1.2.146": - version "1.2.146" - resolved "https://registry.yarnpkg.com/@swc/core-android-arm-eabi/-/core-android-arm-eabi-1.2.146.tgz#027c9b0c57377ce6cf4c7806ba07acf156e70d3a" - integrity sha512-vRlxDksEDdprqfj9VACYUGyCJr/tYLetNjhjel46qmKoXU5uAib1WLWWgMB1Ur+oh8eCSTN8cnOblOziqfC1Rw== +"@swc/core-android-arm-eabi@1.2.152": + version "1.2.152" + resolved "https://registry.yarnpkg.com/@swc/core-android-arm-eabi/-/core-android-arm-eabi-1.2.152.tgz#13973b6f44692121e1b553a069ebc7a97f7b3aa8" + integrity sha512-Vl4mHTL5mEDqPiJMLAqwsTvsl8aREudjUmEfjmM7C+ZcD0W+lNpzpZInbWIaVblNLj04wXoKR2JOpxUC43yy1Q== "@swc/core-android-arm64@1.2.133": version "1.2.133" resolved "https://registry.yarnpkg.com/@swc/core-android-arm64/-/core-android-arm64-1.2.133.tgz#9467327193885692d6b9204599bcb16863e3ccab" integrity sha512-rlsJ+UCk6QOUVde2l4yeM32R04KbnOM6a2WBw43f5IA8M8PDlWdRNHFE3jiwCIwBoG6MJ+EJE2PPmjxr3iSWvw== -"@swc/core-android-arm64@1.2.146": - version "1.2.146" - resolved "https://registry.yarnpkg.com/@swc/core-android-arm64/-/core-android-arm64-1.2.146.tgz#e906088244bab3672ef4c40bd0631d2a09ab51fd" - integrity sha512-YoJygRvjZ6IXvWstYZHGThEj1aWshzoMohX0i6WH5NIZhkzeF0UhRu/IZoS9VcQsd0WtDEMQe0G0wcrd/FToNg== +"@swc/core-android-arm64@1.2.152": + version "1.2.152" + resolved "https://registry.yarnpkg.com/@swc/core-android-arm64/-/core-android-arm64-1.2.152.tgz#40f0e870c6f85e3a2c2fe4cb22e8e293e5f2b072" + integrity sha512-+Xwe882tK1cyVViZhSNYSQmpLtuYIVGw2AvKsrP+VjWf9giiL4Y0Faj6w8KoC24THSxgSX2OTMzw71C+yduj2g== "@swc/core-darwin-arm64@1.2.133": version "1.2.133" resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.133.tgz#95e6d46a8406c4b09e96eec4a3f0bad270285744" integrity sha512-COktqzeii453+JCGwgIM8vs4y4bgbIzY2lvSEYQmxZRVMAkqQVviLqG4cjm9tYHrW0o+9zpw+XTgpdPpkg32Yg== -"@swc/core-darwin-arm64@1.2.146": - version "1.2.146" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.146.tgz#e47a8f5c1b18278c1005007121553a3d01d15622" - integrity sha512-ftAyhczQHSUQo1Mox/VyZ3YL9KtG0LgOFUUUuLD3Pb9zKQB20Jc/Dfnh/bFktemVG8XiH0rOyR9yEI2EANHuEA== +"@swc/core-darwin-arm64@1.2.152": + version "1.2.152" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.152.tgz#50dd61942cade2bcb0a33813855a6e00a9dd130f" + integrity sha512-UGhzOz8KC3uT1Uzjttv9Gxd4bAXIgyjJ338eI0hxmwXDauoiPYK6PylhmQr91ExNmDnXJH4WkP9UME3fk5JgVg== "@swc/core-darwin-x64@1.2.133": version "1.2.133" resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.2.133.tgz#d40999cb465a160c1226fef42df31c7be1ed4999" integrity sha512-H5Hk+qWotdgVQOuQZdSMmIo4KUGxJjfVVBBbKe+TG1Vqyo5SQderc9TUZH8UzMP/tlX83Nzin0FHB+Ui9UhYqA== -"@swc/core-darwin-x64@1.2.146": - version "1.2.146" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.2.146.tgz#5e9a2d9fe1049ec8cdaec265b73781eb08579365" - integrity sha512-mYRN/WTS7TfYt3jqJYghcrpAW7zkpjdeEx9Rot8rmUEmk97luh9Bcwqafzjb9ndoG1mAiaTQcqvs/QqT2efS5Q== +"@swc/core-darwin-x64@1.2.152": + version "1.2.152" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.2.152.tgz#71156a7abb6d67da8f9e248631e1cf23340fe470" + integrity sha512-2B18L/mD2I5r7OJJjZzikXrzj9+9+izRgSbg9Unwo33eUwtlKrk4gT/iV5FaNjHDeWpJ8+SPquFyic8Plq6rGQ== "@swc/core-freebsd-x64@1.2.133": version "1.2.133" resolved "https://registry.yarnpkg.com/@swc/core-freebsd-x64/-/core-freebsd-x64-1.2.133.tgz#0968766e4ff69509ae347e4fed3accb1f1e97c53" integrity sha512-eFYkZLyAghY90w7CfwHsQ7/doJ46QSlmMGA9qR9NEuPt9MthM84ZXE6d20BvOid0zeib2o6HdFzfaAkS09/hvA== -"@swc/core-freebsd-x64@1.2.146": - version "1.2.146" - resolved "https://registry.yarnpkg.com/@swc/core-freebsd-x64/-/core-freebsd-x64-1.2.146.tgz#6bda670ae5abb05abecb51d832950b3c159289d1" - integrity sha512-eYU5g7p/dY98+hvg3VJtwiX+btRWnq+WO4y4M+X1nguqghvuTv6jtVLeHDNr8FEhc+FMSJPYKO321ZVa0xCKXw== +"@swc/core-freebsd-x64@1.2.152": + version "1.2.152" + resolved "https://registry.yarnpkg.com/@swc/core-freebsd-x64/-/core-freebsd-x64-1.2.152.tgz#6a36556c68a1e44ec792462f4bcb8fe054901175" + integrity sha512-fe/qqSX14uKFWYN/72BmjSl3DEgK1M5+bJnJpbHFoPePEf3Jv5Vwwo/dq6YxGf4ITo5O8++/9VAkq346vhAHAg== "@swc/core-linux-arm-gnueabihf@1.2.133": version "1.2.133" resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.133.tgz#fcbefd1783c8fbde44d965ec0fb051387c3c92a9" integrity sha512-oB9L0Xs6cfOYUr7Qc8tpPd3IpY3dXIaJZ/OZQqFhIQFzeMZVApaLBeyfX+gwH8d8wgceuPj4HeyZE+IWw2GTJQ== -"@swc/core-linux-arm-gnueabihf@1.2.146": - version "1.2.146" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.146.tgz#f37f6876cfd42bb58037f7c3b2dd13b58f1cf40d" - integrity sha512-ahKwlP9b41HUlwY+0eRJjgG4yJZN+uT16iBB2X7VedipmRO0aOOaP8xLReDjn4Z13DL14iAPC6Jnxiaw5rl8LQ== +"@swc/core-linux-arm-gnueabihf@1.2.152": + version "1.2.152" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.152.tgz#8852fffa5a676efab94742416d62ca156c07dba5" + integrity sha512-Vqn9O7AK9GlGGTwvJ8Ze+3XyDS/DSAnEVaC4VMk1c6fWh4xHXxmEdnhVGKt+nWpxU/mRir5ayTCcUSd/ia7ogw== "@swc/core-linux-arm64-gnu@1.2.133": version "1.2.133" resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.133.tgz#2d2986824aaf1dd58c4b4e173d6186b7e2073d54" integrity sha512-SF0Yviv+9L1ELsn578/TJd44rIhqbGGAD+AgpyJB8YGoFTAFUTnoAhFYNEPOEfbf/IQyWcyHk3vAZ7a2VPRIFg== -"@swc/core-linux-arm64-gnu@1.2.146": - version "1.2.146" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.146.tgz#9daed25cbcc3fcfbf792fadc26b0d13a1bd8a130" - integrity sha512-S/0EJI8BWBQtsyIuYwVg+Gq03NlGl/xWOJgwLJss5+DawvxK8YZFteczw7M/bN/E5D2TqZRyybLM6baQozgDAg== +"@swc/core-linux-arm64-gnu@1.2.152": + version "1.2.152" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.152.tgz#69f656caeaceb6bac813aae65cb7848036a52f43" + integrity sha512-79hGkWLS0H2l6tMJpdsFacTh8PmHdRIg8vfs5cHn9mNvXTKLOrIHe9eUwiYGrM2XyYVQikebaXyJXjJIOoMw9Q== "@swc/core-linux-arm64-musl@1.2.133": version "1.2.133" resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.2.133.tgz#9daae6e86b9c692aecdaa6109721a5ff00d114ad" integrity sha512-tZiqwz7dTOxnGMwnYguULKl6gNom6CQWXoUyoliksaZA6+uNALO1/PNh/ctzuDbu2Agj4ltsmoevhZlrzC3geA== -"@swc/core-linux-arm64-musl@1.2.146": - version "1.2.146" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.2.146.tgz#af5bdc23160fbb9db49ea1f05580000baabde063" - integrity sha512-tOHcanuqgniMwUWMwjA+zr/hZyVn931l8DiIi3Mthyplp/PDY68PVAUJ8miJd4C5XDPcYfPOe5kRyXsFrdZzhw== +"@swc/core-linux-arm64-musl@1.2.152": + version "1.2.152" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.2.152.tgz#643bfb37e3379e1ff1bff0726175a62bc1a7daf7" + integrity sha512-Rb81Ds1J+0swDrmqsL9dgowiNtVy+1Rf09kC9oKHSWYt2qXWacul8r42O5s1BPK8K5O/6ufj8stYU+g92YjARg== "@swc/core-linux-x64-gnu@1.2.133": version "1.2.133" resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.133.tgz#77439a67f2e39125b2f6c5c62d70accaf5140323" integrity sha512-xXx+/x9y803chUtOqsETvZjimCEiFNcYobsV4wDzlO/E9njrDhmteGcHOv5C6cGSfP6H8tG+hL1JlqJQm+hPSQ== -"@swc/core-linux-x64-gnu@1.2.146": - version "1.2.146" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.146.tgz#aeef122f0b313fb95438e209f22697ddb3da5c7d" - integrity sha512-w9jHnFe1XLYfQYWkaJwKgmtb/HKsgyFy0sCQpVjgDq/+ds8PPyACthDINpiEMsAOFN+IfE59HDn4A2gN3qyVgg== +"@swc/core-linux-x64-gnu@1.2.152": + version "1.2.152" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.152.tgz#952811c3946181568f8bbb77ec54af65cceade42" + integrity sha512-K8uOIO594Mpr9KXUVc7grGfT5KU3wh/BZwUVHBSVaYbCCgwxitHDDQR3KzvYpZSKjx/YwLwRWXZuo0dxmw+NcQ== "@swc/core-linux-x64-musl@1.2.133": version "1.2.133" resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.133.tgz#f37122c608d9392a3dbda4189e1d68db46f49614" integrity sha512-LnLY5MnwG/L7U+FC/k5LU4K7h+kz5/fo8DC507BncSZj5LLxT9ohhCxO+iUp7qKGw+UQFgSUgUinh1I8FfV6cQ== -"@swc/core-linux-x64-musl@1.2.146": - version "1.2.146" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.146.tgz#d146fd167e9d84a08637a9e1d535b04f2204bd99" - integrity sha512-iwKiHvV8p48/82+eJRCy/WcnAZBOFr2ZJ5VLtRuV+sz0mkWjoimnLZ8SEshoru9PVoKF7hfG7AMqKaVOUjSJFg== +"@swc/core-linux-x64-musl@1.2.152": + version "1.2.152" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.152.tgz#2aaf759689a3569de28c2c200f000918520e98a1" + integrity sha512-Q34NF30LM5vynfyCTZNR+Co0AT/0TsLoeXOxkroT9GOfQ+UcsawFs1ZCTBdX15Jv8MXrqZAw5FwcaSReuG58rw== "@swc/core-win32-arm64-msvc@1.2.133": version "1.2.133" resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.2.133.tgz#322ea6234182005a81a2b3e64d3e35273057bd8c" integrity sha512-Fk4D8v56TOhoP5lRFSoZqWXt8enCdHGbZsSIdz7DSjQyS/VeePXdoZI8vmWUcuy2OSquQ4hpS2o1v3wVSREWiw== -"@swc/core-win32-arm64-msvc@1.2.146": - version "1.2.146" - resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.2.146.tgz#23b52c4fdcf1395861eb915924285b7857c3db68" - integrity sha512-n21riIEGTPim19Y0mrBIDVZfOrYdfd2W8QEgbiG/f+kcOlWckvyh9ZKexd6D8QpHe73C4lOX1RrmH3DgnPGhqA== +"@swc/core-win32-arm64-msvc@1.2.152": + version "1.2.152" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.2.152.tgz#5fcb9d6956f53cbeb9d8fa76bcd65f93aa74d27f" + integrity sha512-i9QaNgntUDDrgj8k3ZyUh3HjGgG3aKa2diPCKR+fPArfFpN352mW3pC4EgSj+gF0FdgmTPnRGzT/n/kq770xqg== "@swc/core-win32-ia32-msvc@1.2.133": version "1.2.133" resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.133.tgz#b9766f17821ce3ae7010577174df2549f92a8a07" integrity sha512-Sf9UmXSPFr7308OSDfIIU0iLRfzilWlnVfVzUfWLd02Z9t5awBxNYCAZrXxny4FUvTDK9qL+/uY378bFH6tYiw== -"@swc/core-win32-ia32-msvc@1.2.146": - version "1.2.146" - resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.146.tgz#3e56db016661cf877b8ae39056fadbb14ec17eef" - integrity sha512-5b99VzxvTqTQCZDmpKrGevUc9SK0QBiGZG4Oeh5CnSJyx8SZU0A3R7rbMoSR5/raP9OA/0ZvlXefUDXIsKNadA== +"@swc/core-win32-ia32-msvc@1.2.152": + version "1.2.152" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.152.tgz#5914ad121316949d9150928785632879ca7e17b2" + integrity sha512-HFtEADtw8EF4Rcp87smgEcrm1h2bUVIMshN77K3nzNnjoKRqkTCXpcEaYWzW0pKovEDscHUGQ+YC7LVVAGayMA== "@swc/core-win32-x64-msvc@1.2.133": version "1.2.133" resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.133.tgz#5afc09724bac622e6f40ce6cd5e901e1458aad98" integrity sha512-nXZJihzwUjzzF78ipPp+uUWmLQtbFzuR5eADNk1MsnHgWflKaL5OXNVz5c8+qyTl5/c3/W1b4GSevFOfEuApxw== -"@swc/core-win32-x64-msvc@1.2.146": - version "1.2.146" - resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.146.tgz#e9010b06fbfebdc745d2dd324b752ddd4f685bc9" - integrity sha512-P45vAh0hR9dISIceSv6MkypjT0WduLWB4U8LPoCneeAw7mA1U7liS0Uu1PeiafxQVMWg8SNyIJFDcSg/haLJgg== +"@swc/core-win32-x64-msvc@1.2.152": + version "1.2.152" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.152.tgz#06cab0ab1e71d5f71074b0fad72d2396c3479675" + integrity sha512-zdSzmtlwaJga/48KQncKIo9vH1miS40Gr/TJ2QGtMU7u3XyiFz/PL8BDYQFLqSEWSSRcAwVpm6Mucb30mvuf7Q== "@swc/core@^1.2.119": version "1.2.133" @@ -5618,24 +5618,24 @@ "@swc/core-win32-ia32-msvc" "1.2.133" "@swc/core-win32-x64-msvc" "1.2.133" -"@swc/core@^1.2.146": - version "1.2.146" - resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.2.146.tgz#dd86c65d101e1414f9d5a14a22c3541dd4dcfeef" - integrity sha512-axIapm2mReT45ILuYxwe0xEWqtITj3dyfDIGIgdC8Tx7ss5vpXvr22UbDSUTRIS+nypFy6hViIR1RhXE1hXnig== +"@swc/core@^1.2.152": + version "1.2.152" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.2.152.tgz#cc2329ebc6379564a4c54250c9596658ea2e784e" + integrity sha512-ZklzoNsvEUWqc73BdYvM+F97N+ghwa01Fd49Hpt6abqYz8ZCvXkY2Hloe0HuppCX4BKCaMDfCgDtWMBqCacSKw== optionalDependencies: - "@swc/core-android-arm-eabi" "1.2.146" - "@swc/core-android-arm64" "1.2.146" - "@swc/core-darwin-arm64" "1.2.146" - "@swc/core-darwin-x64" "1.2.146" - "@swc/core-freebsd-x64" "1.2.146" - "@swc/core-linux-arm-gnueabihf" "1.2.146" - "@swc/core-linux-arm64-gnu" "1.2.146" - "@swc/core-linux-arm64-musl" "1.2.146" - "@swc/core-linux-x64-gnu" "1.2.146" - "@swc/core-linux-x64-musl" "1.2.146" - "@swc/core-win32-arm64-msvc" "1.2.146" - "@swc/core-win32-ia32-msvc" "1.2.146" - "@swc/core-win32-x64-msvc" "1.2.146" + "@swc/core-android-arm-eabi" "1.2.152" + "@swc/core-android-arm64" "1.2.152" + "@swc/core-darwin-arm64" "1.2.152" + "@swc/core-darwin-x64" "1.2.152" + "@swc/core-freebsd-x64" "1.2.152" + "@swc/core-linux-arm-gnueabihf" "1.2.152" + "@swc/core-linux-arm64-gnu" "1.2.152" + "@swc/core-linux-arm64-musl" "1.2.152" + "@swc/core-linux-x64-gnu" "1.2.152" + "@swc/core-linux-x64-musl" "1.2.152" + "@swc/core-win32-arm64-msvc" "1.2.152" + "@swc/core-win32-ia32-msvc" "1.2.152" + "@swc/core-win32-x64-msvc" "1.2.152" "@szmarczak/http-timer@^1.1.2": version "1.1.2"