Skip to content

Commit

Permalink
fix hashes for modules importing builtins (#1688)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock authored Sep 26, 2024
1 parent c3012a3 commit 4ca8e9e
Show file tree
Hide file tree
Showing 24 changed files with 70 additions and 15 deletions.
9 changes: 7 additions & 2 deletions src/javascript/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import {extname, join} from "node:path/posix";
import type {Program} from "acorn";
import type {TransformOptions} from "esbuild";
import {transform, transformSync} from "esbuild";
import {resolveJsrImport} from "../jsr.js";
import {resolveNodeImport} from "../node.js";
import {resolveNpmImport} from "../npm.js";
import {resolvePath} from "../path.js";
import {builtins} from "../resolvers.js";
import {builtins, resolveBuiltin} from "../resolvers.js";
import type {RouteResult} from "../route.js";
import {route} from "../route.js";
import {findFiles} from "./files.js";
Expand Down Expand Up @@ -94,8 +95,12 @@ export async function getLocalModuleHash(root: string, path: string, getHash?: (
if (info) {
const globalPaths = new Set<string>();
for (const i of [...info.globalStaticImports, ...info.globalDynamicImports]) {
if (i.startsWith("npm:") && !builtins.has(i)) {
if (builtins.has(i) || i.startsWith("observablehq:")) {
hash.update(`${resolveBuiltin(i)}?version=${process.env.npm_package_version}`); // change hash when Framework changes
} else if (i.startsWith("npm:")) {
globalPaths.add(await resolveNpmImport(root, i.slice("npm:".length)));
} else if (i.startsWith("jsr:")) {
globalPaths.add(await resolveJsrImport(root, i.slice("jsr:".length)));
} else if (!/^\w+:/.test(i)) {
globalPaths.add(await resolveNodeImport(root, i));
}
Expand Down
12 changes: 8 additions & 4 deletions src/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -477,10 +477,8 @@ export function getModuleResolver(
return async (specifier) => {
return isPathImport(specifier)
? relativePath(servePath, resolveImportPath(root, resolvePath(path, specifier), getHash))
: builtins.has(specifier)
? relativePath(servePath, builtins.get(specifier)!)
: specifier.startsWith("observablehq:")
? relativePath(servePath, `/_observablehq/${specifier.slice("observablehq:".length)}${extname(specifier) ? "" : ".js"}`) // prettier-ignore
: builtins.has(specifier) || specifier.startsWith("observablehq:")
? relativePath(servePath, resolveBuiltin(specifier))
: specifier.startsWith("npm:")
? relativePath(servePath, await resolveNpmImport(root, specifier.slice("npm:".length)))
: specifier.startsWith("jsr:")
Expand All @@ -491,6 +489,12 @@ export function getModuleResolver(
};
}

export function resolveBuiltin(specifier: string): string {
if (builtins.has(specifier)) return builtins.get(specifier)!;
if (!specifier.startsWith("observablehq:")) throw new Error(`not built-in: ${specifier}`);
return `/_observablehq/${specifier.slice("observablehq:".length)}${extname(specifier) ? "" : ".js"}`;
}

export function resolveStylesheetPath(root: string, path: string): string {
return `/${join("_import", path)}?sha=${getFileHash(root, path)}`;
}
Expand Down
1 change: 1 addition & 0 deletions test/input/build/npm/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "npm:@observablehq/inputs";
3 changes: 3 additions & 0 deletions test/input/build/npm/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```js
import "./index.js";
```
1 change: 1 addition & 0 deletions test/mocks/jsdelivr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const packages: [name: string, {version: string; dependencies?: Record<string, s
["echarts", {version: "5.5.0"}],
["exceljs", {version: "4.4.0"}],
["htl", {version: "0.3.1"}],
["isoformat", {version: "0.2.1"}],
["jszip", {version: "3.10.1"}],
["katex", {version: "0.16.9"}],
["leaflet", {version: "1.9.4"}],
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export {test} from "./test.17d808d0.js";
export {test} from "./test.86a60bc6.js";
2 changes: 1 addition & 1 deletion test/output/build/data-loaders/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<link rel="modulepreload" href="./_observablehq/runtime.00000002.js">
<link rel="modulepreload" href="./_observablehq/stdlib.00000003.js">
<link rel="modulepreload" href="./_import/import-test.e7269c4e.js">
<link rel="modulepreload" href="./_import/test.17d808d0.js">
<link rel="modulepreload" href="./_import/test.86a60bc6.js">
<script type="module">

import {define} from "./_observablehq/client.00000001.js";
Expand Down
2 changes: 1 addition & 1 deletion test/output/build/embed/chart.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import "./_observablehq/stdlib.00000003.js";
import "./_npm/@observablehq/plot@0.6.11/cd372fb8.js";
import "./_npm/d3-dsv@3.0.1/cd372fb8.js";
export * from "./_import/chart.76ef5352.js";
export * from "./_import/chart.2ce91e05.js";

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

4 changes: 2 additions & 2 deletions test/output/build/fetches/foo.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<link rel="modulepreload" href="./_observablehq/client.00000001.js">
<link rel="modulepreload" href="./_observablehq/runtime.00000002.js">
<link rel="modulepreload" href="./_observablehq/stdlib.00000003.js">
<link rel="modulepreload" href="./_import/foo/foo.3bb4a170.js">
<link rel="modulepreload" href="./_import/foo/foo.666599bc.js">
<script type="module">

import {define} from "./_observablehq/client.00000001.js";
Expand All @@ -21,7 +21,7 @@
registerFile("./foo/foo-data.json", {"name":"./foo/foo-data.json","mimeType":"application/json","path":"./_file/foo/foo-data.67358ed8.json","lastModified":/* ts */1706742000000,"size":10});

define({id: "47a695da", inputs: ["display"], outputs: ["fooJsonData","fooCsvData"], body: async (display) => {
const {fooJsonData, fooCsvData} = await import("./_import/foo/foo.3bb4a170.js");
const {fooJsonData, fooCsvData} = await import("./_import/foo/foo.666599bc.js");

display(fooJsonData);
display(fooCsvData);
Expand Down
6 changes: 3 additions & 3 deletions test/output/build/fetches/top.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
<link rel="modulepreload" href="./_observablehq/client.00000001.js">
<link rel="modulepreload" href="./_observablehq/runtime.00000002.js">
<link rel="modulepreload" href="./_observablehq/stdlib.00000003.js">
<link rel="modulepreload" href="./_import/top.6c858de5.js">
<link rel="modulepreload" href="./_import/foo/foo.3bb4a170.js">
<link rel="modulepreload" href="./_import/top.c85e149a.js">
<link rel="modulepreload" href="./_import/foo/foo.666599bc.js">
<script type="module">

import {define} from "./_observablehq/client.00000001.js";
Expand All @@ -24,7 +24,7 @@
registerFile("./top-data.json", {"name":"./top-data.json","mimeType":"application/json","path":"./_file/top-data.67358ed8.json","lastModified":/* ts */1706742000000,"size":10});

define({id: "cb908c08", inputs: ["display"], outputs: ["fooCsvData","fooJsonData","topCsvData","topJsonData"], body: async (display) => {
const {fooCsvData, fooJsonData, topCsvData, topJsonData} = await import("./_import/top.6c858de5.js");
const {fooCsvData, fooJsonData, topCsvData, topJsonData} = await import("./_import/top.c85e149a.js");

display(fooJsonData);
display(fooCsvData);
Expand Down
1 change: 1 addition & 0 deletions test/output/build/npm/_import/index.4bdc071f.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "../_observablehq/stdlib/inputs.00000005.js";
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
40 changes: 40 additions & 0 deletions test/output/build/npm/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="generator" content="Observable Framework v1.0.0-test">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Source+Serif+4:ital,opsz,wght@0,8..60,200..900;1,8..60,200..900&amp;display=swap" crossorigin>
<link rel="preload" as="style" href="./_observablehq/theme-air,near-midnight.00000004.css">
<link rel="preload" as="style" href="./_observablehq/stdlib/inputs.00000006.css">
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css2?family=Source+Serif+4:ital,opsz,wght@0,8..60,200..900;1,8..60,200..900&amp;display=swap" crossorigin>
<link rel="stylesheet" type="text/css" href="./_observablehq/theme-air,near-midnight.00000004.css">
<link rel="stylesheet" type="text/css" href="./_observablehq/stdlib/inputs.00000006.css">
<link rel="modulepreload" href="./_observablehq/client.00000001.js">
<link rel="modulepreload" href="./_observablehq/runtime.00000002.js">
<link rel="modulepreload" href="./_observablehq/stdlib.00000003.js">
<link rel="modulepreload" href="./_import/index.4bdc071f.js">
<link rel="modulepreload" href="./_observablehq/stdlib/inputs.00000005.js">
<link rel="modulepreload" href="./_npm/htl@0.3.1/cd372fb8.js">
<link rel="modulepreload" href="./_npm/isoformat@0.2.1/cd372fb8.js">
<script type="module">

import {define} from "./_observablehq/client.00000001.js";

define({id: "0e31b7ef", body: async () => {
const {} = await import("./_import/index.4bdc071f.js");

}});

</script>
<div id="observablehq-center">
<aside id="observablehq-toc" data-selector="h1:not(:first-of-type)[id], h2:first-child[id], :not(h1) + h2[id]">
<nav>
</nav>
</aside>
<main id="observablehq-main" class="observablehq">
<div class="observablehq observablehq--block"><!--:0e31b7ef:--></div>
</main>
<footer id="observablehq-footer">
<div>Built with <a href="https://observablehq.com/" target="_blank" rel="noopener noreferrer">Observable</a> on <a title="2024-01-10T16:00:00">Jan 10, 2024</a>.</div>
</footer>
</div>

0 comments on commit 4ca8e9e

Please sign in to comment.