想象一下,在webpack5还没出来前,前端使用第三方组件库,例如使用 dayjs 日期处理库,都是通过 npm i dayjs -s 安装 dayjs 模块到项目里,然后就可以通过 require 或者 import 来使用。整个过程也不是很麻烦,但是如果某一天 dayjs 这个库修复了一个重大bug,我们得重新通过 npm 来安装最新版本,然后重启项目,那么有没有一个更简单的方案呢?

本文首发于:https://www.1024nav.com/blog/webpck5-module-federation

模块联邦

为了减少对 npm 包的安装频率,还有避免本地安装 node_modules 包,webpack开发团队想出了一个解决方案,能否将第三方库放到网络上单独部署,如果项目需要使用再从该库的地址上直接拉取下来使用,这样就不需要通过 npm 来安装,更新指定依赖包,也方便实时保持库的新版本。感觉有点类似以前通过 cdn 引入第三方js库的感觉

模块联邦还可以实现微前端服务

什么是微前端

微前端是一个技术栈无关的多应用集成思想,将一个大应用拆分成多个子应用来开发,每个子应用可以使用自己的技术栈(vue,angularjs,reactjs,jquery)进行独立开发,部署。最后通过主应用基座来集成各个子应用。具体细节这里不展开讲

模块联邦如何实现模块共享

webpack提供了一个 ModuleFederationPlugin 插件,能够实现模块的发布和引入, ModuleFederationPlugin 插件常用的配置有以下几个

  • name : 必须,唯一的库名,使用者通过 [name]/[exposes]使用
  • filename :必须,暴露的文件名,在使用者通过 remotes 来引入
  • library :可选, umd的名称,类似于jQuery的$,lodash的_
  • exposes : 可选,配置暴露指定的模块,供其他人使用
  • remotes : 可选,表示使用其他远程的模块
  • shared :可选, 配置共享库,例如 shared: ['react', 'react-dom'] 意思是宿主和引用依赖的模块共享配置的库,如果host有该库则不需要再次下载,直接使用host已有的库

接下来一步一步实现一个模块联邦功能

模块的开发和部署

通过CRA(create react app)来创建一个应用。我们创建一个 common-component 项目

然后配置 ModuleFederationPlugin ,在 config-overrides.js 文件里面新增以下配置。关于 cra 如何自定义 webpack 配置可以查看这篇文章

module.exports = override(
config => {
config.output.publicPath = 'http://localhost:3000/';
return config;
},
addWebpackPlugin(new ModuleFederationPlugin({
name: 'ccomponent',
filename: "remoteEntry.js",
exposes: {
'./button': './src/button/index.jsx',
}
})),
);

注意这里的 publicPath 是必须的,获取组件的时候会从当前 host 下获取 button 这个组件,通过 ModuleFederationPlugin 的 exposes 选项暴露 button 组件。

我们在 src 新建一个 button 组件

// src/button/index.jsx
import React from 'react'
import PropTypes from 'prop-types' const Button = props => {
const {
children
} = props;
return (
<button>
{ children }
</button>
)
} Button.propTypes = {
children: PropTypes.node.isRequired
} export default Button

通过 npm run start 启动,这时候可以访问到 http://localhost:3000/remoteEntry.js

模块的使用

我们再通过 CRA 创建一个名称 app 的项目,同样的在 config-overrides.js 里面引入 ModuleFederationPlugin

module.exports = override(
addWebpackPlugin(new ModuleFederationPlugin({
name: 'app',
remotes: {
'ccomponent': 'ccomponent@http://localhost:3000/remoteEntry.js',
}
})),
);

cccomponent 是上面 common-component 项目里面配置的 name

然后在 app 里面使用 common-component 的 button 组件,这里使用 React.lazy 来异步加载该组件

const Button = React.lazy(() => import("ccomponent/button"));

function App() {
return (
<div className="App">
<React.Suspense fallback="Loading Component">
<Button>hello</Button>
</React.Suspense>
</div>
);
}

到此为止,就可以在 app 项目里面看到 button 了,666~

总结

webpack提供对模块联邦会使以后模块使用更加方便,快捷,一切工具都是为了方便开发,给 webpack 的贡献者点个赞!

