This commit is contained in:
Seth Trowbridge 2025-02-28 10:03:33 -05:00
parent e160d41d58
commit 4441a6d8f2
6 changed files with 114 additions and 14 deletions

33
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,33 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Attach",
"port": 9229,
"request": "attach",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
},
{
"request": "launch",
"name": "Launch Program",
"type": "node",
"program": "${workspaceFolder}/main.ts",
"cwd": "${workspaceFolder}",
"env": {},
"runtimeExecutable": "C:\\Users\\strowbridge\\.deno\\bin\\deno.EXE",
"runtimeArgs": [
"run",
"--unstable",
"--inspect-wait",
"--allow-all"
],
"attachSimplePort": 9229
}
]
}

59
mod.ts
View File

@ -1,29 +1,59 @@
import * as ESBuild from "https://deno.land/x/esbuild@v0.19.2/wasm.js"; 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 * as Mapper from "https://esm.sh/esbuild-plugin-importmaps@1.0.0"; // https://github.com/andstellar/esbuild-plugin-importmaps
import Introspect from "./introspect.ts"; import Introspect from "./introspect.ts";
const REG = {
pathRel: RegExp("/^(\.\/|\.\.\/).*/"),
pathAbs: RegExp("^\/.*"),
pathHTTP: RegExp("/^https?:\/\//"),
wildcard: RegExp("/.*/")
};
const prefix = "/_dot_importer_/"; const prefix = "/_dot_importer_/";
const resolvePlugin =(fullPathDir:string):ESBuild.Plugin=>({ const resolvePlugin =(fullPathDir:string):ESBuild.Plugin=>({
name: "resolve-plugin", name: "resolve-plugin",
setup(build) { setup(build) {
build.onResolve({ filter: /^(\.\/|\.\.\/).*/ }, (args)=>
build.onResolve({ filter: REG.pathHTTP }, args => {
console.log(`LOCAL RESOLVE`, args);
return { path: args.path, namespace:"remote", pluginData:{origin:new URL(args.path).origin} };
});
build.onLoad({ filter: REG.wildcard, namespace:"remote" }, async(args)=> {
console.log(`REMOTE LOADING`, {args}, "\n");
const contents = await fetch(args.path).then(r=>r.text());
return { contents, loader: `tsx` };
});
build.onResolve({ filter: REG.pathRel }, (args)=>
{ {
let resolveRoot = args.importer||fullPathDir; let resolveRoot = args.importer||fullPathDir;
if(resolveRoot.startsWith(prefix)) if(resolveRoot.startsWith(prefix))
{ {
resolveRoot = resolveRoot.substring(prefix.length); resolveRoot = resolveRoot.substring(prefix.length);
} }
const url = new URL(args.path, resolveRoot).href;
const output:ESBuild.OnResolveResult = { const output:ESBuild.OnResolveResult = {
path:prefix + new URL(args.path, resolveRoot).href, path:prefix + url,
namespace:"http", namespace:"local",
} }
console.log(`LOCAL RESOLVE`, {args, resolveRoot, output}, "\n");
return output; return output;
}); });
build.onLoad({ filter: /.*/, namespace:"http" }, async(args)=> { build.onLoad({ filter: REG.wildcard, namespace:"local" }, async(args)=> {
const fetchPath = args.path.substring(prefix.length); const fetchPath = args.path.substring(prefix.length);
console.log("fetch path", fetchPath);
const result = await fetch(fetchPath); console.log(`LOCAL LOADING`, {args, fetchPath}, "\n");
const contents = await result.text();
const contents = await fetch(fetchPath).then(r=>r.text());
return { contents, loader: `tsx` }; return { contents, loader: `tsx` };
}); });
}, },
@ -32,14 +62,15 @@ const resolvePlugin =(fullPathDir:string):ESBuild.Plugin=>({
await ESBuild.initialize({ worker: false }); await ESBuild.initialize({ worker: false });
export type ImportMap = Parameters<typeof Mapper.importmapPlugin>[0]; export type ImportMap = Parameters<typeof Mapper.importmapPlugin>[0];
export type BuildOptions = ESBuild.BuildOptions; export type BuildOptions = ESBuild.BuildOptions;
/** /**
* *
* @param directory Full file:// or http(s):// path to the directory containing assets you want to build (needed to resolve relative imports) * @param {string} directory Full file:// or http(s):// path to the directory containing assets you want to build (needed to resolve relative imports)
* @param buildOptions ESBuild "build" options (will be merged with "reasonable defaults") for docs: https://esbuild.github.io/api/#general-options * @param {ESBuild.BuildOptions} buildOptions ESBuild "build" options (will be merged with "reasonable defaults") for docs: https://esbuild.github.io/api/#general-options
* @param 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" * @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 build result * @returns {Promise<ESBuild.BuildResult<ESBuild.BuildOptions>>} build result
*/ */
export default async function(directory:string, buildOptions={} as BuildOptions, importMap?:ImportMap):Promise<ESBuild.BuildResult<ESBuild.BuildOptions>> export default async function(directory, buildOptions={}, importMap)
{ {
if(!importMap) if(!importMap)
{ {
@ -56,7 +87,7 @@ export default async function(directory:string, buildOptions={} as BuildOptions,
...buildOptions, ...buildOptions,
plugins: [ plugins: [
resolvePlugin(directory), resolvePlugin(directory),
Mapper.importmapPlugin(importMap) as ESBuild.Plugin, //Mapper.importmapPlugin(importMap) as ESBuild.Plugin,
...buildOptions.plugins||[] ...buildOptions.plugins||[]
] ]
}; };

View File

@ -105,6 +105,9 @@ async function serve(settings:ServeArgs):Promise<void>
const url = new URL(req.url); const url = new URL(req.url);
const {path, type} = PathExtensionType(url.pathname); const {path, type} = PathExtensionType(url.pathname);
console.log(req.url);
const headers = {"content-type":type||"", ETag, "Cache-Control":"max-age=3600"} const headers = {"content-type":type||"", ETag, "Cache-Control":"max-age=3600"}
// serve javascript // serve javascript

9
what/entry.ts Normal file
View File

@ -0,0 +1,9 @@
import Message from "./include.ts";
type Person = {name:string, age:number};
const me:Person = {name:"seth", age:41};
console.log(Message);
export default me;

5
what/include.ts Normal file
View File

@ -0,0 +1,5 @@
import * as LO from "https://esm.sh/lodash@4.17.21";
console.log(LO);
export default "HELLO";

19
what/index.ts Normal file
View File

@ -0,0 +1,19 @@
import Bundle from "../mod.ts";
const {outputFiles} = await Bundle(
// directory to work from
import.meta.resolve('./'),
// ESBuild configuration (entry points are relative to "directory"):
{entryPoints:["./entry.ts"]},
// import map (if omitted, will scan for a deno configuration within "directory" and use that)
{"imports": {
"react": "https://esm.sh/preact@10.22.0/compat",
"react/": "https://esm.sh/preact@10.22.0/compat/"
}}
);
for(const item of outputFiles){
// do something with the output...
console.log(item.text);
}