@esmx/rspack
Version:
A high-performance Rspack integration for Esmx microfrontend framework, providing Module Linking and SSR capabilities.
106 lines (103 loc) • 2.83 kB
JavaScript
import { pathToFileURL } from "node:url";
import {
RenderContext,
createApp,
mergeMiddlewares
} from "@esmx/core";
import { createVmImport } from "@esmx/import";
import hotMiddleware from "webpack-hot-middleware";
import { createRspackConfig } from "./chain-config.mjs";
import { pack } from "./pack.mjs";
import { createRsBuild } from "./utils/index.mjs";
export async function createRspackApp(esmx, options) {
const app = await createApp(esmx, esmx.command);
switch (esmx.command) {
case esmx.COMMAND.dev:
app.middleware = mergeMiddlewares([
...await createMiddleware(esmx, options),
app.middleware
]);
app.render = rewriteRender(esmx);
break;
case esmx.COMMAND.build:
app.build = rewriteBuild(esmx, options);
break;
}
return app;
}
async function createMiddleware(esmx, options = {}) {
if (esmx.command !== esmx.COMMAND.dev) {
return [];
}
const rsBuild = createRsBuild([
generateBuildConfig(esmx, options, "client"),
generateBuildConfig(esmx, options, "server")
]);
rsBuild.watch();
const hot = hotMiddleware(rsBuild.compilers[0], {
path: `${esmx.basePath}hot-middleware`
});
return [
(req, res, next) => {
if (req.url?.startsWith(`${esmx.basePath}hot-middleware`)) {
return hot(req, res, next);
}
return next();
}
];
}
function generateBuildConfig(esmx, options, buildTarget) {
return createRspackConfig(esmx, buildTarget, options);
}
function rewriteRender(esmx) {
return async (options) => {
const baseURL = pathToFileURL(esmx.root);
const importMap = await esmx.getImportMap("server");
const vmImport = createVmImport(baseURL, importMap);
const rc = new RenderContext(esmx, options);
const module = await vmImport(
`${esmx.name}/src/entry.server`,
import.meta.url,
{
console,
setTimeout,
clearTimeout,
process,
URL,
global
}
);
const serverRender = module[rc.entryName];
if (typeof serverRender === "function") {
await serverRender(rc);
}
return rc;
};
}
function rewriteBuild(esmx, options = {}) {
return async () => {
const ok = await createRsBuild([
generateBuildConfig(esmx, options, "client"),
generateBuildConfig(esmx, options, "server"),
generateBuildConfig(esmx, options, "node")
]).build();
if (!ok) {
return false;
}
esmx.writeSync(
esmx.resolvePath("dist/index.mjs"),
`
async function start() {
const options = await import('./node/src/entry.node.mjs').then(
(mod) => mod.default
);
const { Esmx } = await import('@esmx/core');
const esmx = new Esmx(options);
await esmx.init(esmx.COMMAND.start);
}
start();
`.trim()
);
return pack(esmx);
};
}