Skip to content

Commit 42370bc

Browse files
committed
Resolve issue #1652
1 parent 33174f9 commit 42370bc

File tree

6 files changed

+77
-29
lines changed

6 files changed

+77
-29
lines changed

packages/typescript/src/index.ts

+43-21
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as path from 'path';
22

33
import { createFilter } from '@rollup/pluginutils';
44

5-
import type { Plugin, SourceDescription } from 'rollup';
5+
import type { Plugin, PluginContext, SourceDescription } from 'rollup';
66
import type { Watch } from 'typescript';
77

88
import type { RollupTypescriptOptions } from '../types';
@@ -37,6 +37,31 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi
3737
tslib,
3838
typescript: ts
3939
} = getPluginOptions(options);
40+
const createProgram = (context: PluginContext) =>
41+
createWatchProgram(ts, context, {
42+
formatHost,
43+
resolveModule,
44+
parsedOptions,
45+
writeFile(fileName, data, _writeByteOrderMark, _onError, sourceFiles) {
46+
if (sourceFiles) {
47+
for (const sourceFile of sourceFiles) {
48+
if (!parsedOptions.fileNames.includes(sourceFile.fileName)) {
49+
parsedOptions.fileNames.push(sourceFile.fileName);
50+
}
51+
}
52+
}
53+
54+
if (parsedOptions.options.composite || parsedOptions.options.incremental) {
55+
tsCache.cacheCode(fileName, data);
56+
}
57+
emittedFiles.set(fileName, data);
58+
},
59+
status(diagnostic) {
60+
watchProgramHelper.handleStatus(diagnostic);
61+
},
62+
transformers
63+
});
64+
4065
const tsCache = new TSCache(cacheDir);
4166
const emittedFiles = new Map<string, string>();
4267
const watchProgramHelper = new WatchProgramHelper();
@@ -56,6 +81,14 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi
5681
name: 'typescript',
5782

5883
buildStart(rollupOptions) {
84+
if (typeof rollupOptions.input === 'string') {
85+
rollupOptions.input = [rollupOptions.input];
86+
}
87+
88+
if (Array.isArray(rollupOptions.input)) {
89+
parsedOptions.fileNames = rollupOptions.input.map((fileName) => path.resolve(fileName));
90+
}
91+
5992
emitParsedOptionsErrors(ts, this, parsedOptions);
6093

6194
preflight({
@@ -74,21 +107,7 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi
74107
program = null;
75108
}
76109
if (!program) {
77-
program = createWatchProgram(ts, this, {
78-
formatHost,
79-
resolveModule,
80-
parsedOptions,
81-
writeFile(fileName, data) {
82-
if (parsedOptions.options.composite || parsedOptions.options.incremental) {
83-
tsCache.cacheCode(fileName, data);
84-
}
85-
emittedFiles.set(fileName, data);
86-
},
87-
status(diagnostic) {
88-
watchProgramHelper.handleStatus(diagnostic);
89-
},
90-
transformers
91-
});
110+
program = createProgram(this);
92111
}
93112
},
94113

@@ -139,7 +158,6 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi
139158

140159
if (resolved) {
141160
if (/\.d\.[cm]?ts/.test(resolved.extension)) return null;
142-
if (!filter(resolved.resolvedFileName)) return null;
143161
return path.normalize(resolved.resolvedFileName);
144162
}
145163

@@ -149,16 +167,20 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi
149167
async load(id) {
150168
if (!filter(id)) return null;
151169

152-
this.addWatchFile(id);
170+
const resolvedId = path.resolve(id);
171+
172+
this.addWatchFile(resolvedId);
153173
await watchProgramHelper.wait();
154174

155-
const fileName = normalizePath(id);
175+
const fileName = normalizePath(resolvedId);
156176
if (!parsedOptions.fileNames.includes(fileName)) {
157177
// Discovered new file that was not known when originally parsing the TypeScript config
158-
parsedOptions.fileNames.push(fileName);
178+
parsedOptions.fileNames.push(path.resolve(fileName));
179+
180+
createProgram(this).close();
159181
}
160182

161-
const output = findTypescriptOutput(ts, parsedOptions, id, emittedFiles, tsCache);
183+
const output = findTypescriptOutput(ts, parsedOptions, resolvedId, emittedFiles, tsCache);
162184

163185
return output.code != null ? (output as SourceDescription) : null;
164186
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// eslint-disable-next-line
2+
foo
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import {foo} from "./valid";
2+
3+
console.log(foo);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const foo = 5;

packages/typescript/test/test.js

+17-1
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,8 @@ test.serial('does it support tsconfig.rootDir for filtering', async (t) => {
10741074
t.is(files.length, 1);
10751075
});
10761076

1077-
test.serial('does it fail for filtering with incorrect rootDir in nested projects', async (t) => {
1077+
// todo: why would want to deliberately forbid resolution from outside of CWD? What problem does it solve to add such a constraint?
1078+
test.skip('does it fail for filtering with incorrect rootDir in nested projects', async (t) => {
10781079
process.chdir('fixtures/root-dir/packages/test-2');
10791080
const error = await t.throwsAsync(
10801081
rollup({
@@ -1420,3 +1421,18 @@ test.serial('compiled external library', async (t) => {
14201421
});
14211422
t.pass();
14221423
});
1424+
1425+
test.serial(
1426+
'do not consider files that are not part of the entry point dependency graph',
1427+
async (t) => {
1428+
process.chdir('fixtures/with-invalid-sources-inside-cwd');
1429+
const input = 'main.ts';
1430+
1431+
const build = await rollup({
1432+
input,
1433+
plugins: [typescript()]
1434+
});
1435+
1436+
t.deepEqual(build.watchFiles, [path.resolve('main.ts'), path.resolve('valid.ts')]);
1437+
}
1438+
);

packages/typescript/test/tslib.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { platform } from 'os';
22

3+
import { resolve } from 'path';
4+
35
import test from 'ava';
46
import type { RollupError } from 'rollup';
57
import { rollup } from 'rollup';
@@ -62,13 +64,15 @@ test.serial('fails on bad tslib path', async (t) => {
6264
return;
6365
}
6466

65-
if (error.watchFiles) {
66-
let [filePath] = error.watchFiles;
67-
filePath = filePath.substring(filePath.indexOf('packages'));
68-
error.watchFiles[0] = filePath;
69-
}
70-
71-
t.snapshot(error);
67+
t.deepEqual(
68+
error.message,
69+
`Could not load fixtures/joker/tslib.js (imported by fixtures/overriding-tslib/main.ts): ENOENT: no such file or directory, open 'fixtures/joker/tslib.js'`
70+
);
71+
t.deepEqual(error.watchFiles, [
72+
resolve('fixtures/overriding-tslib/main.ts'),
73+
'fixtures/joker/tslib.js'
74+
]);
75+
t.deepEqual(error.code, 'ENOENT');
7276
});
7377

7478
test.serial('fails without tslib installed', async (t) => {

0 commit comments

Comments
 (0)