generated at
deno bundleの代替コード
deno_bundleのmanglingまわりが壊れてしまったので、esbuildで簡単なbuilderを作った

実装
esbuildesbuild_deno_loaderの組み合わせ

$ deno run -A https://scrapbox.io/api/code/takker/deno_bundleの代替コード/build.ts

2024-02-14
12:34:15 依存関係表示プログラムは info.ts に移した
12:31:36 deno-cliffy ansi を使って、infoを再描画できるようにしてみようとしたのだが、うまく消えなかったので断念した
12:31:23 deno infoを表示できるようにした
build.ts
import { build, stop } from "https://deno.land/x/esbuild@v0.20.0/mod.js"; import { denoResolverPlugin, denoLoaderPlugin } from "https://deno.land/x/esbuild_deno_loader@0.9.0/mod.ts"; const result = await build({ plugins: [denoResolverPlugin(), denoLoaderPlugin()], entryPoints: [Deno.args[0]], bundle: true, write: false, format: "esm", minify: true, charset: "utf8", }); console.log(result.outputFiles[0].text); stop();
denoResolverPlugin() を通した後は、 OnResolveArgs .importer が消えてしまう
denoResolverPlugin() の前にいれると、依存関係が保存された処理前の OnLoadArgs と、処理後の OnLoadArgs の両方を取得できる

info.ts
import { build, stop, Plugin } from "https://deno.land/x/esbuild@v0.20.0/mod.js"; import { denoResolverPlugin, denoLoaderPlugin } from "https://deno.land/x/esbuild_deno_loader@0.9.0/mod.ts"; import { gray } from "https://deno.land/std@0.215.0/fmt/colors.ts"; import { toFileUrl } from "https://deno.land/std@0.213.0/path/mod.ts"; /** keyが親ファイルパス, valueがそのファイルでimportしたファイルのパスリスト */ const ancestors = new Map<string, string[]>; let entryPoint = ""; function* makeTree( parent: string, // parentからの相対URLで表示したいときtrue relative?: boolean, viewedPath?: Set<string>, ): Generator<string> { const childs = ancestors.get(parent); if (!childs) return; viewedPath ??= new Set<string>(); viewedPath.add(parent); for (let i = 0; i < childs.length; i++) { const child = childs[i]; const relativePath = decodeURIComponent( relative ? makeRelative(new URL(parent), new URL(child)) : child, ); const lastOne = i + 1 === childs.length; const branch = lastOne ? "└─ " : "├─ "; // 一度読み込んだものは灰色で表示する if (viewedPath.has(child)) { yield `${branch}${gray(relativePath)}`; continue; } yield `${branch}${relativePath}`; viewedPath.add(child); const indent = lastOne ? " " : "│ "; for (const line of makeTree(child, relative ?? false, viewedPath)) { yield `${indent}${line}`; } } } const listPlugin: Plugin = { name: "list-imports", setup: ({ onResolve, resolve }) => { onResolve({ filter: /.*/, }, (args) => { /** * The following codes come from https://github.com/lucacasonato/esbuild_deno_loader/blob/0.9.0/src/plugin_deno_resolver.ts * Copyright (c) 2021 Luca Casonato. All rights reserved. MIT license. */ // // The first pass resolver performs synchronous resolution. This // includes relative to absolute specifier resolution and import map // resolution. // We have to first determine the referrer URL to use when resolving // the specifier. This is either the importer URL, or the resolveDir // URL if the importer is not specified (ie if the specifier is at the // root). let referrer: URL; if (args.importer !== "") { if (args.namespace === "") { throw new Error("[assert] namespace is empty"); } referrer = new URL(`${args.namespace}:${args.importer}`); } else if (args.resolveDir !== "") { referrer = new URL(`${toFileUrl(args.resolveDir).href}/`); } else { return undefined; } // We can then resolve the specifier relative to the referrer URL. If // an import map is specified, we use that to resolve the specifier. const resolved = new URL(args.path, referrer); if (args.kind === "entry-point") { entryPoint = resolved.href; } else { ancestors.set( referrer.href, [...(ancestors.get(referrer.href) ?? []), resolved.href] ); } return undefined; }); }, }; await build({ plugins: [listPlugin, denoResolverPlugin(), denoLoaderPlugin()], entryPoints: [Deno.args[0]], bundle: true, write: false, format: "esm", minify: true, charset: "utf8", }); stop(); console.log(entryPoint); for (const line of makeTree(entryPoint)) { console.log(line); }

scrapbox json dataにするやつ
長すぎるコードを読み込むときに使う
$ deno run -r=https://scrapbox.io -A https://scrapbox.io/api/code/takker/deno_bundleの代替コード/json.ts
json.ts
import { build, stop } from "https://deno.land/x/esbuild@v0.20.0/mod.js"; import { denoResolverPlugin, denoLoaderPlugin } from "https://deno.land/x/esbuild_deno_loader@0.9.0/mod.ts"; const result = await esbuild.build({ plugins: [denoResolverPlugin(), denoLoaderPlugin()], entryPoints: [Deno.args[0]], bundle: true, write: false, format: "esm", minify: true, charset: "utf8", }); const pages = [{ title: Deno.args[1], lines: [ Deno.args[1], "", "code:mod.js", ...result.outputFiles[0].text.split("\n").map((line) => ` ${line}`), ], }]; console.log(JSON.stringify({pages})); stop();

#2023-12-17 09:39:39