大資料請把文章推給想了解DLL的人

一顆冰淇淋發表於2022-11-24

DLL(Dynamic Link Library)動態連結庫在 webpack 中用來將可共享且不常改變的程式碼抽取成公共的庫。

沒有使用 DLL

reactreact-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-domaxios 都被打包到了 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.jsonreact.js 和一個註釋檔案(可透過TerserPlugin去除)

如果此時直接編譯 webpack.config.js 檔案的話,reactreact-dom還是會被作為第三方庫和 axios 編譯到一起。

引入DLL庫

雖然已經透過 DLLreactreact-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 檔案裡已經沒有了 reactreact-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 的內容可以參考我其它的博文,持續更新中~

相關文章