diff --git a/packages/js/src/utils/buildable-libs-utils.spec.ts b/packages/js/src/utils/buildable-libs-utils.spec.ts index 2c3443bea78d89..f9cb121e31be4c 100644 --- a/packages/js/src/utils/buildable-libs-utils.spec.ts +++ b/packages/js/src/utils/buildable-libs-utils.spec.ts @@ -1,10 +1,14 @@ import { DependencyType, ProjectGraph, TaskGraph } from '@nx/devkit'; +import { TempFs } from '@nx/devkit/internal-testing-utils'; +import { readFileSync } from 'fs'; import { - calculateProjectDependencies, calculateDependenciesFromTaskGraph, + calculateProjectDependencies, + createTmpTsConfig, DependentBuildableProjectNode, updatePaths, } from './buildable-libs-utils'; +import { join } from 'path'; describe('updatePaths', () => { const deps: DependentBuildableProjectNode[] = [ @@ -768,3 +772,45 @@ describe('missingDependencies', () => { ).toThrow(); }); }); + +describe('createTmpTsConfig', () => { + it('should create a temporary tsconfig file extending the provided tsconfig', () => { + const fs = new TempFs('buildable-libs-utils#createTmpTsConfig'); + const tsconfigPath = 'packages/foo/tsconfig.json'; + fs.createFileSync(tsconfigPath, '{}'); + + const tmpTsConfigPath = createTmpTsConfig( + tsconfigPath, + fs.tempDir, + 'packages/foo', + [] + ); + + const tmpTsConfig = readFileSync(tmpTsConfigPath, 'utf8'); + // would be generated at /tmp/packages/foo/build/tsconfig.generated.json + // while the extended tsconfig path is /packages/foo/tsconfig.json + expect(JSON.parse(tmpTsConfig).extends).toBe( + '../../../../packages/foo/tsconfig.json' + ); + }); + + it('should also work when the provided tsconfig is an absolute path', () => { + const fs = new TempFs('buildable-libs-utils#createTmpTsConfig'); + const tsconfigPath = join(fs.tempDir, 'packages/foo/tsconfig.json'); + fs.createFileSync(tsconfigPath, '{}'); + + const tmpTsConfigPath = createTmpTsConfig( + tsconfigPath, + fs.tempDir, + 'packages/foo', + [] + ); + + const tmpTsConfig = readFileSync(tmpTsConfigPath, 'utf8'); + // would be generated at /tmp/packages/foo/build/tsconfig.generated.json + // while the extended tsconfig path is /packages/foo/tsconfig.json + expect(JSON.parse(tmpTsConfig).extends).toBe( + '../../../../packages/foo/tsconfig.json' + ); + }); +}); diff --git a/packages/js/src/utils/buildable-libs-utils.ts b/packages/js/src/utils/buildable-libs-utils.ts index a2754b3dc4555b..a272a44cd91e8f 100644 --- a/packages/js/src/utils/buildable-libs-utils.ts +++ b/packages/js/src/utils/buildable-libs-utils.ts @@ -16,7 +16,7 @@ import { unlinkSync } from 'fs'; import { isNpmProject } from 'nx/src/project-graph/operators'; import { directoryExists, fileExists } from 'nx/src/utils/fileutils'; import { output } from 'nx/src/utils/output'; -import { dirname, join, relative, isAbsolute, extname } from 'path'; +import { dirname, join, relative, extname, resolve } from 'path'; import type * as ts from 'typescript'; import { readTsConfigPaths } from './typescript/ts-config'; @@ -194,18 +194,23 @@ function collectDependencies( } function readTsConfigWithRemappedPaths( - tsConfig: string, - generatedTsConfigPath: string, - dependencies: DependentBuildableProjectNode[] + originalTsconfigPath: string, + generatedTsconfigPath: string, + dependencies: DependentBuildableProjectNode[], + workspaceRoot: string ) { const generatedTsConfig: any = { compilerOptions: {} }; - const dirnameTsConfig = dirname(generatedTsConfigPath); - const relativeTsconfig = isAbsolute(dirnameTsConfig) - ? relative(workspaceRoot, dirnameTsConfig) - : dirnameTsConfig; - generatedTsConfig.extends = relative(relativeTsconfig, tsConfig); + const normalizedTsConfig = resolve(workspaceRoot, originalTsconfigPath); + const normalizedGeneratedTsConfigDir = resolve( + workspaceRoot, + dirname(generatedTsconfigPath) + ); + generatedTsConfig.extends = relative( + normalizedGeneratedTsConfigDir, + normalizedTsConfig + ); generatedTsConfig.compilerOptions.paths = computeCompilerOptionsPaths( - tsConfig, + originalTsconfigPath, dependencies ); @@ -443,7 +448,8 @@ export function createTmpTsConfig( const parsedTSConfig = readTsConfigWithRemappedPaths( tsconfigPath, tmpTsConfigPath, - dependencies + dependencies, + workspaceRoot ); process.on('exit', () => cleanupTmpTsConfigFile(tmpTsConfigPath));