import * as ESBuild from "https://deno.land/x/esbuild@v0.25.0/wasm.js"; import * as Mapper from "https://esm.sh/esbuild-plugin-importmaps@1.0.0"; // https://github.com/andstellar/esbuild-plugin-importmaps import Introspect from "./introspect.ts"; const prefix = "/_dot_importer_/"; const resolvePlugin =(fullPathDir:string):ESBuild.Plugin=>({ name: "resolve-plugin", setup(build) { build.onResolve({ /*path relative*/ filter: /^(\.\/|\.\.\/).*/ }, (args)=> { let resolveRoot = args.importer||fullPathDir; if(resolveRoot.startsWith(prefix)) { resolveRoot = resolveRoot.substring(prefix.length); } const url = new URL(args.path, resolveRoot).href; const output:ESBuild.OnResolveResult = { path:prefix + url, namespace:"local", } console.log(`LOCAL RESOLVE`, {args, resolveRoot, output}, "\n"); return output; }); build.onLoad({ /*wildcard*/ filter: /.*/, namespace:"local" }, async(args)=> { const fetchPath = args.path.substring(prefix.length); console.log(`LOCAL LOADING`, {args, fetchPath}, "\n"); const contents = await fetch(fetchPath).then(r=>r.text()); return { contents, loader: `tsx` }; }); build.onResolve({/* path abs */ filter:/^\/.*/}, args=>{ console.log(`ABS RESOLVE`, {args}, "\n"); return { path:args.path, namespace:"ABS", } }); build.onLoad({/*wildcard*/ filter: /.*/, namespace:"ABS"}, async(args)=>{ console.log(`ABS LOADING`, {args}, "\n"); return { contents:"export default 'IDK';", loader: `tsx` }; }); build.onResolve({ /* path HTTP */ filter: /^https?:\/\// }, args => { console.log(`REMOTE RESOLVE`, args); return { path: args.path, namespace:"REMOTE", pluginData:{origin:new URL(args.path).origin} }; }); build.onLoad({ /*wildcard*/ filter: /.*/, namespace:"REMOTE" }, async(args)=> { console.log(`REMOTE LOADING`, {args}, "\n"); const contents = await fetch(args.path).then(r=>r.text()); return { contents, loader: `tsx` }; }); }, }); await ESBuild.initialize({ worker: false }); export type ImportMap = Parameters[0]; export type BuildOptions = ESBuild.BuildOptions; /** * * @param {string} directory Full file:// or http(s):// path to the directory containing assets you want to build (needed to resolve relative imports) * @param {ESBuild.BuildOptions} buildOptions ESBuild "build" options (will be merged with "reasonable defaults") for docs: https://esbuild.github.io/api/#general-options * @param {ImportMap|null} importMap An object to act as the import map ({imports:Record}). If this is left blank, a configuration will be scanned for in the "directory" * @returns {Promise>} build result */ export default async function(directory, buildOptions={}, importMap) { if(!importMap) { importMap = await Introspect(directory) as ImportMap } console.log("using import map", importMap); const configuration:ESBuild.BuildOptions = { entryPoints: ["entry"], bundle: true, minify: true, format: "esm", jsx: "automatic", jsxImportSource: "react", ...buildOptions, plugins: [ resolvePlugin(directory), //Mapper.importmapPlugin(importMap) as ESBuild.Plugin, ...buildOptions.plugins||[] ] }; const result = await ESBuild.build(configuration); return result; } export { ESBuild };