Skip to content

Commit 3b96f28

Browse files
committed
don’t prune import map (yet)
1 parent 5d6d4cb commit 3b96f28

File tree

2 files changed

+29
-18
lines changed

2 files changed

+29
-18
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ TODO
7070
- ✅ parse imports from npm:module and generate the corresponding import map
7171
- ✅ npm packages
7272
- ✅ use ES module imports for (most) recommended libraries
73+
- parse local ES modules for npm imports; add to import map and module preload
7374
- parallelize awaits when multiple static import statements
7475
- local Markdown files
7576
- cloud Observable notebooks?

src/render.ts

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,12 @@ ${
5555
}<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css2?family=Source+Serif+Pro:ital,wght@0,400;0,600;0,700;1,400;1,600;1,700&display=swap">
5656
<link rel="stylesheet" type="text/css" href="/_observablehq/style.css">
5757
<script type="importmap">
58-
${JSON.stringify({imports: Object.fromEntries(imports)}, null, 2)}
58+
${JSON.stringify({imports: Object.fromEntries(Array.from(imports, ([name, [href]]) => [name, href]))}, null, 2)}
5959
</script>
60-
${imports.map(([, href]) => `<link rel="modulepreload" href="${href}">`).join("\n")}
60+
${Array.from(imports.values())
61+
.filter(([, preload]) => preload)
62+
.map(([href]) => `<link rel="modulepreload" href="${href}">`)
63+
.join("\n")}
6164
<script type="module">
6265
6366
import {${preview ? "open, " : ""}define} from "/_observablehq/client.js";
@@ -104,23 +107,30 @@ ${parseResult.html}</main>
104107
`;
105108
}
106109

107-
function getImportMap(parseResult: ParseResult): [name: string, href: string][] {
108-
const modules = new Set(["npm:@observablehq/runtime"]);
109-
if (parseResult.cells.some((c) => c.inputs?.includes("d3") || c.inputs?.includes("Plot"))) modules.add("npm:d3");
110-
if (parseResult.cells.some((c) => c.inputs?.includes("Plot"))) modules.add("npm:@observablehq/plot");
111-
if (parseResult.cells.some((c) => c.inputs?.includes("htl") || c.inputs?.includes("Inputs"))) modules.add("npm:htl");
112-
if (parseResult.cells.some((c) => c.inputs?.includes("Inputs"))) modules.add("npm:@observablehq/inputs");
113-
for (const {name} of parseResult.imports) {
114-
if (name.startsWith("npm:")) {
115-
modules.add(name);
116-
}
110+
// These are always supplied in the import map so that npm imports work from
111+
// local ES modules. TODO We’ll need to parse local ES modules and detect their
112+
// npm imports; and we’ll want to preload those modules, too!
113+
const baseImportMap: Map<string, [href: string, preload: boolean]> = new Map([
114+
["npm:@observablehq/inputs", ["https://cdn.jsdelivr.net/npm/@observablehq/inputs/+esm", false]],
115+
["npm:@observablehq/plot", ["https://cdn.jsdelivr.net/npm/@observablehq/plot/+esm", false]],
116+
["npm:@observablehq/runtime", ["/_observablehq/runtime.js", true]],
117+
["npm:d3", ["https://cdn.jsdelivr.net/npm/d3/+esm", false]],
118+
["npm:htl", ["https://cdn.jsdelivr.net/npm/htl/+esm", false]]
119+
]);
120+
121+
function getImportMap(parseResult: ParseResult): Map<string, [href: string, preload: boolean]> {
122+
const map = new Map(baseImportMap);
123+
const imports = parseResult.imports.map(({name}) => name);
124+
const inputs = new Set(parseResult.cells.flatMap((cell) => cell.inputs ?? []));
125+
if (inputs.has("d3") || inputs.has("Plot")) imports.push("npm:d3");
126+
if (inputs.has("Plot")) imports.push("npm:@observablehq/plot");
127+
if (inputs.has("htl") || inputs.has("Inputs")) imports.push("npm:htl");
128+
if (inputs.has("Inputs")) imports.push("npm:@observablehq/inputs");
129+
for (const name of imports) {
130+
if (map.has(name)) map.set(name, [map.get(name)![0], true]);
131+
else map.set(name, [`https://cdn.jsdelivr.net/npm/${name.slice(4)}/+esm`, true]);
117132
}
118-
return Array.from(modules, (name) => [
119-
name,
120-
name === "npm:@observablehq/runtime"
121-
? "/_observablehq/runtime.js" // self-hosted
122-
: `https://cdn.jsdelivr.net/npm/${name.slice(4)}/+esm`
123-
]);
133+
return map;
124134
}
125135

126136
// TODO Adopt Hypertext Literal?

0 commit comments

Comments
 (0)