UNPKG

@gez/rspack

Version:

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

131 lines (128 loc) 3.59 kB
import fs from "node:fs"; import { pathToFileURL } from "node:url"; import { styleText } from "node:util"; import { PathType, RenderContext, createApp, mergeMiddlewares } from "@gez/core"; import { createVmImport } from "@gez/import"; import hotMiddleware from "webpack-hot-middleware"; import { createRspackConfig } from "./config.mjs"; import { pack } from "./pack.mjs"; import { createRsBuild } from "./utils/index.mjs"; export async function createRspackApp(gez, options) { const app = await createApp(gez, gez.command); switch (gez.command) { case gez.COMMAND.dev: app.middleware = mergeMiddlewares([ ...await createMiddleware(gez, options), app.middleware ]); app.render = rewriteRender(gez); break; case gez.COMMAND.build: app.build = rewriteBuild(gez, options); break; } return app; } async function createMiddleware(gez, options = {}) { if (gez.command !== gez.COMMAND.dev) { return []; } const rsBuild = createRsBuild([ generateBuildConfig(gez, options, "client"), generateBuildConfig(gez, options, "server") ]); rsBuild.watch(); const hot = hotMiddleware(rsBuild.compilers[0], { path: `${gez.basePath}hot-middleware` }); return [ (req, res, next) => { if (req.url?.startsWith(`${gez.basePath}hot-middleware`)) { return hot(req, res, next); } return next(); } ]; } function generateBuildConfig(gez, options, buildTarget) { const config = createRspackConfig(gez, buildTarget, options); options.config?.({ gez, options, buildTarget, config }); return config; } function rewriteRender(gez) { return async (options) => { const baseURL = pathToFileURL(gez.root); const importMap = await gez.getImportMap("server"); const vmImport = createVmImport(baseURL, importMap); const rc = new RenderContext(gez, options); const module = await vmImport( `${gez.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(gez, options = {}) { return async () => { for (const item of gez.moduleConfig.exports) { if (item.type === PathType.root) { const text = fs.readFileSync( gez.resolvePath("./", item.exportPath), "utf-8" ); if (/\bexport\s+\*\s+from\b/.test(text)) { console.log( styleText( "red", `The export * syntax is used in the file '${item.exportPath}', which will cause the packaging to fail.` ) ); console.log( styleText( "red", `Please use specific export syntax, such as export { a, b } from './a';` ) ); return false; } } } await createRsBuild([ generateBuildConfig(gez, options, "client"), generateBuildConfig(gez, options, "server"), generateBuildConfig(gez, options, "node") ]).build(); gez.writeSync( gez.resolvePath("dist/index.js"), ` async function start() { const options = await import('./node/src/entry.node.js').then( (mod) => mod.default ); const { Gez } = await import('@gez/core'); const gez = new Gez(options); await gez.init(gez.COMMAND.start); } start(); `.trim() ); return pack(gez); }; }