DLL(Dynamic Link Library)動態連結庫在 webpack 中用來將可共享且不常改變的程式碼抽取成公共的庫。
沒有使用 DLL
react
和 react-dom
在 react 專案中是必備的兩個庫,把它們抽取出來單獨打個包。
首先進行安裝 npm install react react-dom --save
在 src 目錄下新建 index.jsx 檔案,編寫 react 程式碼
import React, { Component } from 'react';
export default class App extends Component {
state = {
message: 'hello react ',
};
render() {
return <div>{this.state.message}</div>;
}
}
在一層級的 index.js 中引入 react 元件,並安裝 axios
後使用它來傳送一個請求
import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';
import axios from 'axios';
ReactDOM.render(<App />, document.getElementById('container'));
axios.get('https://httpbin.org/get').then((res) => {
console.log('res', res);
});
react 程式碼需要透過 babel 進行處理,可以參考 這篇文章,在沒有使用 DLL 的時候,第三方庫 react react-dom
和 axios
都被打包到了 702.js 檔案中。
打包DLL庫
如果需要對某些資源單獨打包,就可以使用到 DLL
,新建 webpack.dll.js
檔案,自定義編譯規則,透過 DllPlugin
生成 manifest.json
檔案,其中包含依賴的對映關係。
const { DllPlugin } = require('webpack');
const path = require('path');
module.exports = {
entry: {
react: ['react', 'react-dom'],
},
output: {
filename: './[name].js',
path: path.resolve(process.cwd(), './dll'),
library: '[name]',
},
plugins: [
new DllPlugin({
name: '[name]',
path: path.resolve(__dirname, './dll/manifest.json'),
}),
],
};
執行 npx webapck --config ./webpack.dll.js
後,生成三個檔案,mainfest.json
,react.js
和一個註釋檔案(可透過TerserPlugin去除)
如果此時直接編譯 webpack.config.js
檔案的話,react
和 react-dom
還是會被作為第三方庫和 axios
編譯到一起。
引入DLL庫
雖然已經透過 DLL
將 react
和 react-dom
自行打包了,但是沒有告訴 webpack.config.js
不需要再把這兩者打包到公共的庫中。這時候請出 DllReferencePlugin
來處理。
const { DllReferencePlugin } = require('webpack');
module.exports = {
// 其它配置省略
plugins: [
new DllReferencePlugin({
manifest: path.resolve(process.cwd(), './dll/manifest.json'),
context: path.resolve(process.cwd(), './'),
}),
],
};
此時第三方庫的 js 檔案裡已經沒有了 react
和 react-dom
,檔名由 702.js 變成了 559.js 是因為內容發生了變化。
執行編譯後的 index.html 檔案,發現報錯 react is not defined
,也沒有在頁面中顯示 hello react
的程式碼。
將檔案新增到 html 中
這是因為第三庫打包的 js 檔案中排除了 react
和 react-dom
,自行打包的 react.js
又沒有被引入到 html 檔案中,所以執行的時候就找不到檔案了。
安裝外掛 add-asset-html-webpack-plugin
,透過它來引入檔案到 html 中
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');
module.exports = {
// 其它配置省略
plugins: [
new AddAssetHtmlWebpackPlugin({
filepath: path.resolve(process.cwd(), './dll/react.js'),
outputPath: './auto',
}),
],
};
這樣透過 DLL
編譯的 react.js
檔案就被引入到 html 檔案中,頁面也能正常顯示
總結
使用 DLL
可以自定義打包的內容,分為以下三個步驟。
webpack.dll.js
中使用DllPlugin
生成 mainfest.json 和 js 檔案webpack.config.js
中使用DllReferencePlugin
去 mainfest.json 檔案中找到對映關係,排除不需要打包的庫webpack.config.js
中透過add-asset-html-webpack-plugin
在 html 檔案引入資源
以上是關於使用 DLL
打包的總結, 更多有關 webpack
的內容可以參考我其它的博文,持續更新中~