fix(esbuild): declaration:true should find the correct package root regardless of cwd #26261 (#27560)

<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->
The types that are generated for esbuild packages are not placed into
the correct folder structure in the built package and is very dependent
of the CWD.


## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
The declaration files should be generated correctly to match the package
and not dependent on CWD

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #26261 #26376
This commit is contained in:
Colum Ferry 2024-08-21 17:08:13 +01:00 committed by GitHub
parent d557fe207c
commit c427717fc1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 50 additions and 25 deletions

View File

@ -282,15 +282,13 @@ describe('EsBuild Plugin', () => {
` `
); );
runCLI( runCLI(`build ${declarationPkg} --declaration=true`);
`build ${declarationPkg} --declaration=true --declarationRootDir='libs/${declarationPkg}/src'`
);
checkFilesExist( checkFilesExist(
`dist/libs/${declarationPkg}/index.cjs`, `dist/libs/${declarationPkg}/index.cjs`,
`dist/libs/${declarationPkg}/index.d.ts`, `dist/libs/${declarationPkg}/src/index.d.ts`,
`dist/libs/${declarationPkg}/lib/${declarationPkg}.d.ts`, `dist/libs/${declarationPkg}/src/lib/${declarationPkg}.d.ts`,
`dist/libs/${declarationPkg}/lib/testDir/sub.d.ts` `dist/libs/${declarationPkg}/src/lib/testDir/sub.d.ts`
); );
expect(runCommand(`node dist/libs/${declarationPkg}`)).toMatch( expect(runCommand(`node dist/libs/${declarationPkg}`)).toMatch(

View File

@ -22,7 +22,7 @@ import {
} from './lib/build-esbuild-options'; } from './lib/build-esbuild-options';
import { getExtraDependencies } from './lib/get-extra-dependencies'; import { getExtraDependencies } from './lib/get-extra-dependencies';
import { DependentBuildableProjectNode } from '@nx/js/src/utils/buildable-libs-utils'; import { DependentBuildableProjectNode } from '@nx/js/src/utils/buildable-libs-utils';
import { join } from 'path'; import { join, relative } from 'path';
const BUILD_WATCH_FAILED = `[ ${chalk.red( const BUILD_WATCH_FAILED = `[ ${chalk.red(
'watch' 'watch'
@ -58,6 +58,7 @@ export async function* esbuildExecutor(
}); });
} }
return acc; return acc;
return acc;
}, []); }, []);
if (!options.thirdParty) { if (!options.thirdParty) {
@ -210,6 +211,7 @@ function getTypeCheckOptions(
context: ExecutorContext context: ExecutorContext
) { ) {
const { watch, tsConfig, outputPath } = options; const { watch, tsConfig, outputPath } = options;
const projectRoot = context.projectGraph.nodes[context.projectName].data.root;
const typeCheckOptions: TypeCheckOptions = { const typeCheckOptions: TypeCheckOptions = {
...(options.declaration ...(options.declaration
@ -220,9 +222,10 @@ function getTypeCheckOptions(
: { : {
mode: 'noEmit', mode: 'noEmit',
}), }),
tsConfigPath: tsConfig, tsConfigPath: relative(process.cwd(), join(context.root, tsConfig)),
workspaceRoot: context.root, workspaceRoot: context.root,
rootDir: options.declarationRootDir ?? context.root, rootDir: options.declarationRootDir ?? context.root,
projectRoot,
}; };
if (watch) { if (watch) {

View File

@ -63,7 +63,8 @@ describe('buildEsbuildOptions', () => {
format: 'esm', format: 'esm',
platform: 'browser', platform: 'browser',
outfile: 'dist/apps/myapp/index.js', outfile: 'dist/apps/myapp/index.js',
tsconfig: 'apps/myapp/tsconfig.app.json', tsconfig:
'src/executors/esbuild/lib/fixtures/apps/myapp/tsconfig.app.json',
external: [], external: [],
outExtension: { outExtension: {
'.js': '.js', '.js': '.js',
@ -104,7 +105,8 @@ describe('buildEsbuildOptions', () => {
format: 'esm', format: 'esm',
platform: 'browser', platform: 'browser',
outdir: 'dist/apps/myapp', outdir: 'dist/apps/myapp',
tsconfig: 'apps/myapp/tsconfig.app.json', tsconfig:
'src/executors/esbuild/lib/fixtures/apps/myapp/tsconfig.app.json',
external: [], external: [],
outExtension: { outExtension: {
'.js': '.js', '.js': '.js',
@ -144,7 +146,8 @@ describe('buildEsbuildOptions', () => {
format: 'cjs', format: 'cjs',
platform: 'browser', platform: 'browser',
outfile: 'dist/apps/myapp/index.cjs', outfile: 'dist/apps/myapp/index.cjs',
tsconfig: 'apps/myapp/tsconfig.app.json', tsconfig:
'src/executors/esbuild/lib/fixtures/apps/myapp/tsconfig.app.json',
external: [], external: [],
outExtension: { outExtension: {
'.js': '.cjs', '.js': '.cjs',
@ -181,7 +184,8 @@ describe('buildEsbuildOptions', () => {
format: 'cjs', format: 'cjs',
platform: 'node', platform: 'node',
outfile: 'dist/apps/myapp/index.cjs', outfile: 'dist/apps/myapp/index.cjs',
tsconfig: 'apps/myapp/tsconfig.app.json', tsconfig:
'src/executors/esbuild/lib/fixtures/apps/myapp/tsconfig.app.json',
external: [], external: [],
outExtension: { outExtension: {
'.js': '.cjs', '.js': '.cjs',
@ -222,7 +226,8 @@ describe('buildEsbuildOptions', () => {
format: 'esm', format: 'esm',
platform: 'node', platform: 'node',
outfile: 'dist/apps/myapp/index.mjs', outfile: 'dist/apps/myapp/index.mjs',
tsconfig: 'apps/myapp/tsconfig.app.json', tsconfig:
'src/executors/esbuild/lib/fixtures/apps/myapp/tsconfig.app.json',
external: [], external: [],
outExtension: { outExtension: {
'.js': '.mjs', '.js': '.mjs',
@ -261,7 +266,8 @@ describe('buildEsbuildOptions', () => {
format: 'cjs', format: 'cjs',
platform: 'node', platform: 'node',
outfile: 'dist/apps/myapp/index.js', outfile: 'dist/apps/myapp/index.js',
tsconfig: 'apps/myapp/tsconfig.app.json', tsconfig:
'src/executors/esbuild/lib/fixtures/apps/myapp/tsconfig.app.json',
external: [], external: [],
outExtension: { outExtension: {
'.js': '.js', '.js': '.js',
@ -301,7 +307,8 @@ describe('buildEsbuildOptions', () => {
format: 'esm', format: 'esm',
platform: 'node', platform: 'node',
outfile: 'dist/apps/myapp/index.js', outfile: 'dist/apps/myapp/index.js',
tsconfig: 'apps/myapp/tsconfig.app.json', tsconfig:
'src/executors/esbuild/lib/fixtures/apps/myapp/tsconfig.app.json',
external: [], external: [],
outExtension: { outExtension: {
'.js': '.js', '.js': '.js',
@ -340,7 +347,8 @@ describe('buildEsbuildOptions', () => {
format: 'esm', format: 'esm',
platform: 'node', platform: 'node',
outfile: 'dist/apps/myapp/index.js', outfile: 'dist/apps/myapp/index.js',
tsconfig: 'apps/myapp/tsconfig.app.json', tsconfig:
'src/executors/esbuild/lib/fixtures/apps/myapp/tsconfig.app.json',
external: ['bar', 'foo'], external: ['bar', 'foo'],
outExtension: { outExtension: {
'.js': '.js', '.js': '.js',
@ -376,7 +384,8 @@ describe('buildEsbuildOptions', () => {
format: 'esm', format: 'esm',
platform: 'node', platform: 'node',
outdir: 'dist/apps/myapp', outdir: 'dist/apps/myapp',
tsconfig: 'apps/myapp/tsconfig.app.json', tsconfig:
'src/executors/esbuild/lib/fixtures/apps/myapp/tsconfig.app.json',
external: undefined, external: undefined,
outExtension: { outExtension: {
'.js': '.js', '.js': '.js',
@ -414,7 +423,8 @@ describe('buildEsbuildOptions', () => {
format: 'esm', format: 'esm',
platform: 'node', platform: 'node',
outdir: 'dist/apps/myapp', outdir: 'dist/apps/myapp',
tsconfig: 'apps/myapp/tsconfig.app.json', tsconfig:
'src/executors/esbuild/lib/fixtures/apps/myapp/tsconfig.app.json',
external: undefined, external: undefined,
sourcemap: true, sourcemap: true,
outExtension: { outExtension: {
@ -451,7 +461,8 @@ describe('buildEsbuildOptions', () => {
format: 'esm', format: 'esm',
platform: 'node', platform: 'node',
outdir: 'dist/apps/myapp', outdir: 'dist/apps/myapp',
tsconfig: 'apps/myapp/tsconfig.app.json', tsconfig:
'src/executors/esbuild/lib/fixtures/apps/myapp/tsconfig.app.json',
external: undefined, external: undefined,
metafile: undefined, metafile: undefined,
minify: undefined, minify: undefined,
@ -490,7 +501,8 @@ describe('buildEsbuildOptions', () => {
format: 'esm', format: 'esm',
platform: 'node', platform: 'node',
outdir: 'dist/apps/myapp', outdir: 'dist/apps/myapp',
tsconfig: 'apps/myapp/tsconfig.app.json', tsconfig:
'src/executors/esbuild/lib/fixtures/apps/myapp/tsconfig.app.json',
external: undefined, external: undefined,
sourcemap: true, sourcemap: true,
metafile: undefined, metafile: undefined,
@ -530,7 +542,8 @@ describe('buildEsbuildOptions', () => {
format: 'esm', format: 'esm',
platform: 'node', platform: 'node',
outdir: 'dist/apps/myapp', outdir: 'dist/apps/myapp',
tsconfig: 'apps/myapp/tsconfig.app.json', tsconfig:
'src/executors/esbuild/lib/fixtures/apps/myapp/tsconfig.app.json',
external: undefined, external: undefined,
sourcemap: true, sourcemap: true,
metafile: undefined, metafile: undefined,

View File

@ -6,11 +6,13 @@ import {
joinPathFragments, joinPathFragments,
normalizePath, normalizePath,
ProjectGraphProjectNode, ProjectGraphProjectNode,
workspaceRoot,
} from '@nx/devkit'; } from '@nx/devkit';
import { getClientEnvironment } from '../../../utils/environment-variables'; import { getClientEnvironment } from '../../../utils/environment-variables';
import { NormalizedEsBuildExecutorOptions } from '../schema'; import { NormalizedEsBuildExecutorOptions } from '../schema';
import { getEntryPoints } from '../../../utils/get-entry-points'; import { getEntryPoints } from '../../../utils/get-entry-points';
import { join, relative } from 'path';
const ESM_FILE_EXTENSION = '.js'; const ESM_FILE_EXTENSION = '.js';
const CJS_FILE_EXTENSION = '.cjs'; const CJS_FILE_EXTENSION = '.cjs';
@ -38,7 +40,7 @@ export function buildEsbuildOptions(
platform: options.platform, platform: options.platform,
target: options.target, target: options.target,
metafile: options.metafile, metafile: options.metafile,
tsconfig: options.tsConfig, tsconfig: relative(process.cwd(), join(context.root, options.tsConfig)),
sourcemap: sourcemap:
(options.sourcemap ?? options.userDefinedBuildOptions?.sourcemap) || (options.sourcemap ?? options.userDefinedBuildOptions?.sourcemap) ||
false, false,

View File

@ -21,6 +21,7 @@ interface BaseTypeCheckOptions {
cacheDir?: string; cacheDir?: string;
incremental?: boolean; incremental?: boolean;
rootDir?: string; rootDir?: string;
projectRoot?: string;
} }
type Mode = NoEmitMode | EmitDeclarationOnlyMode; type Mode = NoEmitMode | EmitDeclarationOnlyMode;
@ -118,7 +119,7 @@ export async function runTypeCheck(
async function setupTypeScript(options: TypeCheckOptions) { async function setupTypeScript(options: TypeCheckOptions) {
const ts = await import('typescript'); const ts = await import('typescript');
const { workspaceRoot, tsConfigPath, cacheDir, incremental, rootDir } = const { workspaceRoot, tsConfigPath, cacheDir, incremental, projectRoot } =
options; options;
const config = readTsConfig(tsConfigPath); const config = readTsConfig(tsConfigPath);
if (config.errors.length) { if (config.errors.length) {
@ -128,7 +129,15 @@ async function setupTypeScript(options: TypeCheckOptions) {
const emitOptions = const emitOptions =
options.mode === 'emitDeclarationOnly' options.mode === 'emitDeclarationOnly'
? { emitDeclarationOnly: true, declaration: true, outDir: options.outDir } ? {
emitDeclarationOnly: true,
declaration: true,
outDir: options.outDir,
declarationDir:
options.projectRoot && options.outDir.indexOf(projectRoot)
? options.outDir.replace(projectRoot, '')
: undefined,
}
: { noEmit: true }; : { noEmit: true };
const compilerOptions = { const compilerOptions = {
@ -136,7 +145,7 @@ async function setupTypeScript(options: TypeCheckOptions) {
skipLibCheck: true, skipLibCheck: true,
...emitOptions, ...emitOptions,
incremental, incremental,
rootDir: rootDir || config.options.rootDir, rootDir: options.rootDir || config.options.rootDir,
}; };
return { ts, workspaceRoot, cacheDir, config, compilerOptions }; return { ts, workspaceRoot, cacheDir, config, compilerOptions };