UNPKG

@esmx/rspack

Version:

A high-performance Rspack integration for Esmx microfrontend framework, providing module federation and SSR capabilities.

120 lines (117 loc) 3.26 kB
import fs from "node:fs"; import path from "node:path"; import { fileURLToPath, 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"; const extension = path.extname(fileURLToPath(import.meta.url)); const hotFixCode = fs.readFileSync( fileURLToPath(new URL(`./hot-fix${extension}`, import.meta.url)), "utf-8" ); 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); rc.html = rc.html.replace( "</head>", ` <script type="module">${hotFixCode}<\/script> </head> ` ); } 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/exports/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); }; }