diff --git a/packages/modernjs/package.json b/packages/modernjs/package.json index b9ba96b28df..65c6fc9b7de 100644 --- a/packages/modernjs/package.json +++ b/packages/modernjs/package.json @@ -25,6 +25,16 @@ "./ssr-runtime": { "types": "./dist/types/ssr-runtime/index.d.ts", "default": "./dist/esm/ssr-runtime/index.js" + }, + "./config-plugin": { + "import": "./dist/esm/cli/configPlugin.js", + "require": "./dist/cjs/cli/configPlugin.js", + "types": "./dist/types/cli/configPlugin.d.ts" + }, + "./ssr-plugin": { + "import": "./dist/esm/cli/ssrPlugin.js", + "require": "./dist/cjs/cli/ssrPlugin.js", + "types": "./dist/types/cli/ssrPlugin.d.ts" } }, "typesVersions": { @@ -35,8 +45,11 @@ "runtime": [ "./dist/types/runtime/index.d.ts" ], - "ssr-runtime": [ - "./dist/types/ssr-runtime/index.d.ts" + "config-plugin": [ + "./dist/types/cli/configPlugin.d.ts" + ], + "ssr-plugin": [ + "./dist/types/cli/ssrPlugin.d.ts" ] } }, diff --git a/packages/modernjs/src/cli/configPlugin.ts b/packages/modernjs/src/cli/configPlugin.ts new file mode 100644 index 00000000000..85b54b85aaf --- /dev/null +++ b/packages/modernjs/src/cli/configPlugin.ts @@ -0,0 +1,179 @@ +import path from 'path'; +import type { + CliPlugin, + AppTools, + UserConfig, + Bundler, +} from '@modern-js/app-tools'; +import { + StreamingTargetPlugin, + EntryChunkTrackerPlugin, +} from '@module-federation/node'; +import type { BundlerConfig } from '../interfaces/bundler'; +import type { InternalModernPluginOptions } from '../types'; +import { + patchBundlerConfig, + getIPV4, + getMFConfig, + patchMFConfig, +} from './utils'; +import { moduleFederationPlugin } from '@module-federation/sdk'; +import { isDev } from './constant'; + +export function setEnv(enableSSR: boolean) { + if (enableSSR) { + process.env['MF_DISABLE_EMIT_STATS'] = 'true'; + process.env['MF_SSR_PRJ'] = 'true'; + } +} + +export function modifyBundlerConfig(options: { + bundlerType: Bundler; + mfConfig: moduleFederationPlugin.ModuleFederationPluginOptions; + config: BundlerConfig; + isServer: boolean; + modernjsConfig: UserConfig; +}) { + const { mfConfig, config, isServer, modernjsConfig, bundlerType } = options; + + patchMFConfig(mfConfig, isServer); + + // let browserPlugin: BundlerPlugin | undefined = undefined; + // let nodePlugin: BundlerPlugin | undefined= undefined; + // let distOutputDir = ''; + // const envConfig = getTargetEnvConfig(mfConfig, isServer); + // if (isServer) { + // // nodePlugin = new MFBundlerPlugin(envConfig); + // // config.plugins?.push(nodePlugin); + // config.plugins?.push(new StreamingTargetPlugin(mfConfig)); + // if (isDev) { + // config.plugins?.push(new EntryChunkTrackerPlugin()); + // } + // } else { + // // distOutputDir = + // // config.output?.path || path.resolve(process.cwd(), 'dist'); + // // browserPlugin = new MFBundlerPlugin(envConfig); + // // config.plugins?.push(browserPlugin); + // } + + patchBundlerConfig({ + bundlerConfig: config, + isServer, + modernjsConfig, + mfConfig, + }); + + if (bundlerType === 'webpack') { + config.ignoreWarnings = config.ignoreWarnings || []; + config.ignoreWarnings.push((warning) => { + if (warning.message.includes('external script')) { + return true; + } + return false; + }); + } + + // return { + // distOutputDir + // } +} + +export const moduleFederationConfigPlugin = ( + userConfig: InternalModernPluginOptions, +): CliPlugin => ({ + name: '@modern-js/plugin-module-federation-config', + post: ['@modern-js/plugin-module-federation'], + setup: async ({ useConfigContext, useAppContext }) => { + console.log('config plugin'); + + const modernjsConfig = useConfigContext(); + const mfConfig = await getMFConfig(userConfig.originPluginOptions); + const csrConfig = JSON.parse(JSON.stringify(mfConfig)); + const ssrConfig = JSON.parse(JSON.stringify(mfConfig)); + userConfig.ssrConfig = ssrConfig; + userConfig.csrConfig = csrConfig; + + return { + config: async () => { + const bundlerType = + useAppContext().bundlerType === 'rspack' ? 'rspack' : 'webpack'; + + // const WebpackPluginConstructor = + // userConfig.webpackPluginImplementation || + // WebpackModuleFederationPlugin; + // const RspackPluginConstructor = + // userConfig.rspackPluginImplementation || RspackModuleFederationPlugin; + + // const MFBundlerPlugin = + // bundlerType === 'rspack' + // ? RspackPluginConstructor + // : WebpackPluginConstructor; + const ipv4 = getIPV4(); + + return { + tools: { + rspack(config, { isServer }) { + modifyBundlerConfig({ + bundlerType, + mfConfig: isServer ? ssrConfig : csrConfig, + config, + isServer, + // MFBundlerPlugin, + modernjsConfig, + }); + userConfig.distOutputDir = + config.output?.path || path.resolve(process.cwd(), 'dist'); + // if(res.browserPlugin){ + // userConfig.browserPlugin = res.browserPlugin; + // } + // if(res.nodePlugin){ + // userConfig.nodePlugin = res.nodePlugin; + // } + // if(res.distOutputDir){ + // userConfig.distOutputDir = res.distOutputDir + // } + }, + webpack(config, { isServer }) { + modifyBundlerConfig({ + bundlerType, + mfConfig: isServer ? ssrConfig : csrConfig, + config, + isServer, + modernjsConfig, + }); + + userConfig.distOutputDir = + config.output?.path || path.resolve(process.cwd(), 'dist'); + }, + devServer: { + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': + 'GET, POST, PUT, DELETE, PATCH, OPTIONS', + 'Access-Control-Allow-Headers': + 'X-Requested-With, content-type, Authorization', + }, + }, + }, + source: { + alias: { + '@modern-js/runtime/mf': require.resolve( + '@module-federation/modern-js/runtime', + ), + }, + define: { + FEDERATION_IPV4: JSON.stringify(ipv4), + }, + }, + dev: { + assetPrefix: modernjsConfig?.dev?.assetPrefix + ? modernjsConfig.dev.assetPrefix + : true, + }, + }; + }, + }; + }, +}); + +export default moduleFederationConfigPlugin; diff --git a/packages/modernjs/src/cli/constant.ts b/packages/modernjs/src/cli/constant.ts new file mode 100644 index 00000000000..0bd4ecf30c4 --- /dev/null +++ b/packages/modernjs/src/cli/constant.ts @@ -0,0 +1 @@ +export const isDev = process.env.NODE_ENV === 'development'; diff --git a/packages/modernjs/src/cli/index.ts b/packages/modernjs/src/cli/index.ts index ebe71a55f83..fbc57979131 100644 --- a/packages/modernjs/src/cli/index.ts +++ b/packages/modernjs/src/cli/index.ts @@ -1,254 +1,87 @@ -import path from 'path'; -import { fs } from '@modern-js/utils'; -import type { - CliPlugin, - AppTools, - AppToolsUserConfig, - Bundler, -} from '@modern-js/app-tools'; +import type { CliPlugin, AppTools } from '@modern-js/app-tools'; import { ModuleFederationPlugin as WebpackModuleFederationPlugin, AsyncBoundaryPlugin, } from '@module-federation/enhanced'; import { ModuleFederationPlugin as RspackModuleFederationPlugin } from '@module-federation/enhanced/rspack'; -import { - StreamingTargetPlugin, - EntryChunkTrackerPlugin, -} from '@module-federation/node'; -import type { BundlerConfig } from '../interfaces/bundler'; -import type { PluginOptions, BundlerPlugin } from '../types'; -import { - ConfigType, - getMFConfig, - getTargetEnvConfig, - patchWebpackConfig, - getIPV4, -} from './utils'; -import { updateStatsAndManifest } from './manifest'; -import { MODERN_JS_SERVER_DIR, PLUGIN_IDENTIFIER } from '../constant'; - -const SSR_PLUGIN_IDENTIFIER = 'mfPluginSSR'; -const isDev = process.env.NODE_ENV === 'development'; +import type { moduleFederationPlugin as MFPluginOptions } from '@module-federation/sdk'; +import type { PluginOptions, InternalModernPluginOptions } from '../types'; +import { moduleFederationConfigPlugin } from './configPlugin'; +import { moduleFederationSSRPlugin } from './ssrPlugin'; export const moduleFederationPlugin = ( userConfig: PluginOptions = {}, -): CliPlugin => ({ - name: '@modern-js/plugin-module-federation', - setup: async ({ useConfigContext, useAppContext }) => { - const modernjsConfig = useConfigContext(); - const enableSSR = Boolean(modernjsConfig?.server?.ssr); - const mfConfig = await getMFConfig(userConfig); - let outputDir = ''; - - let browserPlugin: BundlerPlugin; - let nodePlugin: BundlerPlugin; - return { - config: async () => { - const bundlerType = - useAppContext().bundlerType === 'rspack' ? 'rspack' : 'webpack'; - - const WebpackPluginConstructor = - userConfig.webpackPluginImplementation || - WebpackModuleFederationPlugin; - const RspackPluginConstructor = - userConfig.rspackPluginImplementation || RspackModuleFederationPlugin; - - const MFBundlerPlugin = - bundlerType === 'rspack' - ? RspackPluginConstructor - : WebpackPluginConstructor; - - if (enableSSR) { - process.env['MF_DISABLE_EMIT_STATS'] = 'true'; - process.env['MF_SSR_PRJ'] = 'true'; - } - - const modifyBundlerConfig = ( - config: BundlerConfig, - isServer: boolean, - ) => { - const envConfig = getTargetEnvConfig(mfConfig, isServer); - if (isServer) { - nodePlugin = new MFBundlerPlugin(envConfig); - config.plugins?.push(nodePlugin); - config.plugins?.push(new StreamingTargetPlugin(envConfig)); - if (isDev) { - config.plugins?.push(new EntryChunkTrackerPlugin()); - } - } else { - outputDir = - config.output?.path || path.resolve(process.cwd(), 'dist'); - browserPlugin = new MFBundlerPlugin(envConfig); - config.plugins?.push(browserPlugin); - } - - patchWebpackConfig({ - bundlerConfig: config, - isServer, - modernjsConfig, - mfConfig: envConfig, - }); - }; - - const ipv4 = getIPV4(); - - return { - tools: { - rspack(config) { - if (enableSSR) { - throw new Error( - `${PLUGIN_IDENTIFIER} not support ssr for rspack bundler yet!`, - ); - } - modifyBundlerConfig(config, false); - }, - webpack(config, { isServer }) { - // @ts-ignore - modifyBundlerConfig(config, isServer); - const enableAsyncEntry = modernjsConfig.source?.enableAsyncEntry; - if (!enableAsyncEntry && mfConfig.async !== false) { - const asyncBoundaryPluginOptions = - typeof mfConfig.async === 'object' - ? mfConfig.async - : { - eager: (module) => - module && /\.federation/.test(module?.request || ''), - excludeChunk: (chunk) => chunk.name === mfConfig.name, - }; - config.plugins?.push( - new AsyncBoundaryPlugin(asyncBoundaryPluginOptions), - ); - } - config.ignoreWarnings = config.ignoreWarnings || []; - config.ignoreWarnings.push((warning) => { - if (warning.message.includes('external script')) { - return true; +): CliPlugin => { + const internalModernPluginOptions: InternalModernPluginOptions = { + csrConfig: undefined, + ssrConfig: undefined, + browserPlugin: undefined, + nodePlugin: undefined, + distOutputDir: '', + originPluginOptions: userConfig, + }; + return { + name: '@modern-js/plugin-module-federation', + setup: async ({ useConfigContext }) => { + console.log('main plugin'); + + const modernjsConfig = useConfigContext(); + return { + config: async () => { + return { + tools: { + rspack(config, { isServer }) { + const browserPluginOptions = + internalModernPluginOptions.csrConfig as MFPluginOptions.ModuleFederationPluginOptions; + if (!isServer) { + internalModernPluginOptions.browserPlugin = + new RspackModuleFederationPlugin(browserPluginOptions); + config.plugins?.push( + internalModernPluginOptions.browserPlugin, + ); + } + }, + webpack(config, { isServer }) { + const browserPluginOptions = + internalModernPluginOptions.csrConfig as MFPluginOptions.ModuleFederationPluginOptions; + if (!isServer) { + internalModernPluginOptions.browserPlugin = + new WebpackModuleFederationPlugin(browserPluginOptions); + config.plugins?.push( + internalModernPluginOptions.browserPlugin, + ); + } + const enableAsyncEntry = + modernjsConfig.source?.enableAsyncEntry; + if (!enableAsyncEntry && browserPluginOptions.async !== false) { + const asyncBoundaryPluginOptions = + typeof browserPluginOptions.async === 'object' + ? browserPluginOptions.async + : { + eager: (module) => + module && + /\.federation/.test(module?.request || ''), + excludeChunk: (chunk) => + chunk.name === browserPluginOptions.name, + }; + config.plugins?.push( + new AsyncBoundaryPlugin(asyncBoundaryPluginOptions), + ); } - return false; - }); - }, - devServer: { - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': - 'GET, POST, PUT, DELETE, PATCH, OPTIONS', - 'Access-Control-Allow-Headers': - 'X-Requested-With, content-type, Authorization', }, - before: [ - (req, res, next) => { - if (!enableSSR) { - next(); - return; - } - try { - const SERVER_PREFIX = `/${MODERN_JS_SERVER_DIR}`; - if ( - req.url?.startsWith(SERVER_PREFIX) || - (req.url?.includes('.json') && - !req.url?.includes('hot-update')) - ) { - const filepath = path.join( - process.cwd(), - `dist${req.url}`, - ); - fs.statSync(filepath); - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader( - 'Access-Control-Allow-Methods', - 'GET, POST, PUT, DELETE, PATCH, OPTIONS', - ); - res.setHeader( - 'Access-Control-Allow-Headers', - 'X-Requested-With, content-type, Authorization', - ); - fs.createReadStream(filepath).pipe(res); - } else { - next(); - } - } catch (err) { - if (process.env.FEDERATION_DEBUG) { - console.error(err); - } - next(); - } - }, - ], - }, - bundlerChain(chain, { isServer }) { - if (isDev && !isServer) { - chain.externals({ - '@module-federation/node/utils': 'NOT_USED_IN_BROWSER', - }); - } - }, - }, - source: { - alias: { - '@modern-js/runtime/mf': require.resolve( - '@module-federation/modern-js/runtime', - ), - }, - define: { - FEDERATION_IPV4: JSON.stringify(ipv4), }, - }, - dev: { - assetPrefix: modernjsConfig?.dev?.assetPrefix - ? modernjsConfig.dev.assetPrefix - : true, - }, - }; - }, - modifyEntryImports({ entrypoint, imports }: any) { - if (!enableSSR || !isDev) { - return { - entrypoint, - imports, }; - } - imports.push({ - value: '@module-federation/modern-js/ssr-runtime', - specifiers: [{ imported: SSR_PLUGIN_IDENTIFIER }], - }); - - return { - entrypoint, - imports, - }; - }, - - modifyEntryRuntimePlugins({ entrypoint, plugins }) { - if (!enableSSR || !isDev) { - return { - entrypoint, - plugins, - }; - } - - plugins.unshift({ - name: SSR_PLUGIN_IDENTIFIER, - options: JSON.stringify({}), - }); - - return { - entrypoint, - plugins, - }; - }, - afterBuild: () => { - if (enableSSR) { - updateStatsAndManifest(nodePlugin, browserPlugin, outputDir); - } - }, - afterDev: () => { - if (enableSSR) { - updateStatsAndManifest(nodePlugin, browserPlugin, outputDir); - } - }, - }; - }, -}); + }, + }; + }, + usePlugins: [ + moduleFederationConfigPlugin(internalModernPluginOptions), + moduleFederationSSRPlugin( + internalModernPluginOptions as Required, + ), + ], + }; +}; export default moduleFederationPlugin; diff --git a/packages/modernjs/src/cli/ssrPlugin.ts b/packages/modernjs/src/cli/ssrPlugin.ts new file mode 100644 index 00000000000..d5b139324e1 --- /dev/null +++ b/packages/modernjs/src/cli/ssrPlugin.ts @@ -0,0 +1,143 @@ +import path from 'path'; +import { fs } from '@modern-js/utils'; +import type { CliPlugin, AppTools } from '@modern-js/app-tools'; +import type { InternalModernPluginOptions } from '../types'; +import { ModuleFederationPlugin } from '@module-federation/enhanced'; +import { + StreamingTargetPlugin, + EntryChunkTrackerPlugin, +} from '@module-federation/node'; +import { updateStatsAndManifest } from './manifest'; +import { MODERN_JS_SERVER_DIR, PLUGIN_IDENTIFIER } from '../constant'; +import { isDev } from './constant'; + +export function setEnv() { + process.env['MF_DISABLE_EMIT_STATS'] = 'true'; + process.env['MF_SSR_PRJ'] = 'true'; +} + +export const moduleFederationSSRPlugin = ( + userConfig: Required, +): CliPlugin => ({ + name: '@modern-js/plugin-module-federation-ssr', + pre: [ + '@modern-js/plugin-module-federation-config', + '@modern-js/plugin-module-federation', + ], + setup: async ({ useConfigContext }) => { + console.log('ssr plugin'); + const modernjsConfig = useConfigContext(); + const enableSSR = Boolean(modernjsConfig?.server?.ssr); + if (!enableSSR) { + return {}; + } + + setEnv(); + return { + _internalRuntimePlugins: ({ entrypoint, plugins }) => { + if (!isDev) { + return { entrypoint, plugins }; + } + plugins.push({ + name: 'mfSSR', + path: '@module-federation/modern-js/ssr-runtime', + config: {}, + }); + return { entrypoint, plugins }; + }, + config: async () => { + return { + tools: { + rspack(config, { isServer }) { + if (isServer) { + throw new Error( + `${PLUGIN_IDENTIFIER} Not support rspack ssr mode yet !`, + ); + } + }, + webpack(config, { isServer }) { + if (isServer) { + if (!userConfig.nodePlugin) { + userConfig.nodePlugin = new ModuleFederationPlugin( + userConfig.ssrConfig, + ); + } + // @ts-ignore + config.plugins?.push(userConfig.nodePlugin); + config.plugins?.push( + new StreamingTargetPlugin(userConfig.nodePlugin), + ); + if (isDev) { + config.plugins?.push(new EntryChunkTrackerPlugin()); + } + } else { + userConfig.distOutputDir = + userConfig.distOutputDir || + config.output?.path || + path.resolve(process.cwd(), 'dist'); + } + }, + devServer: { + before: [ + (req, res, next) => { + if (!enableSSR) { + next(); + return; + } + try { + const SERVER_PREFIX = `/${MODERN_JS_SERVER_DIR}`; + if ( + req.url?.startsWith(SERVER_PREFIX) || + (req.url?.includes('.json') && + !req.url?.includes('hot-update')) + ) { + const filepath = path.join( + process.cwd(), + `dist${req.url}`, + ); + fs.statSync(filepath); + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader( + 'Access-Control-Allow-Methods', + 'GET, POST, PUT, DELETE, PATCH, OPTIONS', + ); + res.setHeader( + 'Access-Control-Allow-Headers', + 'X-Requested-With, content-type, Authorization', + ); + fs.createReadStream(filepath).pipe(res); + } else { + next(); + } + } catch (err) { + if (process.env.FEDERATION_DEBUG) { + console.error(err); + } + next(); + } + }, + ], + }, + bundlerChain(chain, { isServer }) { + if (isDev && !isServer) { + chain.externals({ + '@module-federation/node/utils': 'NOT_USED_IN_BROWSER', + }); + } + }, + }, + }; + }, + afterBuild: () => { + const { nodePlugin, browserPlugin, distOutputDir } = userConfig; + updateStatsAndManifest(nodePlugin, browserPlugin, distOutputDir); + }, + afterDev: () => { + const { nodePlugin, browserPlugin, distOutputDir } = userConfig; + updateStatsAndManifest(nodePlugin, browserPlugin, distOutputDir); + }, + }; + }, +}); + +export default moduleFederationSSRPlugin; diff --git a/packages/modernjs/src/cli/utils.spec.ts b/packages/modernjs/src/cli/utils.spec.ts index 41933086244..0d6811bf9d3 100644 --- a/packages/modernjs/src/cli/utils.spec.ts +++ b/packages/modernjs/src/cli/utils.spec.ts @@ -1,6 +1,6 @@ import { it, expect, describe } from 'vitest'; import path from 'path'; -import { getTargetEnvConfig, patchWebpackConfig } from './utils'; +import { patchMFConfig, patchBundlerConfig, getIPV4 } from './utils'; const mfConfig = { name: 'host', @@ -13,11 +13,13 @@ const mfConfig = { 'react-dom': { singleton: true, eager: true }, }, }; -describe('getTargetEnvConfig', async () => { - it('getTargetEnvConfig: server', async () => { - const targetEnvConfig = getTargetEnvConfig(mfConfig, true); +describe('patchMFConfig', async () => { + it('patchMFConfig: server', async () => { + const patchedConfig = JSON.parse(JSON.stringify(mfConfig)); + patchMFConfig(patchedConfig, true); + const ipv4 = getIPV4(); - expect(targetEnvConfig).toStrictEqual({ + expect(patchedConfig).toStrictEqual({ dev: false, dts: false, filename: 'remoteEntry.js', @@ -27,8 +29,9 @@ describe('getTargetEnvConfig', async () => { }, name: 'host', remotes: { - remote: 'http://localhost:3000/remoteEntry.js', + remote: `http://${ipv4}:3000/remoteEntry.js`, }, + remoteType: 'script', runtimePlugins: [ path.resolve(__dirname, './mfRuntimePlugins/shared-strategy.js'), path.resolve(__dirname, './mfRuntimePlugins/inject-node-fetch.js'), @@ -46,15 +49,18 @@ describe('getTargetEnvConfig', async () => { }); }); - it('getTargetEnvConfig: client', async () => { - const targetEnvConfig = getTargetEnvConfig(mfConfig, false); + it('patchMFConfig: client', async () => { + const patchedConfig = JSON.parse(JSON.stringify(mfConfig)); + patchMFConfig(patchedConfig, false); + const ipv4 = getIPV4(); - expect(targetEnvConfig).toStrictEqual({ + expect(patchedConfig).toStrictEqual({ filename: 'remoteEntry.js', name: 'host', remotes: { - remote: 'http://localhost:3000/remoteEntry.js', + remote: `http://${ipv4}:3000/remoteEntry.js`, }, + remoteType: 'script', runtimePlugins: [ path.resolve(__dirname, './mfRuntimePlugins/shared-strategy.js'), ], @@ -77,14 +83,14 @@ describe('getTargetEnvConfig', async () => { }); }); -describe('patchWebpackConfig', async () => { - it('patchWebpackConfig: server', async () => { +describe('patchBundlerConfig', async () => { + it('patchBundlerConfig: server', async () => { const bundlerConfig = { output: { publicPath: 'auto', }, }; - patchWebpackConfig<'webpack'>({ + patchBundlerConfig<'webpack'>({ bundlerConfig, isServer: true, modernjsConfig: { @@ -106,13 +112,13 @@ describe('patchWebpackConfig', async () => { }); }); - it('patchWebpackConfig: client', async () => { + it('patchBundlerConfig: client', async () => { const bundlerConfig = { output: { publicPath: 'auto', }, }; - patchWebpackConfig<'webpack'>({ + patchBundlerConfig<'webpack'>({ bundlerConfig, isServer: false, modernjsConfig: { diff --git a/packages/modernjs/src/cli/utils.ts b/packages/modernjs/src/cli/utils.ts index 041a767fead..691cc9426a0 100644 --- a/packages/modernjs/src/cli/utils.ts +++ b/packages/modernjs/src/cli/utils.ts @@ -35,13 +35,6 @@ export const getMFConfig = async ( const mfConfig = (await import(preBundlePath)) .default as unknown as moduleFederationPlugin.ModuleFederationPluginOptions; - await replaceRemoteUrl(mfConfig); - if (mfConfig.remoteType === undefined) { - mfConfig.remoteType = 'script'; - } - if (!mfConfig.name) { - throw new Error(`${PLUGIN_IDENTIFIER} mfConfig.name can not be empty!`); - } return mfConfig; }; @@ -54,9 +47,9 @@ const injectRuntimePlugins = ( } }; -const replaceRemoteUrl = async ( +const replaceRemoteUrl = ( mfConfig: moduleFederationPlugin.ModuleFederationPluginOptions, -): Promise => { +) => { if (!mfConfig.remotes) { return; } @@ -135,6 +128,13 @@ export const patchMFConfig = ( mfConfig: moduleFederationPlugin.ModuleFederationPluginOptions, isServer: boolean, ) => { + replaceRemoteUrl(mfConfig); + if (mfConfig.remoteType === undefined) { + mfConfig.remoteType = 'script'; + } + if (!mfConfig.name) { + throw new Error(`${PLUGIN_IDENTIFIER} mfConfig.name can not be empty!`); + } const runtimePlugins = [...(mfConfig.runtimePlugins || [])]; patchDTSConfig(mfConfig, isServer); @@ -165,52 +165,38 @@ export const patchMFConfig = ( path.resolve(__dirname, './mfRuntimePlugins/inject-node-fetch.js'), runtimePlugins, ); - } - - if (!isServer) { - return { - ...mfConfig, - runtimePlugins, - }; - } - - return { - ...mfConfig, - runtimePlugins, - dts: false, - dev: false, - }; -}; -export function getTargetEnvConfig( - mfConfig: moduleFederationPlugin.ModuleFederationPluginOptions, - isServer: boolean, -) { - const patchedMFConfig = patchMFConfig(mfConfig, isServer); - if (isServer) { - return { - library: { + if (!mfConfig.library) { + mfConfig.library = { type: 'commonjs-module', name: mfConfig.name, - }, - ...patchedMFConfig, - }; + }; + } else { + if (!mfConfig.library.type) { + mfConfig.library.type = 'commonjs-module'; + } + if (!mfConfig.library.name) { + mfConfig.library.name = mfConfig.name; + } + } } - if (patchedMFConfig.library?.type === 'commonjs-module') { - return { - ...patchedMFConfig, - library: { - ...mfConfig.library, - type: 'global', - }, - }; + mfConfig.runtimePlugins = runtimePlugins; + + if (!isServer) { + if (mfConfig.library?.type === 'commonjs-module') { + mfConfig.library.type = 'global'; + } + return mfConfig; } - return patchedMFConfig; -} + mfConfig.dts = false; + mfConfig.dev = false; + + return mfConfig; +}; -export function patchWebpackConfig(options: { +export function patchBundlerConfig(options: { bundlerConfig: BundlerConfig; isServer: boolean; modernjsConfig: UserConfig; diff --git a/packages/modernjs/src/ssr-runtime/plugin.tsx b/packages/modernjs/src/ssr-runtime/plugin.tsx index 03bfe5fddb8..1c0e3879818 100644 --- a/packages/modernjs/src/ssr-runtime/plugin.tsx +++ b/packages/modernjs/src/ssr-runtime/plugin.tsx @@ -2,7 +2,7 @@ import type { Plugin } from '@modern-js/runtime'; import hoistNonReactStatics from 'hoist-non-react-statics'; import { SSRLiveReload } from './SSRLiveReload'; -export const mfPluginSSR = (): Plugin => ({ +export const mfSSRPlugin = (): Plugin => ({ name: '@module-federation/modern-js', setup: () => { diff --git a/packages/modernjs/src/types/index.ts b/packages/modernjs/src/types/index.ts index 8eb99495d24..e4f880aca55 100644 --- a/packages/modernjs/src/types/index.ts +++ b/packages/modernjs/src/types/index.ts @@ -5,10 +5,16 @@ import type { ModuleFederationPlugin as RspackModuleFederationPlugin } from '@mo export interface PluginOptions { config?: moduleFederationPlugin.ModuleFederationPluginOptions; configPath?: string; - webpackPluginImplementation?: typeof WebpackModuleFederationPlugin; - rspackPluginImplementation?: typeof RspackModuleFederationPlugin; } +export interface InternalModernPluginOptions { + csrConfig?: moduleFederationPlugin.ModuleFederationPluginOptions; + ssrConfig?: moduleFederationPlugin.ModuleFederationPluginOptions; + distOutputDir: string; + originPluginOptions: PluginOptions; + browserPlugin?: BundlerPlugin; + nodePlugin?: BundlerPlugin; +} export type BundlerPlugin = | WebpackModuleFederationPlugin | RspackModuleFederationPlugin;