/* * Webpack bundle configuration that enables project export as UMD library and Module Federated container * * Custom styleTagTransform script is defined at https://gist.github.com/marcosmapf/904986dde911148e39a17a59dc3dd132 * The 'from' option attribute is used inside styleTagTransform as a reference to the project's root element */ const { join } = require('path') const { container, EnvironmentPlugin } = require('webpack') const ModuleFederationPlugin = container.ModuleFederationPlugin const { PATHS } = require('../constants.js') const common = require('../webpack.common.js') const pkjson = require(join(PATHS.ROOT, 'package.json')) require('dotenv').config({ path: join(PATHS.ENV, `/.${process.env.NODE_ENV}`) }) const isDevelopment = process.env.NODE_ENV === 'development' const environmentVars = [ 'variablesHere' ] module.exports = { entry: join(PATHS.STARTUP, 'umd', './index.tsx'), mode: 'production', output: { filename: 'bundle.js', chunkFilename: '[contenthash].[name].bundle.js', library: '@enterprise/app-name', libraryTarget: 'umd', path: PATHS.BUILD, }, resolve: { extensions: ['.js', '.ts', '.tsx', '.json'], alias: { '@cosmos': PATHS.COSMOS, 'assets': PATHS.ASSETS, 'components': PATHS.COMPONENTS, 'config': PATHS.CONFIG, 'hooks': PATHS.HOOKS, 'languages': PATHS.LANGUAGES, 'pages': PATHS.PAGES, 'root': PATHS.ROOT, 'startup': PATHS.STARTUP, 'typings': PATHS.TYPINGS, 'utils': PATHS.UTILS, }, fallback: { path: false, fs: false, url: false } }, module: { rules: [ { test: /\.(ts|js)x?$/, exclude: /node_modules/, loader: 'ts-loader', options: { compilerOptions: { noEmit: false } } }, { test: /\.(s?)css$/, use: [ { loader: `${PATHS.CUSTOM_SCRIPTS}/style-loader`, // Irrelevant for most projects, you can probably use style-loader directly options: { attributes: { from: process.env.PROJECT_NAME }, styleTagTransform: `${PATHS.CUSTOM_SCRIPTS}/styleTagTransform` } }, 'css-loader', 'postcss-loader', 'sass-loader' ] }, { test: /\.(png|jpg|gif|ico)$/, loader: 'asset/resource', }, { test: /\.svg$/, use: ['@svgr/webpack'], } ] }, plugins: [ new EnvironmentPlugin(environmentVars), new ModuleFederationPlugin({ name: 'app_1', // Name of the current app, considered the host project filename: 'remoteEntry.js', exposes: { './Main': join(PATHS.STARTUP, 'module-federation/index.tsx'), // exposed module name }, remotes: { App2: 'app_2@http://app-uri.com/remoteEntry.js' }, shared: { react: { requiredVersion: pkjson.dependencies.react, }, 'react-dom': { requiredVersion: pkjson.dependencies['react-dom'], }, 'react-router-dom': { requiredVersion: pkjson.dependencies['react-router-dom'], }, }, }), ], optimization: { splitChunks: { chunks: 'async', maxAsyncRequests: 30, maxInitialRequests: 30, cacheGroups: { defaultVendors: { test: /[\\/]node_modules[\\/]/, chunks: 'async', filename: '[contenthash].vendors.bundle.js', }, }, }, }, }