Skip to content

Commit c5015b5

Browse files
committed
Resolve issue rollup#1652
1 parent 33174f9 commit c5015b5

File tree

6 files changed

+70
-30
lines changed

6 files changed

+70
-30
lines changed

packages/typescript/src/index.ts

Lines changed: 34 additions & 22 deletions
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,23 @@ 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) {
46+
if (parsedOptions.options.composite || parsedOptions.options.incremental) {
47+
tsCache.cacheCode(fileName, data);
48+
}
49+
emittedFiles.set(fileName, data);
50+
},
51+
status(diagnostic) {
52+
watchProgramHelper.handleStatus(diagnostic);
53+
},
54+
transformers
55+
});
56+
4057
const tsCache = new TSCache(cacheDir);
4158
const emittedFiles = new Map<string, string>();
4259
const watchProgramHelper = new WatchProgramHelper();
@@ -56,6 +73,14 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi
5673
name: 'typescript',
5774

5875
buildStart(rollupOptions) {
76+
if (typeof rollupOptions.input === 'string') {
77+
parsedOptions.fileNames = [path.resolve(rollupOptions.input)];
78+
}
79+
80+
if (Array.isArray(rollupOptions.input)) {
81+
parsedOptions.fileNames = rollupOptions.input.map((fileName) => path.resolve(fileName));
82+
}
83+
5984
emitParsedOptionsErrors(ts, this, parsedOptions);
6085

6186
preflight({
@@ -74,21 +99,7 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi
7499
program = null;
75100
}
76101
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-
});
102+
program = createProgram(this);
92103
}
93104
},
94105

@@ -139,26 +150,27 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi
139150

140151
if (resolved) {
141152
if (/\.d\.[cm]?ts/.test(resolved.extension)) return null;
142-
if (!filter(resolved.resolvedFileName)) return null;
143153
return path.normalize(resolved.resolvedFileName);
144154
}
145155

146156
return null;
147157
},
148158

149159
async load(id) {
150-
if (!filter(id)) return null;
160+
const resolvedId = path.resolve(id);
151161

152-
this.addWatchFile(id);
162+
this.addWatchFile(resolvedId);
153163
await watchProgramHelper.wait();
154164

155-
const fileName = normalizePath(id);
165+
const fileName = normalizePath(resolvedId);
156166
if (!parsedOptions.fileNames.includes(fileName)) {
157167
// Discovered new file that was not known when originally parsing the TypeScript config
158-
parsedOptions.fileNames.push(fileName);
168+
parsedOptions.fileNames.push(path.resolve(fileName));
169+
170+
createProgram(this).close();
159171
}
160172

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

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

packages/typescript/test/test.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1074,14 +1074,16 @@ 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({
10811082
input: 'main.ts',
10821083
plugins: [typescript({ tsconfig: 'tsconfig.json' })]
10831084
})
10841085
);
1086+
10851087
// It imports a typescript file outside CWD, hence will not get resolved
10861088
t.is(error.code, 'UNRESOLVED_IMPORT');
10871089
});
@@ -1420,3 +1422,18 @@ test.serial('compiled external library', async (t) => {
14201422
});
14211423
t.pass();
14221424
});
1425+
1426+
test.serial(
1427+
'do not consider files that are not part of the entry point dependency graph',
1428+
async (t) => {
1429+
process.chdir('fixtures/with-invalid-sources-inside-cwd');
1430+
const input = 'main.ts';
1431+
1432+
const build = await rollup({
1433+
input,
1434+
plugins: [typescript()]
1435+
});
1436+
1437+
t.deepEqual(build.watchFiles, [path.resolve('main.ts'), path.resolve('valid.ts')]);
1438+
}
1439+
);

packages/typescript/test/tslib.ts

Lines changed: 12 additions & 7 deletions
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,16 @@ 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+
resolve('fixtures/joker/tslib.js'),
74+
'fixtures/joker/tslib.js'
75+
]);
76+
t.deepEqual(error.code, 'ENOENT');
7277
});
7378

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

0 commit comments

Comments
 (0)