Skip to content

Commit 2711aa8

Browse files
fix(typescript): only emit tsbuildinfo file when there is something to emit (#771)
* fix(typescript): only emit tsbuildinfo file when there is something to emit (fixes #681) * test(typescript): fix test failing on Node.js v10
1 parent 6b4b7b6 commit 2711aa8

File tree

4 files changed

+123
-54
lines changed

4 files changed

+123
-54
lines changed

packages/typescript/src/index.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,15 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi
142142

143143
const tsBuildInfoPath = ts.getTsBuildInfoEmitOutputFilePath(parsedOptions.options);
144144
if (tsBuildInfoPath) {
145-
this.emitFile({
146-
type: 'asset',
147-
fileName: normalizePath(path.relative(outputOptions.dir!, tsBuildInfoPath)),
148-
source: emittedFiles.get(tsBuildInfoPath)
149-
});
145+
const tsBuildInfoSource = emittedFiles.get(tsBuildInfoPath);
146+
// https://github.com/rollup/plugins/issues/681
147+
if (tsBuildInfoSource) {
148+
this.emitFile({
149+
type: 'asset',
150+
fileName: normalizePath(path.relative(outputOptions.dir!, tsBuildInfoPath)),
151+
source: tsBuildInfoSource
152+
});
153+
}
150154
}
151155
}
152156
};
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
type AnswerToQuestion = string | undefined;
2+
3+
const answer: AnswerToQuestion = '42';
4+
5+
// eslint-disable-next-line no-console
6+
console.log(`the answer is ${answer}`);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"compilerOptions": {
3+
"incremental": true,
4+
"outDir": "./dist",
5+
"tsBuildInfoFile": "./dist/.tsbuildinfo"
6+
}
7+
}

packages/typescript/test/test.js

Lines changed: 101 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -249,19 +249,29 @@ test.serial('ensures multiple outputs can be built', async (t) => {
249249
plugins: [typescript({ tsconfig: 'fixtures/multiple-files/tsconfig.json' })]
250250
});
251251

252-
const output1 = await getCode(bundle1, { file: 'fixtures/multiple-files/index.js', format: 'cjs' }, true);
252+
const output1 = await getCode(
253+
bundle1,
254+
{ file: 'fixtures/multiple-files/index.js', format: 'cjs' },
255+
true
256+
);
253257

254258
const bundle2 = await rollup({
255259
input: 'fixtures/multiple-files/src/server.ts',
256260
plugins: [typescript({ tsconfig: 'fixtures/multiple-files/tsconfig.json' })]
257261
});
258262

259-
const output2 = await getCode(bundle2, { file: 'fixtures/multiple-files/server.js', format: 'cjs' }, true);
260-
261-
t.deepEqual(
262-
[...new Set(output1.concat(output2).map((out) => out.fileName))].sort(),
263-
['index.d.ts', 'index.js', 'server.d.ts', 'server.js']
263+
const output2 = await getCode(
264+
bundle2,
265+
{ file: 'fixtures/multiple-files/server.js', format: 'cjs' },
266+
true
264267
);
268+
269+
t.deepEqual([...new Set(output1.concat(output2).map((out) => out.fileName))].sort(), [
270+
'index.d.ts',
271+
'index.js',
272+
'server.d.ts',
273+
'server.js'
274+
]);
265275
});
266276

