-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathesbuild.mjs
More file actions
128 lines (116 loc) · 5.06 KB
/
esbuild.mjs
File metadata and controls
128 lines (116 loc) · 5.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import * as esbuild from "esbuild";
import process from "node:process";
import console from "node:console";
import { problemMatcher, inlineCSS } from "@hpcc-js/esbuild-plugins";
import { readFileSync, copyFileSync, mkdirSync } from "node:fs";
import path from "node:path";
const tsconfigNode = JSON.parse(readFileSync("./tsconfig.json", "utf8"));
const tsconfigBrowser = JSON.parse(readFileSync("./tsconfig.webview.json", "utf8"));
const outputDirectory = "dist";
const watch = process.argv.includes("--watch");
const production = !watch && process.argv.includes("--production");
// Custom alias plugin for pattern matching
const aliasPlugin = {
name: 'alias-plugin',
setup(build) {
const aliases = [
{
find: /^npm:(.*)$/,
replacement: "https://cdn.jsdelivr.net/npm/$1/+esm"
},
{
find: /^jsr:(.*)$/,
replacement: "https://esm.sh/jsr/$1"
}
];
build.onResolve({ filter: /^(npm|jsr):/ }, args => {
for (const alias of aliases) {
const match = args.path.match(alias.find);
if (match) {
const resolved = alias.replacement.replace('$1', match[1]);
return { path: resolved, external: true };
}
}
});
// For Node builds, use the /node subpath of @hpcc-js/observablehq-compiler
// which has a clean Node-compatible build without Rollup's broken require() stubs.
if (build.initialOptions.platform === "node") {
build.onResolve({ filter: /^@hpcc-js\/observablehq-compiler$/ }, () => {
return { path: path.resolve("node_modules/@hpcc-js/observablehq-compiler/dist/node/index.js") };
});
}
}
};
const xhrSyncWorkerPlugin = {
name: "xhr-sync-worker",
setup(build) {
const workerSource = path.resolve("node_modules/jsdom/lib/jsdom/living/xhr/xhr-sync-worker.js");
build.onStart(() => {
try {
// Ensure the output directory exists before copying (production builds often start from a clean state)
mkdirSync(outputDirectory, { recursive: true });
copyFileSync(workerSource, path.join(outputDirectory, "xhr-sync-worker.js"));
} catch {
// Ignore if jsdom not installed; worker not needed.
}
});
build.onLoad({ filter: /XMLHttpRequest-impl\.js$/ }, async (args) => {
let contents = readFileSync(args.path, "utf8");
// Replace only if the exact snippet exists.
const search = 'const syncWorkerFile = require.resolve ? require.resolve("./xhr-sync-worker.js") : null;';
if (contents.includes(search)) {
contents = contents.replace(search, 'const syncWorkerFile = require.resolve ? require.resolve(require("node:path").join(__dirname, "xhr-sync-worker.js")) : null;');
}
return { contents, loader: "js" };
});
}
};
async function main(tsconfigRaw, entryPoint, platform, format, plugins = [], outputName = null) {
// External dependencies for browser builds - npm: protocol dependencies from Observable Kit
const npmExternals = [
// "npm:d3-dsv", "npm:apache-arrow", "npm:arquero", "npm:parquet-wasm",
// "npm:lodash", "npm:d3", "npm:@duckdb/duckdb-wasm", "npm:echarts",
// "npm:htl", "npm:@observablehq/plot", "npm:react", "npm:react-dom",
// "npm:topojson-client", "npm:@observablehq/inputs", "npm:vega",
// "npm:mermaid", "npm:mapbox-gl", "npm:leaflet", "npm:@viz-js/viz",
// "npm:katex", "npm:vega-lite", "npm:vega-lite-api"
];
const external = platform === "node"
? ["vscode"]
: ["vscode", ...npmExternals];
const ctx = await esbuild.context({
tsconfigRaw,
entryPoints: outputName ? { [outputName]: entryPoint } : [entryPoint],
outdir: outputDirectory,
bundle: true,
format,
minify: production,
sourcemap: !production ? "linked" : false,
platform,
target: platform === "node" ? "node20" : "es2022",
external,
logLevel: production ? "silent" : "info",
// No alias overrides currently needed; remove invalid relative alias that broke esbuild
// We intentionally do not suppress jsdom warnings; instead we rewrite resolution for the worker.
plugins: [
aliasPlugin,
...plugins,
problemMatcher(),
]
});
if (watch) {
await ctx.watch();
} else {
await ctx.rebuild();
await ctx.dispose();
}
}
Promise.all([
main(tsconfigNode, "./src/extension.ts", "node", "cjs", [xhrSyncWorkerPlugin]),
main(tsconfigBrowser, "./src/notebook/renderers/ojsRenderer.ts", "browser", "esm"),
main(tsconfigBrowser, "./src/notebook-kit/renderers/renderer.ts", "browser", "esm", [inlineCSS()], "observable-kit-renderer"),
main(tsconfigBrowser, "./src/webview.ts", "browser", "iife")
]).catch((e) => {
console.error(e);
process.exit(1);
});