Skip to content

Commit

Permalink
Resolve issue rollup#1652
Browse files Browse the repository at this point in the history
  • Loading branch information
ericmorand committed Dec 16, 2023
1 parent 33174f9 commit 5d6ebe9
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 31 deletions.
56 changes: 34 additions & 22 deletions packages/typescript/src/index.ts
Expand Up @@ -2,7 +2,7 @@ import * as path from 'path';

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

import type { Plugin, SourceDescription } from 'rollup';
import type { Plugin, PluginContext, SourceDescription } from 'rollup';
import type { Watch } from 'typescript';

import type { RollupTypescriptOptions } from '../types';
Expand Down Expand Up @@ -37,6 +37,23 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi
tslib,
typescript: ts
} = getPluginOptions(options);
const createProgram = (context: PluginContext) =>
createWatchProgram(ts, context, {
formatHost,
resolveModule,
parsedOptions,
writeFile(fileName, data) {
if (parsedOptions.options.composite || parsedOptions.options.incremental) {
tsCache.cacheCode(fileName, data);
}
emittedFiles.set(fileName, data);
},
status(diagnostic) {
watchProgramHelper.handleStatus(diagnostic);
},
transformers
});

const tsCache = new TSCache(cacheDir);
const emittedFiles = new Map<string, string>();
const watchProgramHelper = new WatchProgramHelper();
Expand All @@ -56,6 +73,14 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi
name: 'typescript',

buildStart(rollupOptions) {
if (typeof rollupOptions.input === 'string') {
parsedOptions.fileNames = [path.resolve(rollupOptions.input)];
}

if (Array.isArray(rollupOptions.input)) {
parsedOptions.fileNames = rollupOptions.input.map((fileName) => path.resolve(fileName));
}

emitParsedOptionsErrors(ts, this, parsedOptions);

preflight({
Expand All @@ -74,21 +99,7 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi
program = null;
}
if (!program) {
program = createWatchProgram(ts, this, {
formatHost,
resolveModule,
parsedOptions,
writeFile(fileName, data) {
if (parsedOptions.options.composite || parsedOptions.options.incremental) {
tsCache.cacheCode(fileName, data);
}
emittedFiles.set(fileName, data);
},
status(diagnostic) {
watchProgramHelper.handleStatus(diagnostic);
},
transformers
});
program = createProgram(this);
}
},

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

if (resolved) {
if (/\.d\.[cm]?ts/.test(resolved.extension)) return null;
if (!filter(resolved.resolvedFileName)) return null;
return path.normalize(resolved.resolvedFileName);
}

return null;
},

async load(id) {
if (!filter(id)) return null;
const resolvedId = path.resolve(id);

this.addWatchFile(id);
this.addWatchFile(resolvedId);
await watchProgramHelper.wait();

const fileName = normalizePath(id);
const fileName = normalizePath(resolvedId);
if (!parsedOptions.fileNames.includes(fileName)) {
// Discovered new file that was not known when originally parsing the TypeScript config
parsedOptions.fileNames.push(fileName);
parsedOptions.fileNames.push(path.resolve(fileName));

createProgram(this).close();
}

const output = findTypescriptOutput(ts, parsedOptions, id, emittedFiles, tsCache);
const output = findTypescriptOutput(ts, parsedOptions, resolvedId, emittedFiles, tsCache);

return output.code != null ? (output as SourceDescription) : null;
},
Expand Down
@@ -0,0 +1,2 @@
// eslint-disable-next-line
foo
@@ -0,0 +1,3 @@
import {foo} from "./valid";

console.log(foo);
@@ -0,0 +1 @@
export const foo = 5;
23 changes: 21 additions & 2 deletions packages/typescript/test/test.js
Expand Up @@ -394,7 +394,9 @@ test.serial('supports overriding the TypeScript version', async (t) => {
// Call the overrided emit function to trigger writeFile
program.emit();

return { close() {} };
return {
close() {}
};
}
})
})
Expand Down Expand Up @@ -1074,14 +1076,16 @@ test.serial('does it support tsconfig.rootDir for filtering', async (t) => {
t.is(files.length, 1);
});

test.serial('does it fail for filtering with incorrect rootDir in nested projects', async (t) => {
// todo: why would want to deliberately forbid resolution from outside of CWD? What problem does it solve to add such a constraint?
test.skip('does it fail for filtering with incorrect rootDir in nested projects', async (t) => {
process.chdir('fixtures/root-dir/packages/test-2');
const error = await t.throwsAsync(
rollup({
input: 'main.ts',
plugins: [typescript({ tsconfig: 'tsconfig.json' })]
})
);

// It imports a typescript file outside CWD, hence will not get resolved
t.is(error.code, 'UNRESOLVED_IMPORT');
});
Expand Down Expand Up @@ -1420,3 +1424,18 @@ test.serial('compiled external library', async (t) => {
});
t.pass();
});

test.serial(
'do not consider files that are not part of the entry point dependency graph',
async (t) => {
process.chdir('fixtures/with-invalid-sources-inside-cwd');
const input = 'main.ts';

const build = await rollup({
input,
plugins: [typescript()]
});

t.deepEqual(build.watchFiles, [path.resolve('main.ts'), path.resolve('valid.ts')]);
}
);
19 changes: 12 additions & 7 deletions packages/typescript/test/tslib.ts
@@ -1,5 +1,7 @@
import { platform } from 'os';

import { resolve } from 'path';

import test from 'ava';
import type { RollupError } from 'rollup';
import { rollup } from 'rollup';
Expand Down Expand Up @@ -62,13 +64,16 @@ test.serial('fails on bad tslib path', async (t) => {
return;
}

if (error.watchFiles) {
let [filePath] = error.watchFiles;
filePath = filePath.substring(filePath.indexOf('packages'));
error.watchFiles[0] = filePath;
}

t.snapshot(error);
t.deepEqual(
error.message,
`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'`
);
t.deepEqual(error.watchFiles, [
resolve('fixtures/overriding-tslib/main.ts'),
resolve('fixtures/joker/tslib.js'),
'fixtures/joker/tslib.js'
]);
t.deepEqual(error.code, 'ENOENT');
});

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

0 comments on commit 5d6ebe9

Please sign in to comment.