Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion bin/typedoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
//@ts-check

const { fork } = require("child_process");
const { existsSync } = require("fs");
const path = require("path");

const bundled = path.join(__dirname, "..", "dist", "lib", "cli.bundled.js");
const fallback = path.join(__dirname, "..", "dist", "lib", "cli.js");
const entry = existsSync(bundled) ? bundled : fallback;

function main() {
fork(__dirname + "/../dist/lib/cli.js", process.argv.slice(2), {
fork(entry, process.argv.slice(2), {
stdio: "inherit",
}).on("exit", (code) => {
// Watch restart required? Fork a new child
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,12 @@
"example": "cd example && node ../bin/typedoc",
"test:full": "c8 -r lcov -r text-summary mocha --config .config/mocha.full.json",
"rebuild_specs": "node scripts/rebuild_specs.js",
"build": "pnpm build:tsc && pnpm build:locales && pnpm build:themes",
"build": "pnpm build:tsc && pnpm build:locales && pnpm build:themes && pnpm build:bundle",
"build:tsc": "tsc --project .",
"build:themes": "node scripts/build_themes.js",
"build:locales": "node scripts/build_browser_translations.js",
"build:prod": "pnpm build:prod:tsc && pnpm build:locales && pnpm build:themes && node scripts/generate_options_schema.js typedoc-config.schema.json",
"build:bundle": "node scripts/build_bundle.js",
"build:prod": "pnpm build:prod:tsc && pnpm build:locales && pnpm build:themes && pnpm build:bundle && node scripts/generate_options_schema.js typedoc-config.schema.json",
"build:prod:tsc": "tsc --project . --sourceMap false --declarationMap false",
"lint": "eslint . --max-warnings 0 && dprint check",
"prepack": "node scripts/set_strict.js false && pnpm build:prod",
Expand Down
49 changes: 49 additions & 0 deletions scripts/build_bundle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// @ts-check
//
// Bundle typedoc's CLI entry point into a single file via esbuild.
//
// Why this exists: typedoc's compiled output uses `import.meta.url` in a few
// places (locale loading in internationalization.js, TYPEDOC_ROOT in
// utils/general.js, theme assets in AssetsPlugin.js) to compute paths relative
// to the source file's on-disk location. When esbuild concatenates everything
// into one file, every `import.meta.url` would point at the bundle, breaking
// those source-relative lookups.
//
// The plugin below rewrites `import.meta.url` to a string literal of the
// ORIGINAL file URL during load, so each module continues to compute the same
// paths it would have computed unbundled. Bundled and unbundled outputs then
// behave identically.

import esbuild from "esbuild";
import { pathToFileURL } from "node:url";

/** @type {esbuild.Plugin} */
const preserveImportMetaUrl = {
name: "preserve-import-meta-url",
setup(build) {
build.onLoad({ filter: /\.js$/, namespace: "file" }, async (args) => {
const fs = await import("node:fs/promises");
const contents = await fs.readFile(args.path, "utf8");
if (!contents.includes("import.meta.url")) {
return null;
}
const url = JSON.stringify(pathToFileURL(args.path).href);
return {
contents: contents.replaceAll("import.meta.url", url),
loader: "js",
};
});
},
};

await esbuild.build({
entryPoints: ["dist/lib/cli.js"],
outfile: "dist/lib/cli.bundled.js",
bundle: true,
platform: "node",
format: "esm",
target: "node18",
packages: "external",
plugins: [preserveImportMetaUrl],
logLevel: "info",
});
7 changes: 7 additions & 0 deletions tsconfig.bundle.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.json",
"exclude": [
"src/lib/output/themes/default/assets",
"src/test"
]
}
Loading