Skip to content
This repository was archived by the owner on Jul 6, 2025. It is now read-only.

Commit aef3f14

Browse files
committed
Inject __ALEPH_MODULE_LOADERS in build command
1 parent ab6648c commit aef3f14

File tree

6 files changed

+57
-23
lines changed

6 files changed

+57
-23
lines changed

server/build.ts

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { builtinModuleExts, toLocalPath } from "../lib/helpers.ts";
88
import { parseHtmlLinks } from "./html.ts";
99
import log from "../lib/log.ts";
1010
import util from "../lib/util.ts";
11-
import { getAlephPkgUri, loadImportMap, loadJSXConfig } from "../server/config.ts";
11+
import { getAlephPkgUri, initModuleLoaders, loadImportMap, loadJSXConfig } from "../server/config.ts";
1212
import { DependencyGraph } from "../server/graph.ts";
1313
import { initRoutes } from "../server/routing.ts";
1414
import type { AlephConfig, BuildPlatform, FetchHandler } from "../server/types.ts";
@@ -24,6 +24,7 @@ export async function build(serverEntry?: string) {
2424
const alephPkgUri = getAlephPkgUri();
2525
const importMap = await loadImportMap();
2626
const jsxCofig = await loadJSXConfig(importMap);
27+
const moduleLoaders = await initModuleLoaders(importMap);
2728
const config: AlephConfig | undefined = Reflect.get(globalThis, "__ALEPH_CONFIG");
2829
const platform = config?.build?.platform ?? "deno";
2930
const outputDir = join(workingDir, config?.build?.outputDir ?? "dist");
@@ -56,6 +57,20 @@ export async function build(serverEntry?: string) {
5657
`import graph from "./server_dependency_graph.js";`,
5758
`globalThis.serverDependencyGraph = new DependencyGraph(graph.modules);`,
5859
routeFiles.length > 0 && `import { revive } from "${alephPkgUri}/server/routing.ts";`,
60+
moduleLoaders.length > 0 &&
61+
`import { globToRegExp } from "https://deno.land/[email protected]/path/mod.ts";const moduleLoaders = []; globalThis["__ALEPH_MODULE_LOADERS"] = moduleLoaders;`,
62+
moduleLoaders.length > 0 &&
63+
moduleLoaders.map(({ meta }, idx) => `
64+
import loader_${idx} from ${JSON.stringify(meta.src)};
65+
const reg = globToRegExp(${JSON.stringify(meta.glob)});
66+
moduleLoaders.push({
67+
meta: ${JSON.stringify(meta)},
68+
test: (pathname) => {
69+
return reg.test(pathname) && loader_${idx}.test(pathname);
70+
},
71+
load: (pathname, env) => loader_${idx}.load(pathname, env),
72+
})
73+
`).join("\n"),
5974
...routeFiles.map(([filename, exportNames], idx) => {
6075
const hasDefaultExport = exportNames.includes("default");
6176
const hasDataExport = exportNames.includes("data");
@@ -77,11 +92,11 @@ export async function build(serverEntry?: string) {
7792
].filter(Boolean).join(", ")
7893
} });`,
7994
];
80-
}).flat().filter(Boolean),
95+
}),
8196
serverEntry && `import "http://localhost:${port}/${basename(serverEntry)}";`,
8297
!serverEntry && `import { serve } from "${alephPkgUri}/server/mode.ts";`,
8398
!serverEntry && `serve();`,
84-
].filter(Boolean).join("\n");
99+
].flat().filter(Boolean).join("\n");
85100

86101
// since esbuild doesn't support jsx automic transform, we need to manually import jsx runtime
87102
let jsxShimFile: string | null = null;
@@ -130,13 +145,8 @@ export async function build(serverEntry?: string) {
130145
name: "aleph-esbuild-plugin",
131146
setup(build) {
132147
build.onResolve({ filter: /.*/ }, (args) => {
133-
let importUrl = args.path;
134-
if (importUrl in importMap.imports) {
135-
importUrl = importMap.imports[importUrl];
136-
}
137-
138-
const isRemote = util.isLikelyHttpURL(importUrl);
139-
const [path] = util.splitBy(isRemote ? importUrl : util.trimPrefix(importUrl, "file://"), "#");
148+
const isRemote = util.isLikelyHttpURL(args.path);
149+
const [path] = util.splitBy(isRemote ? args.path : util.trimPrefix(args.path, "file://"), "#");
140150

141151
if (args.kind === "dynamic-import") {
142152
return { path, external: true };
@@ -158,6 +168,12 @@ export async function build(serverEntry?: string) {
158168
return { path, external: true };
159169
}
160170

171+
if (path.startsWith("./") || path.startsWith("../")) {
172+
return {
173+
path: join(dirname(args.importer), path),
174+
};
175+
}
176+
161177
return { path };
162178
});
163179
build.onLoad({ filter: /.*/, namespace: "http" }, async (args) => {

server/config.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,10 @@ export async function loadImportMap(): Promise<ImportMap> {
159159
}
160160

161161
export async function initModuleLoaders(importMap: ImportMap): Promise<ModuleLoader[]> {
162-
const loaders: ModuleLoader[] = [];
162+
const loaders: ModuleLoader[] = Reflect.get(globalThis, "__ALEPH_MODULE_LOADERS") || [];
163+
if (loaders.length > 0) {
164+
return loaders;
165+
}
163166
if (Deno.env.get("ALEPH_CLI")) {
164167
for (const key in importMap.imports) {
165168
if (/^\*\.[a-z0-9]+$/i.test(key)) {
@@ -177,8 +180,10 @@ export async function initModuleLoaders(importMap: ImportMap): Promise<ModuleLoa
177180
typeof loader === "object" && loader !== null &&
178181
typeof loader.test === "function" && typeof loader.load === "function"
179182
) {
180-
const reg = globToRegExp("/**/" + key);
183+
const glob = "/**/" + key;
184+
const reg = globToRegExp(glob);
181185
loaders.push({
186+
meta: { src, glob },
182187
test: (pathname: string) => {
183188
return reg.test(pathname) && loader.test(pathname);
184189
},
@@ -189,6 +194,7 @@ export async function initModuleLoaders(importMap: ImportMap): Promise<ModuleLoa
189194
}
190195
}
191196
}
197+
Reflect.set(globalThis, "__ALEPH_MODULE_LOADERS", loaders);
192198
return loaders;
193199
}
194200

server/mod.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { serve as stdServe, type ServeInit, serveTls } from "https://deno.land/[email protected]/http/server.ts";
22
import { readableStreamFromReader } from "https://deno.land/[email protected]/streams/conversion.ts";
3-
import { builtinModuleExts } from "../lib/helpers.ts";
43
import log, { LevelName } from "../lib/log.ts";
54
import { getContentType } from "../lib/mime.ts";
65
import type { Routes } from "../lib/route.ts";
@@ -50,38 +49,39 @@ export const serve = (options: ServerOptions = {}) => {
5049
}
5150

5251
// transform client modules
53-
if (
54-
pathname.startsWith("/-/") ||
55-
(builtinModuleExts.find((ext) => pathname.endsWith(`.${ext}`)) && !pathname.endsWith(".d.ts")) ||
56-
pathname.endsWith(".css")
57-
) {
52+
if (clientModuleTransformer.test(pathname)) {
5853
const [buildHash, jsxConfig, importMap] = await Promise.all([
5954
buildHashPromise,
6055
jsxConfigPromise,
6156
importMapPromise,
6257
]);
6358
return clientModuleTransformer.fetch(req, {
64-
isDev,
6559
importMap,
6660
jsxConfig,
6761
buildHash,
6862
buildTarget: config?.build?.target,
63+
isDev,
6964
});
7065
}
7166

7267
// use loader to load modules
7368
const moduleLoaders = await moduleLoadersPromise;
7469
const loader = moduleLoaders.find((loader) => loader.test(pathname));
7570
if (loader) {
76-
const [buildHash, importMap] = await Promise.all([buildHashPromise, importMapPromise]);
71+
const [buildHash, jsxConfig, importMap] = await Promise.all([
72+
buildHashPromise,
73+
jsxConfigPromise,
74+
importMapPromise,
75+
]);
7776
try {
7877
const loaded = await loader.load(pathname, { isDev, importMap });
7978
return clientModuleTransformer.fetch(req, {
80-
isDev,
81-
importMap,
8279
loaded,
80+
importMap,
81+
jsxConfig,
8382
buildHash,
8483
buildTarget: config?.build?.target,
84+
isDev,
8585
});
8686
} catch (err) {
8787
if (!(err instanceof Deno.errors.NotFound)) {

server/serve_dist.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
import { readableStreamFromReader } from "https://deno.land/[email protected]/streams/conversion.ts";
22
import log from "../lib/log.ts";
3+
import { builtinModuleExts } from "../lib/helpers.ts";
34
import type { AlephConfig } from "./types.ts";
45

56
export default {
7+
test: (pathname: string) => {
8+
return pathname.startsWith("/-/") ||
9+
(builtinModuleExts.find((ext) => pathname.endsWith(`.${ext}`)) && !pathname.endsWith(".d.ts")) ||
10+
pathname.endsWith(".css");
11+
},
612
fetch: async (req: Request): Promise<Response> => {
713
const config: AlephConfig | undefined = Reflect.get(globalThis, "__ALEPH_CONFIG");
814
const outputDir = config?.build?.outputDir ?? "dist";

server/transformer.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import MagicString from "https://esm.sh/[email protected]";
22
import { parseDeps, transform } from "../compiler/mod.ts";
33
import type { TransformOptions, TransformResult } from "../compiler/types.ts";
44
import { readCode } from "../lib/fs.ts";
5-
import { restoreUrl, toLocalPath } from "../lib/helpers.ts";
5+
import { builtinModuleExts, restoreUrl, toLocalPath } from "../lib/helpers.ts";
66
import log from "../lib/log.ts";
77
import util from "../lib/util.ts";
88
import { bundleCSS } from "./bundle_css.ts";
@@ -21,6 +21,11 @@ export type TransformerOptions = {
2121
};
2222

2323
export default {
24+
test: (pathname: string) => {
25+
return pathname.startsWith("/-/") ||
26+
(builtinModuleExts.find((ext) => pathname.endsWith(`.${ext}`)) && !pathname.endsWith(".d.ts")) ||
27+
pathname.endsWith(".css");
28+
},
2429
fetch: async (req: Request, options: TransformerOptions): Promise<Response> => {
2530
const { isDev, buildHash, loaded } = options;
2631
const { pathname, searchParams, search } = new URL(req.url);

server/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export type ImportMap = {
4848
};
4949

5050
export type ModuleLoader = {
51+
readonly meta: { src: string; glob: string };
5152
test(pathname: string): boolean;
5253
load(pathname: string, env: ModuleLoaderEnv): Promise<ModuleLoaderContent> | ModuleLoaderContent;
5354
};

0 commit comments

Comments
 (0)