手把手教你如何使用 webpack5 的模块联邦新特性的更多相关文章

  1. 17、手把手教你Extjs5(十七)模块的新增、修改、删除操作

    上节在Grid展示时做了一个金额单位可以手工选择的功能,如果你要加入其他功能,也只要按照这个模式来操作就行了,比如说你想改变金额字段的颜色.小数位数.零值是否显示.货币符号.单位显示在标题栏或者跟在金 ...

  2. 13、手把手教你Extjs5(十三)模块字段和Grid列的定义[1]

    这一节加入模块自定义字段,并根据这些字段生成model.然后再定义grid中的分组和列.从这一切开始真正进入到了模块自定义的节奏当中,代码的复杂度和技巧性也大大提高.先从模块字段的自定义开始.先看一下 ...

  3. 11、手把手教你Extjs5(十一)模块界面的总体设计

    上一节中设计了一些模块自定义中用到的要素,为了直观起见,这一节先建立一个模块的主界面.看过我 模块管理常规功能自定义系统的设计与实现 博客的人应该会有所了解了.一个模块的主界面是一个Grid,在其上方 ...

  4. 手把手教你写LKM rookit! 之 第一个lkm程序及模块隐藏(一)

    唉,一开始在纠结起个什么名字,感觉名字常常的很装逼,于是起了个这<手把手教你写LKM rookit> 我觉得: 你们觉得:...... 开始之前,我们先来理解一句话:一切的操作都是系统调用 ...

  5. 每天记录一点:NetCore获得配置文件 appsettings.json vue-router页面传值及接收值 详解webpack + vue + node 打造单页面(入门篇) 30分钟手把手教你学webpack实战 vue.js+webpack模块管理及组件开发

    每天记录一点:NetCore获得配置文件 appsettings.json   用NetCore做项目如果用EF  ORM在网上有很多的配置连接字符串,读取以及使用方法 由于很多朋友用的其他ORM如S ...

  6. 手把手教你做JavaWeb项目:登录模块

    现如今,无论是客户端还是移动端,无论是游戏登陆还是社交平台登陆,无处不在的“登陆”.那么你知道怎么制作吗?今天就为你娓娓道来: 用户登录 在各大信息管理系统中,登录功能是必不可少的,他的作用就是验证用 ...

  7. 手把手教Linux驱动2-之模块参数和符号导出

    通过<手把手教Linux驱动1-模块化编程,玩转module>的学习,我们已经掌握了如何向内核加载一个模块,现在我们学习模块之间如何传递参数. 一.给模块传递参数 当我们加载一个模块到Li ...

  8. 30分钟手把手教你学webpack实战

    30分钟手把手教你学webpack实战 阅读目录 一:什么是webpack? 他有什么优点? 二:如何安装和配置 三:理解webpack加载器 四:理解less-loader加载器的使用 五:理解ba ...

  9. 手把手教你用动软.NET代码生成器实例教程

    动软实战攻略 手把手教你用动软 文档编号:20110421 版权所有 © 2004-2011 动软 在线帮助:http://help.maticsoft.com 目录   一.        产品介绍 ...

随机推荐

  1. Codeforces 772D - Varying Kibibits(高维差分+二项式定理维护 k 次方和)

    Codeforces 题目传送门 & 洛谷题目传送门 首先很容易注意到一件事,那就是对于所有 \(f(S)\) 可能成为 \(x\) 的集合 \(S\),必定有 \(\forall y\in ...

  2. UOJ #11 - 【UTR #1】ydc的大树(换根 dp)

    题面传送门 Emmm--这题似乎做法挺多的,那就提供一个想起来写起来都不太困难的做法吧. 首先不难想到一个时间复杂度 \(\mathcal O(n^2)\) 的做法:对于每个黑点我们以它为根求出离它距 ...

  3. 使用bioawk对基因组fasta序列ID(染色体/scaffold名称)排序?

    目录 需求 实现 需求 已知某基因组序列,染色体或scaffold ID顺序不定,想要对其按数字排序. 原顺序: 想要的排序结果: 实现 使用bioawk,没有的话conda直接安装. bioawk ...

  4. Linux中gz文件操作遇到的一些技巧和坑

    目录 不解压情况下获取gz超大文件的前/后几行? Perl读入gz文件操作? 不能直接通过wc -l 来统计gz文件的行数 前提是gz文件超大,如上百G,肯定不能直接解压来做. 不解压情况下获取gz超 ...

  5. RNA-seq 生物学重复相关性验证

    根据拿到的表达矩阵设为exprSet 1.用scale 进行标准化 数据中心化:数据集中的各个数字减去数据集的均值 数据标准化:中心化之后的数据在除以数据集的标准差. 在R中利用scale方法来对数据 ...

  6. perl和python3 同时打开两个文件

    perl : while(defined(my $f1=<FQ1>) && defined(my $f2=<FQ2>)){ condition } python ...

  7. 进程和线程操作系统转载的Mark一下

    https://www.cnblogs.com/leisure_chn/p/10393707.html Linux的进程线程及调度 本文为宋宝华<Linux的进程.线程以及调度>学习笔记. ...

  8. jmeter+ant输出测试报告

    jmeter自己本身可以输出html测试报告的,不过这种自带的测试报告特别简陋,如下图所示,一般我们是不看这种的. 我们可以使用ant来输出更高效.更直观的测试报告. 首先下载安装ant, 我用的是a ...

  9. 【Redis】Sentinel 哨兵模式

    Sentinel(哨兵模式) 目录 Sentinel(哨兵模式) 哨兵模式的三个定时任务 Sentinel(哨兵)与Sentinel .主服务器.从服务器之间的连接 检测下线状态 选择领头 Senti ...

  10. 学习java 7.20

    学习内容: Stream流 Stream流的生成方式 中间操作方法 终结操作方法 Stream流的收集操作 类加载 类加载器的作用 将.class文件加载到内存中,并为之生成对应的java.lang. ...