diff --git a/packages/tao/src/shared/nx-plugin.ts b/packages/tao/src/shared/nx-plugin.ts index 558d40a4ac16d3..a54bd45740afbb 100644 --- a/packages/tao/src/shared/nx-plugin.ts +++ b/packages/tao/src/shared/nx-plugin.ts @@ -1,12 +1,12 @@ -import { execSync } from 'child_process'; import { sync } from 'fast-glob'; import { existsSync } from 'fs'; import * as path from 'path'; +import { register } from '@swc-node/register/register'; +import { readDefaultTsConfig } from '@swc-node/register/read-default-tsconfig'; import { appRootPath } from '../utils/app-root'; import { readJsonFile } from '../utils/fileutils'; import { PackageJson } from './package-json'; -import { getPackageManagerCommand } from './package-manager'; import { ProjectGraphProcessor } from './project-graph'; import { Workspaces } from './workspace'; import { @@ -132,40 +132,48 @@ export function readPluginPackageJson( * @returns The path to the built plugin, or null if it doesn't exist */ const localPluginCache = {}; +let tsNodeAndPathsRegistered = false; export function resolveLocalNxPlugin( importPath: string, root = appRootPath ): string | null { - localPluginCache[importPath] ??= buildLocalPlugin(importPath, root); + localPluginCache[importPath] ??= lookupLocalPlugin(importPath, root); return localPluginCache[importPath]; } -function buildLocalPlugin(importPath: string, root = appRootPath): string { +function registerTSTranspiler() { + try { + const tsConfigOptions = readDefaultTsConfig( + path.join(appRootPath, 'tsconfig.base.json') + ); + register(tsConfigOptions); + + const tsconfigPaths: typeof import('tsconfig-paths') = require('tsconfig-paths'); + + /** + * Register the custom workspace path mappings with node so that workspace libraries + * can be imported and used within custom workspace lint rules. + */ + return tsconfigPaths.register({ + baseUrl: appRootPath, + paths: tsConfigOptions.paths, + }); + } catch (err) {} +} + +function lookupLocalPlugin(importPath: string, root = appRootPath): string { const workspace = new Workspaces(root).readWorkspaceConfiguration(); const plugin = findNxProjectForImportPath(importPath, workspace, root); if (!plugin) { return null; } - const projectConfig = workspace.projects[plugin]; + if (!tsNodeAndPathsRegistered) { + registerTSTranspiler(); + } - /** - * todo(v14-v15) make this stuff async + use task scheduler - * - * Ideally, we wouldn't invoke nx via execSync here. We should be - * able to run an executor given a project and target programmatically. - * Currently, runExecutor is async and doesn't hit the task orchestrator. - * So to use it, we would have to make a bunch of this stuff async (a breaking change), - * and we would also not benefit from remote or local caches which would be much slower. - * Therefore, currently we use execSync here. We should work towards simplifying - * the task orchestrator API, while consolidating @nrwl/workspace and @nrwl/tao - * to make this something like `await TaskScheduler.runTaskNow({project, target: 'build'})`, - * but that API doesn't exist. - */ - execSync(`${getPackageManagerCommand().exec} nx build ${plugin}`, { - cwd: root, - }); - return path.join(root, projectConfig.targets?.build?.options?.outputPath); + const projectConfig = workspace.projects[plugin]; + return path.join(root, projectConfig.root); } function findNxProjectForImportPath(