Skip to content

Commit a85b649

Browse files
authored
fix(typescript)!: correctly resolve filenames of declaration files for output.file (#1728)
* test(typescript): add test case for invalid declarationDir with output.file * fix(typescript): correctly resolve output filename of declaration files when output.file is used * fix(typescript): validate that declarationDir is inside bundle output directory when using output.file * test(typescript): check for correct error for invalid declarationDir when using output.file --------- Co-authored-by: eu ler <[email protected]>
1 parent 62fac85 commit a85b649

File tree

3 files changed

+46
-20
lines changed

3 files changed

+46
-20
lines changed

packages/typescript/src/index.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -178,20 +178,8 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi
178178
if (outputOptions.dir) {
179179
baseDir = outputOptions.dir;
180180
} else if (outputOptions.file) {
181-
// find common path of output.file and configured declation output
182-
const outputDir = path.dirname(outputOptions.file);
183-
const configured = path.resolve(
184-
parsedOptions.options.declarationDir ||
185-
parsedOptions.options.outDir ||
186-
tsconfig ||
187-
process.cwd()
188-
);
189-
const backwards = path
190-
.relative(outputDir, configured)
191-
.split(path.sep)
192-
.filter((v) => v === '..')
193-
.join(path.sep);
194-
baseDir = path.normalize(`${outputDir}/${backwards}`);
181+
// the bundle output directory used by rollup when outputOptions.file is used instead of outputOptions.dir
182+
baseDir = path.dirname(outputOptions.file);
195183
}
196184
if (!baseDir) return;
197185

packages/typescript/src/options/validate.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { relative } from 'path';
1+
import { relative, dirname } from 'path';
22

33
import type { OutputOptions, PluginContext } from 'rollup';
44

@@ -51,14 +51,24 @@ export function validatePaths(
5151
);
5252
}
5353

54+
let outputDir: string | undefined = outputOptions.dir;
55+
if (outputOptions.file) {
56+
outputDir = dirname(outputOptions.file);
57+
}
5458
for (const dirProperty of DIRECTORY_PROPS) {
55-
if (compilerOptions[dirProperty] && outputOptions.dir) {
59+
if (compilerOptions[dirProperty] && outputDir) {
5660
// Checks if the given path lies within Rollup output dir
57-
const fromRollupDirToTs = relative(outputOptions.dir, compilerOptions[dirProperty]!);
61+
const fromRollupDirToTs = relative(outputDir, compilerOptions[dirProperty]!);
5862
if (fromRollupDirToTs.startsWith('..')) {
59-
context.error(
60-
`@rollup/plugin-typescript: Path of Typescript compiler option '${dirProperty}' must be located inside Rollup 'dir' option.`
61-
);
63+
if (outputOptions.dir) {
64+
context.error(
65+
`@rollup/plugin-typescript: Path of Typescript compiler option '${dirProperty}' must be located inside Rollup 'dir' option.`
66+
);
67+
} else {
68+
context.error(
69+
`@rollup/plugin-typescript: Path of Typescript compiler option '${dirProperty}' must be located inside the same directory as the Rollup 'file' option.`
70+
);
71+
}
6272
}
6373
}
6474
}

packages/typescript/test/test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,34 @@ test.serial('ensures declarationDir is located in Rollup output dir', async (t)
101101
);
102102
});
103103

104+
test.serial(
105+
'ensures declarationDir is located in Rollup output directory when output.file is used',
106+
async (t) => {
107+
const bundle = await rollup({
108+
input: 'fixtures/basic/main.ts',
109+
plugins: [
110+
typescript({
111+
tsconfig: 'fixtures/basic/tsconfig.json',
112+
declarationDir: 'fixtures/basic/other/',
113+
declaration: true
114+
})
115+
],
116+
onwarn
117+
});
118+
119+
// this should throw an error just like the equivalent setup using output.dir above
120+
const wrongDirError = await t.throwsAsync(() =>
121+
getCode(bundle, { format: 'es', file: 'fixtures/basic/dist/index.js' }, true)
122+
);
123+
t.true(
124+
wrongDirError.message.includes(
125+
`Path of Typescript compiler option 'declarationDir' must be located inside the same directory as the Rollup 'file' option`
126+
),
127+
`Unexpected error message: ${wrongDirError.message}`
128+
);
129+
}
130+
);
131+
104132
test.serial('ensures multiple outputs can be built', async (t) => {
105133
// In a rollup.config.js we would pass an array
106134
// The rollup method that's exported as a library won't do that so we must make two calls

0 commit comments

Comments
 (0)