想象一下,在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 配置可以查看这篇文章

  1. module.exports = override(
  2. config => {
  3. config.output.publicPath = 'http://localhost:3000/';
  4. return config;
  5. },
  6. addWebpackPlugin(new ModuleFederationPlugin({
  7. name: 'ccomponent',
  8. filename: "remoteEntry.js",
  9. exposes: {
  10. './button': './src/button/index.jsx',
  11. }
  12. })),
  13. );

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

我们在 src 新建一个 button 组件

  1. // src/button/index.jsx
  2. import React from 'react'
  3. import PropTypes from 'prop-types'
  4. const Button = props => {
  5. const {
  6. children
  7. } = props;
  8. return (
  9. <button>
  10. { children }
  11. </button>
  12. )
  13. }
  14. Button.propTypes = {
  15. children: PropTypes.node.isRequired
  16. }
  17. export default Button

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

模块的使用

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

  1. module.exports = override(
  2. addWebpackPlugin(new ModuleFederationPlugin({
  3. name: 'app',
  4. remotes: {
  5. 'ccomponent': 'ccomponent@http://localhost:3000/remoteEntry.js',
  6. }
  7. })),
  8. );

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

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

  1. const Button = React.lazy(() => import("ccomponent/button"));
  2. function App() {
  3. return (
  4. <div className="App">
  5. <React.Suspense fallback="Loading Component">
  6. <Button>hello</Button>
  7. </React.Suspense>
  8. </div>
  9. );
  10. }

到此为止,就可以在 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 1175G - Yet Another Partiton Problem(李超线段树)

    Codeforces 题面传送门 & 洛谷题面传送门 这是一道李超线段树的毒瘤题. 首先我们可以想到一个非常 trivial 的 DP:\(dp_{i,j}\)​ 表示前 \(i\)​ 个数划 ...

  2. 洛谷 P5280 - [ZJOI2019]线段树(线段树+dp,神仙题)

    题面传送门 神仙 ZJOI,不会做啊不会做/kk Sooke:"这八成是考场上最可做的题",由此可见 ZJOI 之毒瘤. 首先有一个非常显然的转化,就是题目中的"将线段树 ...

  3. PHP 获取两个日期相差多少年,多少月,多少天,多少小时,并填充数组

    PHP 获取两个日期相差多少年,多少月,多少天,多少小时,并填充数组 <?php /** * 获取两个日期相差多少年,多少月,多少天,多少小时,并填充数组 * @param [type] $st ...

  4. mysql—Linux系统直接进入mysql服务器,并实现一些基础操作

    首先,我们需要通过以下命令来检查MySQL服务器是否启动: ps -ef | grep mysqld 如果MySql已经启动,以上命令将输出mysql进程列表 如果mysql未启动,你可以使用以下命令 ...

  5. CentOS6源码安装zabbix服务器

    1.下载安装包并解压 2.预环境搭建 3.创建zabbix用户,编译安装zabbix 4.配置mysql 5.配置zabbix-server 6.配置apache和php 7.添加开机自启动 1 yu ...

  6. javaSE高级篇7 — 设计原则和设计模式 — 设计模式慢慢更( 这是思想层次篇 )

    1.什么是设计原则? 设计原则就是面向对象的原则嘛,即:OOP原则 换句话说:就是为了处理类与类之间的关系( 包括接口.类中的方法 ) 2.OOP设计原则有哪些? 1).开闭原则:就是指对拓展开放.对 ...

  7. python-3.x- 序列操作

    1. list操作 A.添加元素 1 list = ["C++","C", "Java", "Python"] 2 &q ...

  8. Android 高级UI组件(一)GridView与ListView

    1.GridView 1.GridView学习 GridView和ListView都是比较常用的多控件布局,而GridView更是实现九宫图的首选 main.xml: <?xml version ...

  9. android知识点duplicateParentState

    android知识点duplicateParentState 今天要做一个效果,组件RelativeLayout上有两个TextView,这两个TextView具有不同的颜色值,现在要的效果是,当Re ...

  10. Static data members in C++

    Predict the output of following C++ program: 1 #include <iostream> 2 using namespace std; 3 4 ...