Skip to content

Commit

Permalink
fix: create Program on-demand when file exists (#126)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
aleclarson committed Oct 29, 2020
1 parent cdd64c7 commit 0c99364
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Expand Up @@ -2,5 +2,5 @@
.nyc_output
coverage
dist
node_modules
/node_modules
.build
20 changes: 10 additions & 10 deletions src/index.ts
Expand Up @@ -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";

Expand Down Expand Up @@ -34,17 +34,9 @@ const plugin: PluginImpl<Options> = (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(
Expand All @@ -53,6 +45,14 @@ const plugin: PluginImpl<Options> = (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 };
}
Expand Down
9 changes: 9 additions & 0 deletions src/program.ts
Expand Up @@ -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<string>, overrideOptions: ts.CompilerOptions) {
const programs = [];
let inputs: Array<string> = [];
Expand Down
5 changes: 5 additions & 0 deletions 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 };
1 change: 1 addition & 0 deletions tests/d3-drag/package.json
@@ -0,0 +1 @@
{"name": "d3-drag"}
5 changes: 5 additions & 0 deletions 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 };
1 change: 1 addition & 0 deletions tests/testcases/externals-link/index.ts
@@ -0,0 +1 @@
export { DragContainerElement } from "d3-drag";
8 changes: 8 additions & 0 deletions tests/testcases/externals-link/meta.json
@@ -0,0 +1,8 @@
{
"options": {
"respectExternal": true
},
"rollupOptions": {
"external": []
}
}
1 change: 1 addition & 0 deletions tests/testcases/externals-link/node_modules/d3-drag

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 comments on commit 0c99364

@aleclarson
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get a release for this?

@Swatinem
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

published, sorry for the delay.

Please sign in to comment.