前言

webpack5 出了 federated-modules,对于对微前端有需求的项目来说,无疑是一个好消息,因为它解决跨应用之间的共享模块。
而这也是微前端的核心功能之一。

github 例子
federated-modules 资料

而这个功能还在试行阶段,在这之前一般都是使用 externals 解决这种跨应用问题,当然 externals 不止这些作用,还可以优化编译速度。

externals

externals 是 webpack 的外部扩展,例如我们想引用一个库,但是又不想让 webpack 打包,并且又不影响我们在程序中以 CMD、AMD 或者 window/global 全局等方式进行使用,那就可以通过配置 externals。这个功能主要是用在创建一个库的时候用的,但是也可以在我们项目开发中充分使用,从中可知完全符合微前端糅合项目。

当然它在优化方面是很棒的。
如我们在使用 js 库如 react-dom 或者 react 等的时候,webpack 会将他们一起打包,react 和 react-dom 文件就好几百 k,全部打包成一个文件,可想而知,这个文件会很大,用户在首次打开时往往会出现白屏等待时间过长的问题,这时,我们就需要将这类文件抽离出来,那么我们就可以 externals 的方式引入。也就是说,自己的库本身不打包这个 react-dom、react,需要用户环境提供,也优化了开发与打包的编译速度。

  1. 项目中正常使用
1
2
import React from "react";
import ReactDOM from "react-dom";
  1. webpack 配置
1
2
3
4
externals: {
react: "React",
"react-dom": "ReactDOM",
},
  1. 需要 html 引入 js

直接 index.html 引入

1
2
<script src="https://cdn.bootcss.com/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.13.1/umd/react-dom.production.min.js"></script>

html-webpack-plugin 方式引入,因为 html-webpack-plugin 可以使用 ejs

1
2
3
4
5
6
7
8
9
10
11
12
13
plugins: [
//...
new HtmlWebpackPlugin({
filename: 'index.html',
template: `/public/template.ejs`,
//...
// 添加参数SCRIPTS,后面母版页会使用
SCRIPTS: [
https://cdn.bootcss.com/react/16.13.1/umd/react.production.min.js,
https://cdn.bootcss.com/react-dom/16.13.1/umd/react-dom.production.min.js
],
}),
],

template.ejs

1
2
3
<% htmlWebpackPlugin.options.SCRIPTS.forEach(function(url)) { %>
<script src="<%=url %>"></script>
<% }) %>

如果你写的库要支持各种环境,你需要设置 output 中的 libraryTarget 为 umd,也就是将打包的文件,生成为 umd 规范,适用于各种环境。libraryTarget 和 externals 关系紧密,如果出现不符合的,你可以使用 webpack 打包为 umd,webpack 打包出的名称与 externals 的 value 保持一致。

externals 配置一般都是使用 object,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
externals: {
"lodash": {
commonjs: "lodash",//如果我们的库运行在Node.js环境中,import _ from 'lodash'等价于const _ = require('lodash')
commonjs2: "lodash",//同上
amd: "lodash",//如果我们的库使用require.js等加载,等价于 define(["lodash"], factory);
root: "_"//如果我们的库在浏览器中使用,需要提供一个全局的变量‘_’,等价于 var _ = (window._) or (_);
}
}


externals: {
react: "React"
}

externals 详细资料

externals 是需要网络环境的支持的,如果一定要本地就支持,可以使用 DllPlugin
只是 DllPlugin 需要在项目里配置符合它的打包配置,项目内有一个专门打包静态不常变的配置与存放它的文件,因为与项目打包文件夹在每次打包都要被删除的,所以不能放在那。

ProvidePlugin

webpack 配置 ProvidePlugin 后,在使用时将不再需要 import 和 require 进行引入,直接使用即可。
既配置它后我们可以直接在 window 上获取到方法,不用模块导入。

webpack ProvidePlugin
ProvidePlugin 资料