esbuild-wasm-deno/mod.ts

105 lines
3.4 KiB
TypeScript

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<typeof Mapper.importmapPlugin>[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<string, string>}). If this is left blank, a configuration will be scanned for in the "directory"
* @returns {Promise<ESBuild.BuildResult<ESBuild.BuildOptions>>} 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 };