267277
test.serial('relative paths in tsconfig.json are resolved relative to the file', async (t) => {
@@ -877,6 +887,50 @@ test.serial('supports consecutive incremental rebuilds', async (t) => {
877887
);
878888
});
879889

890+
// https://github.com/rollup/plugins/issues/681
891+
test.serial('supports incremental rebuilds with no change to cache', async (t) => {
892+
process.chdir('fixtures/incremental-output-cache');
893+
const cleanup = () => {
894+
let files;
895+
try {
896+
files = fs.readdirSync('dist');
897+
} catch (error) {
898+
if (error.code === 'ENOENT') return;
899+
throw error;
900+
}
901+
files.forEach((file) => fs.unlinkSync(path.join('dist', file)));
902+
};
903+
904+
cleanup();
905+
906+
const firstBundle = await rollup({
907+
input: 'main.ts',
908+
plugins: [typescript()],
909+
onwarn
910+
});
911+
912+
const firstRun = await getCode(firstBundle, { format: 'esm', dir: 'dist' }, true);
913+
t.deepEqual(
914+
firstRun.map((out) => out.fileName),
915+
['main.js', '.tsbuildinfo']
916+
);
917+
await firstBundle.write({ dir: 'dist' });
918+
919+
const secondBundle = await rollup({
920+
input: 'main.ts',
921+
plugins: [typescript()],
922+
onwarn
923+
});
924+
const secondRun = await getCode(secondBundle, { format: 'esm', dir: 'dist' }, true);
925+
t.deepEqual(
926+
secondRun.map((out) => out.fileName),
927+
// .tsbuildinfo should not be emitted
928+
['main.js']
929+
);
930+
931+
cleanup();
932+
});
933+
880934
test.serial.skip('supports project references', async (t) => {
881935
process.chdir('fixtures/project-references');
882936

@@ -1088,50 +1142,48 @@ test('supports custom transformers', async (t) => {
10881142
});
10891143

10901144
function fakeTypescript(custom) {
1091-
return Object.assign(
1092-
{
1093-
sys: ts.sys,
1094-
createModuleResolutionCache: ts.createModuleResolutionCache,
1095-
ModuleKind: ts.ModuleKind,
1096-
1097-
transpileModule() {
1098-
return {
1099-
outputText: '',
1100-
diagnostics: [],
1101-
sourceMapText: JSON.stringify({ mappings: '' })
1102-
};
1103-
},
1104-
1105-
createWatchCompilerHost() {
1106-
return {
1107-
afterProgramCreate() {}
1108-
};
1109-
},
1110-
1111-
createWatchProgram() {
1112-
return {};
1113-
},
1114-
1115-
parseJsonConfigFileContent(json, host, basePath, existingOptions) {
1116-
return {
1117-
options: {
1118-
...json.compilerOptions,
1119-
...existingOptions
1120-
},
1121-
fileNames: [],
1122-
errors: []
1123-
};
1124-
},
1125-
1126-
getOutputFileNames(_, id) {
1127-
return [id.replace(/\.tsx?/, '.js')];
1128-
},
1129-
1130-
// eslint-disable-next-line no-undefined
1131-
getTsBuildInfoEmitOutputFilePath: () => undefined
1145+
return {
1146+
sys: ts.sys,
1147+
createModuleResolutionCache: ts.createModuleResolutionCache,
1148+
ModuleKind: ts.ModuleKind,
1149+
1150+
transpileModule() {
1151+
return {
1152+
outputText: '',
1153+
diagnostics: [],
1154+
sourceMapText: JSON.stringify({ mappings: '' })
1155+
};
11321156
},
1133-
custom
1134-
);
1157+
1158+
createWatchCompilerHost() {
1159+
return {
1160+
afterProgramCreate() {}
1161+
};
1162+
},
1163+
1164+
createWatchProgram() {
1165+
return {};
1166+
},
1167+
1168+
parseJsonConfigFileContent(json, host, basePath, existingOptions) {
1169+
return {
1170+
options: {
1171+
...json.compilerOptions,
1172+
...existingOptions
1173+
},
1174+
fileNames: [],
1175+
errors: []
1176+
};
1177+
},
1178+
1179+
getOutputFileNames(_, id) {
1180+
return [id.replace(/\.tsx?/, '.js')];
1181+
},
1182+
1183+
// eslint-disable-next-line no-undefined
1184+
getTsBuildInfoEmitOutputFilePath: () => undefined,
1185+
...custom
1186+
};
11351187
}
11361188

11371189
test.serial('picks up on newly included typescript files in watch mode', async (t) => {

0 commit comments

Comments
 (0)