Skip to content

Commit

Permalink
fix(bundling): Correct declarationRootDir handling for esbuild
Browse files Browse the repository at this point in the history
Refine declarationDir logic for esbuild plugin as follows

- IF no custom declaration root AND outDir structure mirrors {projectRoot}
  e.g if project root packages/mylib and output directory is dist/packages/mylib
  THEN we adjust declarationDir to place types in outDir
- ELSE if we have specified a custom declarationRootDir, place declarations in outDir

Add test to check for the case when declarationDir id specified.

Closes #28814.
  • Loading branch information
danielsharvey committed Dec 12, 2024
1 parent 0d1c960 commit 048504a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 6 deletions.
2 changes: 1 addition & 1 deletion docs/generated/packages/esbuild/executors/esbuild.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
},
"declarationRootDir": {
"type": "string",
"description": "Sets the rootDir for the declaration (*.d.ts) files."
"description": "Sets the rootDir for the declaration (*.d.ts) files. If not specified, the generator will attempt to determine the the correct location. Declarations files will be output to `outputPath`."
},
"watch": {
"type": "boolean",
Expand Down
38 changes: 38 additions & 0 deletions e2e/esbuild/src/esbuild.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,4 +314,42 @@ describe('EsBuild Plugin', () => {
new RegExp(`${declarationPkg}-sub`)
);
}, 300_000);

it('should support declaration builds specifying declarationRootDir', () => {
const declarationPkg = uniq('declaration-pkg');
runCLI(
`generate @nx/js:lib ${declarationPkg} --directory=libs/${declarationPkg} --bundler=esbuild`
);
createFile(
`libs/${declarationPkg}/src/lib/testDir/sub.ts`,
`
export function sub(): string {
return 'sub';
}
`
);
updateFile(
`libs/${declarationPkg}/src/lib/${declarationPkg}.ts`,
`
import { sub } from './testDir/sub';
console.log('${declarationPkg}-' + sub());
`
);

runCLI(
`build ${declarationPkg} --declaration=true --declarationRootDir='libs/${declarationPkg}/src'`
);

checkFilesExist(
`dist/libs/${declarationPkg}/index.cjs`,
`dist/libs/${declarationPkg}/index.d.ts`,
`dist/libs/${declarationPkg}/lib/${declarationPkg}.d.ts`,
`dist/libs/${declarationPkg}/lib/testDir/sub.d.ts`
);

expect(runCommand(`node dist/libs/${declarationPkg}`)).toMatch(
new RegExp(`${declarationPkg}-sub`)
);
}, 300_000);
});
2 changes: 1 addition & 1 deletion packages/esbuild/src/executors/esbuild/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
},
"declarationRootDir": {
"type": "string",
"description": "Sets the rootDir for the declaration (*.d.ts) files."
"description": "Sets the rootDir for the declaration (*.d.ts) files. If not specified, the generator will attempt to determine the the correct location. Declarations files will be output to `outputPath`."
},
"watch": {
"type": "boolean",
Expand Down
25 changes: 21 additions & 4 deletions packages/js/src/utils/typescript/run-type-check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,33 @@ async function setupTypeScript(options: TypeCheckOptions) {
throw new Error(`Invalid config file due to following: ${errorMessages}`);
}

// declarationDir logic
const rootDirIsWorkspaceRoot =
path.relative(options.workspaceRoot, options.rootDir) === '';

// IF no custom declaration root AND outDir structure mirrors {projectRoot}
// e.g. packages/mylib AND dist/packages/mylib
// THEN we adjust declarationDir to place types in outDir
// ELSE if we have specified a custom declarationRootDir, place declarations in outDir
const _projectRoot = path.normalize(projectRoot);
const dfltStructure =
options.mode === 'emitDeclarationOnly'
? options.projectRoot &&
rootDirIsWorkspaceRoot &&
path.normalize(options.outDir).endsWith(_projectRoot)
: undefined;

const emitOptions =
options.mode === 'emitDeclarationOnly'
? {
emitDeclarationOnly: true,
declaration: true,
outDir: options.outDir,
declarationDir:
options.projectRoot && options.outDir.indexOf(projectRoot)
? options.outDir.replace(projectRoot, '')
: undefined,
declarationDir: dfltStructure
? options.outDir.slice(0, -_projectRoot.length)
: !rootDirIsWorkspaceRoot
? options.outDir
: undefined,
}
: { noEmit: true };

Expand Down

0 comments on commit 048504a

Please sign in to comment.