UNPKG

@esmx/rspack

Version:

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

166 lines (141 loc) 4.47 kB
import type { Esmx } from '@esmx/core'; import type { RspackOptions } from '@rspack/core'; import { rspack } from '@rspack/core'; import RspackChain from 'rspack-chain'; import nodeExternals from 'webpack-node-externals'; import type { ModuleLinkPluginOptions } from '../module-link'; import { initModuleLink } from '../module-link'; import type { RspackAppOptions } from './app'; import type { BuildTarget } from './build-target'; export function createChainConfig( esmx: Esmx, buildTarget: BuildTarget, options: RspackAppOptions ): RspackChain { const isHot = buildTarget === 'client' && !esmx.isProd; const isClient = buildTarget === 'client'; const isServer = buildTarget === 'server'; const isNode = buildTarget === 'node'; const chain = new RspackChain(); chain.context(esmx.root); chain.mode(esmx.isProd ? 'production' : 'development'); chain.target(isClient ? 'web' : 'node24'); chain.cache(!esmx.isProd); chain.output .clean(esmx.isProd) .filename( !isNode && esmx.isProd ? '[name].[contenthash:8].final.mjs' : '[name].mjs' ) .chunkFilename( esmx.isProd ? 'chunks/[name].[contenthash:8].final.mjs' : 'chunks/[name].mjs' ) .publicPath( isClient ? 'auto' : `${esmx.basePathPlaceholder}${esmx.basePath}` ); chain.output.set( 'cssFilename', esmx.isProd ? '[name].[contenthash:8].final.css' : '[name].css' ); chain.output.set( 'cssChunkFilename', esmx.isProd ? 'chunks/[name].[contenthash:8].final.css' : 'chunks/[name].css' ); chain.output.path(esmx.resolvePath('dist', buildTarget)); chain.plugin('progress').use(rspack.ProgressPlugin, [ { prefix: buildTarget } ]); if (isHot) { chain.plugin('hmr').use(rspack.HotModuleReplacementPlugin); } chain.module.parser.set('javascript', { url: isClient ? true : 'relative', importMeta: false, strictExportPresence: true }); chain.module.generator.set('asset', { emit: isClient }); chain.module.generator.set('asset/resource', { emit: isClient }); chain.resolve.alias.set(esmx.name, esmx.root); chain.optimization .minimize(options.minimize ?? esmx.isProd) .emitOnErrors(true); chain.externalsPresets({ web: isClient, node: isServer || isNode }); chain.externalsType('module-import'); if (isNode) { chain.externals([ // @ts-expect-error nodeExternals({ // @ts-expect-error importType: 'module-import' }) ]); } chain.experiments({ ...(chain.get('experiments') || {}), outputModule: true, nativeWatcher: true, rspackFuture: { bundlerInfo: { force: false } } }); chain.set('lazyCompilation', false); initModuleLink(chain, createModuleLinkConfig(esmx, buildTarget)); return chain; } function createModuleLinkConfig( esmx: Esmx, buildTarget: BuildTarget ): ModuleLinkPluginOptions { const isClient = buildTarget === 'client'; const isServer = buildTarget === 'server'; const isNode = buildTarget === 'node'; if (isNode) { return { name: esmx.name, exports: { 'src/entry.node': { pkg: false, file: './src/entry.node' } } }; } const preEntries: string[] = []; if (isClient && !esmx.isProd) { preEntries.push( `${import.meta.resolve('webpack-hot-middleware/client.js')}?path=/${esmx.name}/hot-middleware` ); } return { ...esmx.moduleConfig.environments[buildTarget], name: esmx.name, injectChunkName: isServer, deps: Object.keys(esmx.moduleConfig.links), preEntries }; } export function createRspackConfig( esmx: Esmx, buildTarget: BuildTarget, options: RspackAppOptions ): RspackOptions { const chain = createChainConfig(esmx, buildTarget, options); options.chain?.({ esmx, options, buildTarget, chain }); const config = chain.toConfig(); options.config?.({ esmx, options, buildTarget, config }); return config; }