TianlunXiong / webpack-external-import

Dynamically import modules from other webpack bundles. Painless code sharing between separate apps

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Webpack External Import

import() other modules from third parties, or other webpack builds themselves while sharing dependencies! At runtime! Welcome To Webpack Module Federation

Commitizen friendly Version

Downloads License License

webpack-external-import

This Project has been incoporated into the Webpack 5 core. Track the progress and share the issue for wider exposure. I believe a system like this would offer great benefits for the JavaScript community. https://github.com/ScriptedAlchemy/webpack/issues/10352

Because this project is now based out of the Webpack 5 repo. It serves mostly as an example, testing ground, and documentation house.

How to run example project

  1. Run an install from the root yarn install

  2. From the root of the project, run yarn dev

Usage

Configure each webpack build you intend to federate code between.

const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
	// other webpack config options...
	output: {
		publicPath: 'http://localhost:3002/', //important to specify url path if loading code from alternative domains/ports
	},
	plugins: [
		new ModuleFederationPlugin({
			name: 'website1',
			library: { type: 'var', name: 'website1' },
			filename: 'remoteEntry.js',
			exposes: {
				Footer: './src/Footer',
			},
			remotes: {
				website2: 'website2',
			},
			shared: ['react', 'react-dom'],
		}),
	],
};

Consuming code from a remote

Webpack will generate a special file along with a standard build. In this example, i have called it remoteEntry.js

Add the remote entry to an application that will consume federated modules.

<html>
	<head>
		<script src="http://localhost:3002/remoteEntry.js"></script>
	</head>
	<body>
		<div id="app"></div>
	</body>
</html>

Consume code from a remote using any require syntax.

import React, { lazy, Suspense, useState } from 'react';
import Footer from './Footer';
import Footer2 from 'website2/Footer'; // federated

const Title = lazy(() => import('website2/Title')); // federated

export default () => {
	return (
		<>
			<Suspense fallback={'fallback'}>
				<Title />
			</Suspense>
			<p>
				This app loads the heading above from website2, and doesnt expose
				anything itself.
			</p>
			<Footer />
			<Footer2 />
		</>
	);
};

API

name Must be a unique name, used as the namespace to reference federated code. No two apps should share the same namespace
library Expects an object, the type can be any of the following. `{type:'var'
filename Name of the generated javascript file. The name will be static (no hash) in order to allow orchestration between webpack builds.
exposes Expects an object/array. The key is how a module will be required from another app, the value is a relative path based on the context of the build.
remotes A list of other remote names. A remote name is the string used in the name option. Its used to inform Webpack of the scope where a module is located
shared Object/Array of requests or modules that should be shared between federated code. A remote will depend on the host's dependency, if none exists, the remote will fallback and load its own

Examples of using Module Federation outside of the browser - Useful for SSR

Read more: https://github.com/webpack/webpack/tree/b5eeb7d67dcb1dab246a4ea9cef62255e177406d/test/configCases/container/2-container-full

module.exports = {
	plugins: [
		new ModuleFederationPlugin({
			name: 'container',
			library: { type: 'commonjs-module' },
			filename: 'container.js',
			remotes: {
				containerB: '../1-container-full/container.js',
			},
			shared: ['react'],
		}),
	],
};

Inside the App, remotes can be consumed as such.

import React from "react";
import ComponentC from "containerB/ComponentC";

export default () => {
	return `App rendered with [${React()}] and [${ComponentC()}]`;
};

About

Dynamically import modules from other webpack bundles. Painless code sharing between separate apps

License:BSD 3-Clause "New" or "Revised" License


Languages

Language:JavaScript 100.0%