From 0c99364e420301e62c9cdc3c5fd09e67b7627bf4 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Thu, 29 Oct 2020 16:36:46 -0400 Subject: [PATCH] fix: create Program on-demand when file exists (#126) In this test, the `node_modules/d3-drag` path is linked to `../../d3-drag` (which is a local package, not from node_modules). This setup mimics a monorepo, where dependencies often point to local packages. The local `d3-drag` package contains an `index.d.ts` module. This test fails with `Unexpected token` error, since no `Program` is found for the `d3-drag/index.d.ts` module. --- .gitignore | 2 +- src/index.ts | 20 +++++++++---------- src/program.ts | 9 +++++++++ tests/d3-drag/index.d.ts | 5 +++++ tests/d3-drag/package.json | 1 + tests/testcases/externals-link/expected.d.ts | 5 +++++ tests/testcases/externals-link/index.ts | 1 + tests/testcases/externals-link/meta.json | 8 ++++++++ .../externals-link/node_modules/d3-drag | 1 + 9 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 tests/d3-drag/index.d.ts create mode 100644 tests/d3-drag/package.json create mode 100644 tests/testcases/externals-link/expected.d.ts create mode 100644 tests/testcases/externals-link/index.ts create mode 100644 tests/testcases/externals-link/meta.json create mode 120000 tests/testcases/externals-link/node_modules/d3-drag diff --git a/.gitignore b/.gitignore index dd21b94..f30addf 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,5 @@ .nyc_output coverage dist -node_modules +/node_modules .build diff --git a/src/index.ts b/src/index.ts index bf14a01..cabb5eb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ import { PluginImpl, SourceDescription } from "rollup"; import * as ts from "typescript"; import { NamespaceFixer } from "./NamespaceFixer"; -import { createPrograms, dts, formatHost } from "./program"; +import { createProgram, createPrograms, dts, formatHost } from "./program"; import { reorderStatements } from "./reorder"; import { Transformer } from "./Transformer"; @@ -34,17 +34,9 @@ const plugin: PluginImpl = (options = {}) => { function getModule(fileName: string) { let source: ts.SourceFile | undefined; let program: ts.Program | undefined; - if (programs.length) { - // Rollup doesn't tell you the entry point of each module in the bundle, - // so we need to ask every TypeScript program for the given filename. - for (program of programs) { - source = program.getSourceFile(fileName); - if (source) break; - } - } // Create any `ts.SourceFile` objects on-demand for ".d.ts" modules, // but only when there are zero ".ts" entry points. - else if (fileName.endsWith(dts)) { + if (!programs.length && fileName.endsWith(dts)) { const code = ts.sys.readFile(fileName, "utf8"); if (code) source = ts.createSourceFile( @@ -53,6 +45,14 @@ const plugin: PluginImpl = (options = {}) => { ts.ScriptTarget.Latest, true, // setParentNodes ); + } else { + // Rollup doesn't tell you the entry point of each module in the bundle, + // so we need to ask every TypeScript program for the given filename. + program = programs.find((p) => (source = p.getSourceFile(fileName))); + if (!program && ts.sys.fileExists(fileName)) { + programs.push((program = createProgram(fileName, compilerOptions))); + source = program.getSourceFile(fileName); + } } return { source, program }; } diff --git a/src/program.ts b/src/program.ts index 3941859..64e1a9d 100644 --- a/src/program.ts +++ b/src/program.ts @@ -62,6 +62,15 @@ function getCompilerOptions( }; } +export function createProgram(fileName: string, overrideOptions: ts.CompilerOptions) { + const { dtsFiles, compilerOptions } = getCompilerOptions(fileName, overrideOptions) + return ts.createProgram( + [fileName].concat(Array.from(dtsFiles)), + compilerOptions, + ts.createCompilerHost(compilerOptions, true) + ); +} + export function createPrograms(input: Array, overrideOptions: ts.CompilerOptions) { const programs = []; let inputs: Array = []; diff --git a/tests/d3-drag/index.d.ts b/tests/d3-drag/index.d.ts new file mode 100644 index 0000000..52d4b6f --- /dev/null +++ b/tests/d3-drag/index.d.ts @@ -0,0 +1,5 @@ +/** + * Container element type usable for mouse/touch functions + */ +type DragContainerElement = HTMLElement | SVGSVGElement | SVGGElement; +export { DragContainerElement }; diff --git a/tests/d3-drag/package.json b/tests/d3-drag/package.json new file mode 100644 index 0000000..1d9a32c --- /dev/null +++ b/tests/d3-drag/package.json @@ -0,0 +1 @@ +{"name": "d3-drag"} diff --git a/tests/testcases/externals-link/expected.d.ts b/tests/testcases/externals-link/expected.d.ts new file mode 100644 index 0000000..52d4b6f --- /dev/null +++ b/tests/testcases/externals-link/expected.d.ts @@ -0,0 +1,5 @@ +/** + * Container element type usable for mouse/touch functions + */ +type DragContainerElement = HTMLElement | SVGSVGElement | SVGGElement; +export { DragContainerElement }; diff --git a/tests/testcases/externals-link/index.ts b/tests/testcases/externals-link/index.ts new file mode 100644 index 0000000..9f820e1 --- /dev/null +++ b/tests/testcases/externals-link/index.ts @@ -0,0 +1 @@ +export { DragContainerElement } from "d3-drag"; diff --git a/tests/testcases/externals-link/meta.json b/tests/testcases/externals-link/meta.json new file mode 100644 index 0000000..81594d1 --- /dev/null +++ b/tests/testcases/externals-link/meta.json @@ -0,0 +1,8 @@ +{ + "options": { + "respectExternal": true + }, + "rollupOptions": { + "external": [] + } +} diff --git a/tests/testcases/externals-link/node_modules/d3-drag b/tests/testcases/externals-link/node_modules/d3-drag new file mode 120000 index 0000000..1fc182d --- /dev/null +++ b/tests/testcases/externals-link/node_modules/d3-drag @@ -0,0 +1 @@ +../../../d3-drag \ No newline at end of file