Skip to content

Commit 1534ee5

Browse files
authored
feat: warn if declarationDir or outDir is resolved outside project root (#780)
1 parent abc203b commit 1534ee5

File tree

9 files changed

+91
-7
lines changed

9 files changed

+91
-7
lines changed

packages/plugin-dts/src/index.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
clearTempDeclarationDir,
1111
loadTsconfig,
1212
processSourceEntry,
13+
warnIfOutside,
1314
} from './utils';
1415

1516
const __filename = fileURLToPath(import.meta.url);
@@ -110,11 +111,18 @@ export const pluginDts = (options: PluginDtsOptions = {}): RsbuildPlugin => ({
110111

111112
const tsConfigResult = loadTsconfig(tsconfigPath);
112113
const { options: rawCompilerOptions } = tsConfigResult;
114+
const { declarationDir, outDir, composite, incremental } =
115+
rawCompilerOptions;
113116
const dtsEmitPath =
114117
options.distPath ??
115-
rawCompilerOptions.declarationDir ??
118+
declarationDir ??
119+
outDir ??
116120
config.output?.distPath?.root;
117121

122+
// check whether declarationDir or outDir is outside from current project
123+
warnIfOutside(cwd, declarationDir, 'declarationDir');
124+
warnIfOutside(cwd, outDir, 'outDir');
125+
118126
// clean dts files
119127
if (config.output.cleanDistPath !== false) {
120128
await cleanDtsFiles(dtsEmitPath);
@@ -126,11 +134,7 @@ export const pluginDts = (options: PluginDtsOptions = {}): RsbuildPlugin => ({
126134
}
127135

128136
// clean tsbuildinfo file
129-
if (
130-
rawCompilerOptions.composite ||
131-
rawCompilerOptions.incremental ||
132-
options.build
133-
) {
137+
if (composite || incremental || options.build) {
134138
await cleanTsBuildInfoFile(tsconfigPath, rawCompilerOptions);
135139
}
136140

packages/plugin-dts/src/utils.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,3 +505,21 @@ export async function cleanTsBuildInfoFile(
505505
await fsP.rm(tsbuildInfoFilePath, { force: true });
506506
}
507507
}
508+
509+
export function warnIfOutside(
510+
cwd: string,
511+
dir: string | undefined,
512+
label: string,
513+
): void {
514+
if (dir) {
515+
const normalizedCwd = normalize(cwd);
516+
const normalizedDir = normalize(dir);
517+
const relDir = relative(normalizedCwd, normalizedDir);
518+
519+
if (relDir.startsWith('..')) {
520+
logger.warn(
521+
`The resolved ${label} ${color.cyan(normalizedDir)} is outside the project root ${color.cyan(normalizedCwd)}, please check your tsconfig file.`,
522+
);
523+
}
524+
}
525+
}

pnpm-lock.yaml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "dts-check-outdise-root-test",
3+
"version": "1.0.0",
4+
"private": true,
5+
"type": "module"
6+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { defineConfig } from '@rslib/core';
2+
import { generateBundleEsmConfig } from 'test-helper';
3+
4+
export default defineConfig({
5+
lib: [
6+
generateBundleEsmConfig({
7+
dts: true,
8+
}),
9+
],
10+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const foo = 'foo';
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": "../tsconfig/declarationDir.json",
3+
"compilerOptions": {
4+
"baseUrl": "./",
5+
"rootDir": "src",
6+
"composite": true
7+
},
8+
"include": ["src"]
9+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"compilerOptions": {
3+
"declaration": true,
4+
"declarationDir": "dist"
5+
}
6+
}

tests/integration/dts/index.test.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { existsSync } from 'node:fs';
2-
import { join } from 'node:path';
2+
import { join, normalize } from 'node:path';
33
import stripAnsi from 'strip-ansi';
44
import {
55
buildAndGetResults,
@@ -607,3 +607,31 @@ describe('use with other features', async () => {
607607
`);
608608
});
609609
});
610+
611+
describe('check tsconfig.json field', async () => {
612+
test('check whether declarationDir is resolved outside from project root', async () => {
613+
const fixturePath = join(__dirname, 'check', 'outside-root');
614+
const { logs, restore } = proxyConsole();
615+
const { files } = await buildAndGetResults({
616+
fixturePath,
617+
type: 'dts',
618+
});
619+
const logStrings = logs.map((log) => stripAnsi(log));
620+
restore();
621+
622+
const expectDeclarationDir = normalize(
623+
join(__dirname, 'check/tsconfig/dist'),
624+
);
625+
const expectRoot = normalize(join(__dirname, 'check/outside-root'));
626+
627+
expect(
628+
logStrings.some((log) =>
629+
log.includes(
630+
`The resolved declarationDir ${expectDeclarationDir} is outside the project root ${expectRoot}, please check your tsconfig file.`,
631+
),
632+
),
633+
).toEqual(true);
634+
635+
expect(files.esm).toMatchInlineSnapshot('undefined');
636+
});
637+
});

0 commit comments

Comments
 (0)