DLL:Dynamic Link Library,动态链接库。最早的时候是 Windows 系统中在多个软件之间实现共享函数库的一种方式。
Webpack 中也有内置 DLL 的功能,指的是可以将不经常改变的代码,抽取成一个共享的库,之后就可以将其直接引入到需要的项目中了。从 Webpack4 开始用的已经很少了。
React 脚手架和 Vue 脚手架中在升级到 Webpack4+ 之后,都移除了 DLL 库。
以下是 Vue 作者关于移除 DLL 的说法。
使用 DLL:
以将 react 和 react-dom
打包成一个 DLL 库为例。
将想要共享的代码打包一个 DLL 库:
- 首先进入一个单独的项目,来专门对 react 和
react-dom
进行打包。 - 安装 react 和
react-dom
:npm install react reatc-dom
。 - 在
webpack.config.js
配置文件中进行配置。const path = require('path') const webpack = require('webpack') module.exports = { entry: { // 将 react 和 react-dom 打包成一个 DLL 库 react: ['react', 'react-dom'], }, output: { // 将 react 和 react 打包成的 DLL 库放到根目录的 dll 文件夹下 path: path.resolve(__dirname, './dll'), // react 和 react-dom 打包成 DLL 库的文件的名称 filename: 'dll_[name].js', // react 和 react-dom 打包成的 DLL 库的名称 library: 'dll_[name]', }, plugins: [ // 通过 DllPlugin 插件打包 DLL 库 new webpack.DllPlugin({ // 打包成的 DLL 库的名称 name: 'dll_[name]', // 为打包成的 DLL 库生成 manifest 文件,文件中是各种描述信息。这样当其他的项目引用 DLL 的时候,就可以根据 manifest 找到对应的文件 path: path.resolve(__dirname, './dll/[name].manifest.json') }) ] }
- 运行
webpack
命令进行打包,会发现生成了 DLL 库。
在需要的项目中引入 DLL 库:
-
进入其他的项目中。
-
安装 react 和
react-dom
:npm install react reatc-dom
。即使引用 DLL 库也需要安装 react 和
react-dom
,否则的话在代码中 import 引用的时候,会因为在node_modules
下找不到而报错。不过引用 DLL 库之后,打包的时候就不会再打包 react 和reatc-dom
了。 -
新建
src/index.js
文件,并编写代码。// src/index.js import React from 'react' import ReactDom from 'react-dom'
-
在
webpack.config.js
中进行配置。这一步的目的只是为了将 react 和reatc-dom
分割打包,方便后续能够明确查看出引用 DLL 库是否有生效。module.exports = { optimization: { splitChunks: { chunks: "all" } }, }
-
运行
webpack
命令进行打包,会发现 react 和reatc-dom
被打包为了一个单独的文件。
-
将打包好的 React DLL 库直接复制粘贴到该项目下。
-
安装 HtmlWebpackPlugin 插件:
npm install html-webpack-plugin --save-dev
。 -
安装 AddAssetHtmlWebpackPlugin 插件:
npm install add-asset-html-webpack-plugin --save-dev
。 -
在
webpack.config.js
配置文件中进行配置。const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const webpack = require('webpack') const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin') module.exports = { // 此处配置只是为了能明确看出 DLL 库生效了,react 和 react-dom 确实没有被单独打包 optimization: { splitChunks: { chunks: "all" } }, plugins: [ // 通过 HtmlWebpackPlugin 插件自动生成 HTML 文件 new HtmlWebpackPlugin(), // 通过 DllReferencePlugin 插件告知 Webpack 要引用 DLL 库,就不会再单独打包可以被 DLL 库替代的包了 new webpack.DllReferencePlugin({ // 要引用的 DLL 库的 manifest 文件的路径 manifest: path.resolve(__dirname, './dll/react.manifest.json'), // manifest 文件中的路径的请求上下文。根据 manifest 去查找 DLL 库的时候的上下文路径 context: path.resolve(__dirname, './'), }), // 通过 AddAssetHtmlWebpackPlugin 插件将 DLL 库复制到打包输出的文件夹下,并且自动插入到 HTML 中 new AddAssetHtmlWebpackPlugin({ // DLL 库的路径 filepath: path.resolve(__dirname, './dll/dll_react.js'), // 复制到打包输出的文件夹下的路径 outputPath: "auto", }), ] }
-
运行
webpack
命令进行打包,会发现 react 和react-dom
没有被单独打包,dll_react.js
文件被复制到了打包输出的文件夹下并自动引入到了index.html
文件中。