@esmx/rspack
Version:
A high-performance Rspack integration for Esmx microfrontend framework, providing module federation and SSR capabilities.
135 lines (134 loc) • 4.11 kB
JavaScript
import { moduleLinkPlugin } from "@esmx/rspack-module-link-plugin";
import {
rspack
} from "@rspack/core";
import nodeExternals from "webpack-node-externals";
import { HMR_DIR, HMR_JSONP } from "./hmr-config.mjs";
export function createRspackConfig(esmx, buildTarget, options) {
const isHot = buildTarget === "client" && !esmx.isProd;
return {
/**
* Project root directory, cannot be modified
*/
context: esmx.root,
output: {
clean: esmx.isProd,
filename: buildTarget !== "node" && esmx.isProd ? "exports/[name].[contenthash:8].final.mjs" : "exports/[name].mjs",
cssFilename: esmx.isProd ? "exports/[name].[contenthash:8].final.css" : "exports/[name].css",
chunkFilename: esmx.isProd ? "chunks/[name].[contenthash:8].final.mjs" : "chunks/[name].mjs",
cssChunkFilename: esmx.isProd ? "chunks/[name].[contenthash:8].final.css" : "chunks/[name].css",
publicPath: buildTarget === "client" ? "auto" : `${esmx.basePathPlaceholder}${esmx.basePath}`,
uniqueName: esmx.varName,
hotUpdateGlobal: HMR_JSONP,
chunkLoadingGlobal: HMR_JSONP + "_chunk",
hotUpdateChunkFilename: `${HMR_DIR}/[id].[fullhash].hot-update.mjs`,
hotUpdateMainFilename: `${HMR_DIR}/[runtime].[fullhash].hot-update.json`,
path: (() => {
switch (buildTarget) {
case "client":
return esmx.resolvePath("dist/client");
case "server":
return esmx.resolvePath("dist/server");
case "node":
return esmx.resolvePath("dist/node");
}
})()
},
plugins: (() => {
return [
new rspack.ProgressPlugin({
prefix: buildTarget
}),
createModuleLinkPlugin(esmx, buildTarget),
isHot ? new rspack.HotModuleReplacementPlugin() : false
];
})(),
module: {
parser: {
javascript: {
// DEV hot update fix
dynamicImportMode: esmx.isProd ? "lazy" : "eager",
url: buildTarget === "client" ? true : "relative"
}
},
generator: {
asset: {
emit: buildTarget === "client"
},
"asset/resource": {
emit: buildTarget === "client"
}
},
rules: []
},
resolve: {
alias: {
[esmx.name]: esmx.root
}
},
optimization: {
minimize: options.minimize ?? esmx.isProd,
emitOnErrors: true,
// DEV hot update fix
splitChunks: esmx.isProd ? void 0 : false,
// DEV hot update fix
runtimeChunk: esmx.isProd ? void 0 : false
},
externalsPresets: {
web: buildTarget === "client",
node: buildTarget === "server" || buildTarget === "node"
},
externalsType: "module-import",
externals: (() => {
if (buildTarget === "node") {
return [
// @ts-ignore
nodeExternals({
// @ts-ignore
importType: "module-import"
})
];
}
return [];
})(),
target: buildTarget === "client" ? "web" : "node24",
mode: esmx.isProd ? "production" : "development",
cache: !esmx.isProd
};
}
function createModuleLinkPlugin(esmx, buildTarget) {
if (buildTarget === "node") {
return moduleLinkPlugin({
name: esmx.name,
exports: {
"src/entry.node": {
rewrite: false,
file: "./src/entry.node"
}
}
});
}
const exports = {};
for (const [name, item] of Object.entries(esmx.moduleConfig.exports)) {
if (item.inputTarget[buildTarget]) {
exports[name] = {
rewrite: item.rewrite,
file: item.inputTarget[buildTarget]
};
}
}
const preEntries = [];
if (buildTarget === "client" && !esmx.isProd) {
preEntries.push(
`${import.meta.resolve("webpack-hot-middleware/client.js")}?path=/${esmx.name}/hot-middleware`
);
}
return moduleLinkPlugin({
name: esmx.name,
injectChunkName: buildTarget === "server",
imports: esmx.moduleConfig.imports,
deps: Object.keys(esmx.moduleConfig.links),
exports,
preEntries
});
}