Files
docs/src/frontend/apps/impress-plugin/webpack.config.js
rvveber ab74aeff5c fix: Ensure federated types are downloaded before type compiling/ type checking
- Adds a function to the webpack.config and documentation to make sure host types are downloaded to the plugin before the first type compile/ type check is happening

Avoids an error where on cold start the types were not yet downloaded but types were already checked.
2025-11-12 17:16:11 +01:00

105 lines
2.9 KiB
JavaScript

const path = require('path');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
const {
NativeFederationTypeScriptHost,
} = require('@module-federation/native-federation-typescript/webpack');
const {
NativeFederationTypeScriptHost: NativeFederationTypeScriptHostCore,
} = require('@module-federation/native-federation-typescript');
const moduleFederationConfig = {
name: 'plugin_frontend',
filename: 'remoteEntry.js',
exposes: {
'./MyCustomComponent': './src/MyCustomComponent.tsx',
'./MyCustomHeaderMenu': './src/MyCustomHeaderMenu.tsx',
'./ThemingComponent': './src/ThemingComponent.tsx',
'./ThemingDemo': './src/ThemingDemo.tsx',
},
remotes: {
impress: 'impress@http://localhost:3000/_next/static/chunks/remoteEntry.js',
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true },
'styled-components': { singleton: true },
'react-aria-components': { singleton: true },
'@openfun/cunningham-react': { singleton: true },
'react-i18next': { singleton: true },
'yjs': { singleton: true },
'@gouvfr-lasuite/ui-kit': { singleton: true },
'clsx': { singleton: true },
'cmdk': { singleton: true },
'react-intersection-observer': { singleton: true },
'@tanstack/react-query': { singleton: true },
'zustand': { singleton: true },
},
};
let mfTypesReady;
const ensureFederatedTypesPlugin = {
apply(compiler) {
compiler.hooks.beforeCompile.tapPromise(
'EnsureFederatedTypes',
async () => {
if (!mfTypesReady) {
const downloader = NativeFederationTypeScriptHostCore.raw({
moduleFederationConfig,
});
mfTypesReady = downloader.writeBundle();
}
await mfTypesReady;
},
);
},
};
module.exports = (env, argv) => {
const dev = argv.mode !== 'production';
return {
entry: './src/index.tsx',
mode: dev ? 'development' : 'production',
devServer: dev ? {
port: 3002,
hot: true,
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',
},
} : undefined,
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: dev ? 'http://localhost:3002/' : undefined,
},
resolve: {
extensions: ['.tsx', '.ts', '.js', '.jsx'],
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
plugins: [
new ModuleFederationPlugin(moduleFederationConfig),
...(dev
? [
ensureFederatedTypesPlugin,
NativeFederationTypeScriptHost({
moduleFederationConfig,
}),
]
: []),
],
};
};