fix(misc): pass full path to tsconfig when registering transpiler (#19451)

This commit is contained in:
Craigory Coppola 2023-10-06 14:40:15 -04:00 committed by GitHub
parent e97bbc040b
commit 6946f65059
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 66 additions and 32 deletions

View File

@ -140,7 +140,7 @@ Nx provides a helper function that you can import within your setup/teardown fil
```typescript {% fileName="global-setup.ts" %}
import { registerTsProject } from '@nx/js/src/internal';
const cleanupRegisteredPaths = registerTsProject('.', 'tsconfig.base.json');
const cleanupRegisteredPaths = registerTsProject('./tsconfig.base.json');
import { yourFancyFunction } from '@some-org/my-util-library';
export default async function () {
@ -184,7 +184,7 @@ export default {
```typescript {% fileName="global-setup-swc.ts" %}
import { registerTsProject } from '@nx/js/src/internal';
const cleanupRegisteredPaths = registerTsProject('.', 'tsconfig.base.json');
const cleanupRegisteredPaths = registerTsProject('./tsconfig.base.json');
export default async function () {
// swc will hoist all imports, and we need to make sure the register happens first

View File

@ -140,7 +140,7 @@ Nx provides a helper function that you can import within your setup/teardown fil
```typescript {% fileName="global-setup.ts" %}
import { registerTsProject } from '@nx/js/src/internal';
const cleanupRegisteredPaths = registerTsProject('.', 'tsconfig.base.json');
const cleanupRegisteredPaths = registerTsProject('./tsconfig.base.json');
import { yourFancyFunction } from '@some-org/my-util-library';
export default async function () {
@ -184,7 +184,7 @@ export default {
```typescript {% fileName="global-setup-swc.ts" %}
import { registerTsProject } from '@nx/js/src/internal';
const cleanupRegisteredPaths = registerTsProject('.', 'tsconfig.base.json');
const cleanupRegisteredPaths = registerTsProject('./tsconfig.base.json');
export default async function () {
// swc will hoist all imports, and we need to make sure the register happens first

View File

@ -53,7 +53,7 @@ describe('Jest', () => {
`libs/${mylib}/setup.ts`,
stripIndents`
const { registerTsProject } = require('@nx/js/src/internal');
const cleanup = registerTsProject('.', 'tsconfig.base.json');
const cleanup = registerTsProject('./tsconfig.base.json');
import {setup} from '@global-fun/globals';
export default async function() {setup();}
@ -66,7 +66,7 @@ describe('Jest', () => {
`libs/${mylib}/teardown.ts`,
stripIndents`
const { registerTsProject } = require('@nx/js/src/internal');
const cleanup = registerTsProject('.', 'tsconfig.base.json');
const cleanup = registerTsProject('./tsconfig.base.json');
import {teardown} from '@global-fun/globals';
export default async function() {teardown();}

View File

@ -1,4 +1,4 @@
import { join } from 'path';
import { basename, dirname, join } from 'path';
import { existsSync, readFileSync } from 'fs';
import { logger, ProjectConfiguration } from '@nx/devkit';
import { registerTsProject } from '@nx/js/src/internal';
@ -92,10 +92,7 @@ function getModuleFederationConfig(
let cleanupTranspiler = () => {};
if (existsSync(moduleFederationConfigPathTS)) {
cleanupTranspiler = registerTsProject(
moduleFederationConfigPathTS,
tsconfigPath
);
cleanupTranspiler = registerTsProject(join(workspaceRoot, tsconfigPath));
moduleFederationConfigPath = moduleFederationConfigPathTS;
}

View File

@ -1,5 +1,7 @@
import { merge } from 'webpack-merge';
import { registerTsProject } from '@nx/js/src/internal';
import { workspaceRoot } from '@nx/devkit';
import { join } from 'path';
export async function mergeCustomWebpackConfig(
baseWebpackConfig: any,
@ -9,7 +11,7 @@ export async function mergeCustomWebpackConfig(
) {
const customWebpackConfiguration = resolveCustomWebpackConfig(
pathToWebpackConfig,
options.tsConfig
join(workspaceRoot, options.tsConfig)
);
// The extra Webpack configuration file can also export a Promise, for instance:
// `module.exports = new Promise(...)`. If it exports a single object, but not a Promise,
@ -26,7 +28,7 @@ export async function mergeCustomWebpackConfig(
}
export function resolveCustomWebpackConfig(path: string, tsConfig: string) {
const cleanupTranspiler = registerTsProject(path, tsConfig);
const cleanupTranspiler = registerTsProject(tsConfig);
const customWebpackConfig = require(path);
cleanupTranspiler();
// If the user provides a configuration in TS file
@ -42,7 +44,7 @@ export function resolveIndexHtmlTransformer(
tsConfig: string,
target: import('@angular-devkit/architect').Target
) {
const cleanupTranspiler = registerTsProject(path, tsConfig);
const cleanupTranspiler = registerTsProject(tsConfig);
const indexTransformer = require(path);
cleanupTranspiler();

View File

@ -9,6 +9,7 @@ import { existsSync } from 'fs';
import { readNxJson } from 'nx/src/config/configuration';
import { isNpmProject } from 'nx/src/project-graph/operators';
import { getDependencyConfigs } from 'nx/src/tasks-runner/utils';
import { join } from 'path';
import { from, Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { createTmpTsConfigForBuildableLibs } from '../utilities/buildable-libs';

View File

@ -19,6 +19,7 @@ import { createTmpTsConfigForBuildableLibs } from '../utilities/buildable-libs';
import { from } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { getRootTsConfigPath } from '@nx/js';
import { join } from 'path';
type BuildTargetOptions = {
tsConfig: string;

View File

@ -2,6 +2,7 @@ import type { TSESLint } from '@typescript-eslint/utils';
import { existsSync } from 'fs';
import { registerTsProject } from '@nx/js/src/internal';
import { WORKSPACE_PLUGIN_DIR, WORKSPACE_RULE_NAMESPACE } from './constants';
import { join } from 'path';
type ESLintRules = Record<string, TSESLint.RuleModule<string, unknown[]>>;
@ -11,7 +12,9 @@ export const workspaceRules = ((): ESLintRules => {
return {};
}
// Register `tools/eslint-rules` for TS transpilation
const registrationCleanup = registerTsProject(WORKSPACE_PLUGIN_DIR);
const registrationCleanup = registerTsProject(
join(WORKSPACE_PLUGIN_DIR, 'tsconfig.json')
);
try {
/**
* Currently we only support applying the rules from the user's workspace plugin object

View File

@ -14,6 +14,7 @@ import * as path from 'path';
import { createESLintRule } from '../utils/create-eslint-rule';
import { readProjectGraph } from '../utils/project-graph-utils';
import { valid } from 'semver';
import { join } from 'path';
type Options = [
{
@ -147,7 +148,7 @@ export default createESLintRule<Options, MessageIds>({
}
if (!(global as any).tsProjectRegistered) {
registerTsProject(workspaceRoot, 'tsconfig.base.json');
registerTsProject(join(workspaceRoot, 'tsconfig.base.json'));
(global as any).tsProjectRegistered = true;
}

View File

@ -18,11 +18,24 @@ let ts: typeof import('typescript');
*
* @returns cleanup function
*/
export const registerTsProject = (
export function registerTsProject(tsConfigPath: string): () => void;
/**
* Optionally, if swc-node and tsconfig-paths are available in the current workspace, apply the require
* register hooks so that .ts files can be used for writing custom workspace projects.
*
* If ts-node and tsconfig-paths are not available, the user can still provide an index.js file in
* the root of their project and the fundamentals will still work (but
* workspace path mapping will not, for example).
*
* @returns cleanup function
* @deprecated This signature will be removed in Nx v18. You should pass the full path to the tsconfig in the first argument.
*/
export function registerTsProject(path: string, configFilename: string);
export function registerTsProject(
path: string,
configFilename = 'tsconfig.json'
): (() => void) => {
const tsConfigPath = join(path, configFilename);
configFilename?: string
): () => void {
const tsConfigPath = configFilename ? join(path, configFilename) : path;
const compilerOptions: CompilerOptions = readCompilerOptions(tsConfigPath);
const cleanupFunctions: ((...args: unknown[]) => unknown)[] = [
@ -35,7 +48,7 @@ export const registerTsProject = (
fn();
}
};
};
}
export function getSwcTranspiler(
compilerOptions: CompilerOptions
@ -132,7 +145,7 @@ export function registerTsConfigPaths(tsConfigPath): () => void {
/**
* Load the ts config from the source project
*/
const tsconfigPaths: typeof import('tsconfig-paths') = require('tsconfig-paths');
const tsconfigPaths = loadTsConfigPaths();
const tsConfigResult = tsconfigPaths.loadConfig(tsConfigPath);
/**
* Register the custom workspace path mappings with node so that workspace libraries
@ -145,9 +158,11 @@ export function registerTsConfigPaths(tsConfigPath): () => void {
});
}
} catch (err) {
warnNoTsconfigPaths();
if (err instanceof Error) {
throw new Error(`Unable to load ${tsConfigPath}: ` + err.message);
}
}
return () => {};
throw new Error(`Unable to load ${tsConfigPath}`);
}
function readCompilerOptions(tsConfigPath): CompilerOptions {
@ -178,6 +193,14 @@ function readCompilerOptionsWithTypescript(tsConfigPath) {
return options;
}
function loadTsConfigPaths(): typeof import('tsconfig-paths') | null {
try {
return require('tsconfig-paths');
} catch {
warnNoTsconfigPaths();
}
}
function warnTsNodeUsage() {
logger.warn(
stripIndent(`${NX_PREFIX} Falling back to ts-node for local typescript execution. This may be a little slower.

View File

@ -56,10 +56,7 @@ function getModuleFederationConfig(
// create a no-op so this can be called with issue
let cleanupTranspiler = () => {};
if (existsSync(moduleFederationConfigPathTS)) {
cleanupTranspiler = registerTsProject(
moduleFederationConfigPathTS,
tsconfigPath
);
cleanupTranspiler = registerTsProject(join(workspaceRoot, tsconfigPath));
moduleFederationConfigPath = moduleFederationConfigPathTS;
}

View File

@ -19,6 +19,7 @@ import { resolveCustomWebpackConfig } from '../../utils/webpack/custom-webpack';
import { normalizeOptions } from '../webpack/lib/normalize-options';
import { WebpackExecutorOptions } from '../webpack/schema';
import { WebDevServerOptions } from './schema';
import { join } from 'path';
export async function* devServerExecutor(
serveOptions: WebDevServerOptions,
@ -62,9 +63,12 @@ export async function* devServerExecutor(
let config = getDevServerConfig(context, buildOptions, serveOptions);
if (buildOptions.webpackConfig) {
let tsconfigPath = buildOptions.tsConfig.startsWith(context.root)
? buildOptions.tsConfig
: join(context.root, buildOptions.tsConfig);
let customWebpack = resolveCustomWebpackConfig(
buildOptions.webpackConfig,
buildOptions.tsConfig
tsconfigPath
);
if (typeof customWebpack.then === 'function') {

View File

@ -1,4 +1,9 @@
import { ExecutorContext, logger, stripIndents } from '@nx/devkit';
import {
ExecutorContext,
logger,
stripIndents,
workspaceRoot,
} from '@nx/devkit';
import { eachValueFrom } from '@nx/devkit/src/utils/rxjs-for-await';
import type { Configuration, Stats } from 'webpack';
import { from, of } from 'rxjs';
@ -9,7 +14,7 @@ import {
switchMap,
tap,
} from 'rxjs/operators';
import { resolve } from 'path';
import { join, resolve } from 'path';
import {
calculateProjectBuildableDependencies,
createTmpTsConfig,

View File

@ -1,7 +1,7 @@
import { registerTsProject } from '@nx/js/src/internal';
export function resolveCustomWebpackConfig(path: string, tsConfig: string) {
const cleanupTranspiler = registerTsProject(path, tsConfig);
const cleanupTranspiler = registerTsProject(tsConfig);
const customWebpackConfig = require(path);
cleanupTranspiler();