This article describes the use of the DllPlugin plugin in Webpack and the use of the AddAssetHtmlPlugin to insert the built JS file into the HTML page.

Demo address

This article project code location: source code address

Welcome to Star!


Introduction to DLLPlugin and DllReferencePlugin

DLLPlugin compiles a library that contains a large number of reusable modules and is not updated frequently. It only needs to be compiled once and then stored in a specified file (here we can call it a dynamically linked library). These modules are not compiled later in the build process, and the DllReferencePlugin is used directly to reference the dynamically linked library code. Therefore, the build speed can be greatly increased. This is typically used with common third-party modules such as React, React -dom, Lodash, and so on. As long as these modules are not updated, these dynamically linked libraries do not need to be recompiled.


Use it in Webpack

Need to plug-in

Webpack already has built-in support for dynamically linked libraries, which need to be used in conjunction with two built-in plug-ins. They are:

  • DllPlugin plugin: used to package individual dynamic link library files
  • DllReferencePlugin: Used to introduce DllPlugin packed dynamic link library files into the main configuration file

Create a project

Find an empty folder, open the command line, and execute the command

Create project directory
$ mkdir webpack-dll-demo

# Initialize package.json file
$ npm init -y 

Create SRC folder
$ mkdir src

Create a public folder
$ mkdir public

Install the plugins you need
$ npm install webpack webpack-cli html-webpacl-plugin clean-webpacl-plugin friendly-errors-webpack-plugin -D

# Install lodash plugin to demonstrate DllPlugin usage
$ npm install lodash
Copy the code

Create the index.html file in the public directory

index.html


      
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Use of Webpak DllPlugin</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>
Copy the code

Create the index.js file in the SRC directory

index.js

import { join } from 'lodash';

function createSpan(){
    const element = document.createElement('span');
    element.innerHTML = join(['Hello'.'DllPlugin'].', ');
    return element;
}

document.querySelector('#root').appendChild(createSpan());
Copy the code

Current project directory structure

webpack-prod-demo
|- /public
  |- index.html
|- /src
  |- index.js
|- package.json
Copy the code

Use the DllPlugin and DllReferencePlugin (in three steps)

Write a configuration file specifically to build the dynamic link library (using DllPlugin)

webpack_dll.config.js

const path = require('path');
const webpack = require('webpack');
const CleanWebpaclPlugin = require('clean-webpack-plugin');
const FirendlyErrorePlugin = require('friendly-errors-webpack-plugin');

module.exports = {
    mode: 'production'.entry: {
        // Compile the lodash module as an entry to the dynamic link library
        lodash: ['lodash']},output: {
        // Specify the directory where the build file resides
        // Since the dist folder is cleared every time you pack the production environment, I put them in the public folder
        path: path.resolve(__dirname, 'public/vendor'),
        // Specify a file name
        filename: '[name].dll.js'.// The name of the global variable used to store the dynamically linked library, for example lodash_dll_lib
        // This name needs to correspond to the value of the name attribute in the DllPlugin plugin
        _dll_lib is used to prevent global variable collisions
        library: '[name]_dll_lib'
    },
    plugins: [
        new CleanWebpaclPlugin(['vendor'] and {root: path.resolve(__dirname, 'public')}),new FirendlyErrorePlugin(),
        
        / / access DllPlugin
        new webpack.DllPlugin({
            // The name of the manifest.json file that describes the output of the dynamic link library
            // Since the dist folder is cleared every time you pack the production environment, I put them in the public folder
            path: path.join(__dirname, 'public'.'vendor'.'[name].manifest.json'),
            // The global variable name of the dynamically linked library needs to be the same as that in output.library
            // The value of this field is the value of the name field in the output manifest.json file
            // For example, lodash.manifest.json has "name": "lodash_dll_lib"
            name: '[name]_dll_lib'}})]Copy the code

2. Write a configuration file to package the project (using the DllReferencePlugin)

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const CleanWebpaclPlugin = require('clean-webpack-plugin');
const FirendlyErrorePlugin = require('friendly-errors-webpack-plugin');

module.exports = {
    mode: 'production'.devtool: 'source-map'.entry: './src/index.js'.output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'build-[hash:5].js'
    },
    plugins: [
        new HTMLWebpackPlugin({
            title: 'Use of the Webpak DllPlugin'.template: './public/index.html'
        }),
        new CleanWebpaclPlugin(['dist']),
        new FirendlyErrorePlugin(),
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('production')}),// Tell Webpack which dynamic link libraries are used
        new webpack.DllReferencePlugin({
            // Describes the file contents of the Lodash dynamic link library
            manifest: require('./public/vendor/lodash.manifest.json')]}})Copy the code

3. Introduce dynamic link libraries in index. HTML files

Because dynamic link libraries are compiled only once and then not compiled, reusable modules are packaged into dynamic link libraries, so they are no longer included in the index.js file of the entry, so they are introduced separately in index.html.

index.html


      
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Use of Webpak DllPlugin</title>
</head>
<body>
    <div id="root"></div>
    <script src=".. /public/vendor/lodash.dll.js"></script>
</body>
</html>
Copy the code

Note: SINCE the dist file will be cleaned up when the project is packaged, I put the generated dynamic link library in the public directory, so here is the introduction of the public dynamic link library.

We add two directives to package.json:

  • Build: Package the project
  • Build: DLL: builds a dynamic link library

package.json

. "scripts": { "build": "webpack --config webpack.config.js", "build:dll": "webpack --config webpack_dll.config.js" } ...Copy the code

run

According to the three steps described above, the use of DLLS is over. Now let’s run it and see what happens.

Open the command line and run the command

# create dynamic link library, only need to run this command once, later packaging projects do not need to execute this command
$ npm run build:dll

# Package projects
$ npm run build
Copy the code

Open the index.html file in the dist folder in your browser and you will see: Hello, DllPlugin. The project configuration is successful.

What does the DllPlugin and DllReferencePlugin do

After running the NPM run build: DLL command, you can see that there is an extra vendor folder in the public directory of the project, and you can see that it contains two files:

  • lodash.dll.jsIt containslodashThis is the loDash module
  • lodash.manifest.jsonAlso generated by DllPlugin to describe which modules are included in the dynamic link library file

lodash.dll.js

var lodash_dll_lib=...  // There is too much code here
Copy the code

lodash.manifest.json

{"name":"lodash_dll_lib"."content": {"./node_modules/lodash/lodash.js": {"id":1."buildMeta": {"providedExports":true}},"./node_modules/webpack/buildin/global.js": {"id":2."buildMeta": {"providedExports":true}},"./node_modules/webpack/buildin/module.js": {"id":3."buildMeta": {"providedExports":true}}}}
Copy the code

After comparison, it can be understood:

  • A dynamic link library file contains code for a number of modules stored in an array with the array’s index number as its ID. It also exposes itself globally through the lodash_dll_lib variable, which means that window.lodash_dll_lib can access the modules it contains

  • The manifest.json file clearly describes which modules are contained in its corresponding DLL. js file, as well as the path and ID of each module

At this point, the use and configuration of the Dll is complete. But here’s another thing to think about: Currently, the project works fine, but now the dynamic link library is stored in the public directory. If we need to package the project online, how can we make the dynamic link library automatically stored in the dist directory? How do we automatically introduce dynamic link libraries into our index. HTML file without manually adding scripts? If you are interested, read on to see the use of the Add-asset-html-webpack-plugin.


Add – asset – HTML – webpack – the use of the plugin

As mentioned above, although the use and configuration of DLLS are ok, it is not satisfactory. When packaging, the Dll cannot be automatically stored in the dist folder, nor can it automatically introduce the Dll script into the HTML file. So this is where the Add-asset-html-webpack-plugin comes in.

Installing a plug-in

$ npm install add-asset-html-webpack-plugin -D
Copy the code

use

Use it in the webpack.config.js file

webpack.config.js

. ;const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');

module.exports = { ... .plugins: [...// The plugin will add the given JS or CSS file to the webPack configuration file and put it into the resource list. The HTML WebPack plugin will inject the generated HTML.
        new AddAssetHtmlPlugin([
            {
                // The absolute path to the file to be added to the compilation, along with the generated HTML file. Globby strings are supported
                filepath: require.resolve(path.resolve(__dirname, 'public/vendor/lodash.dll.js')),
                // File output directory
                outputPath: 'vendor'.// Public path for script or link tags
                publicPath: 'vendor')]}}]Copy the code

At this point, you can remove the script manually imported from the index.html file


      
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Use of Webpak DllPlugin</title>
</head>
<body>
    <div id="root"></div>
    <! Delete the following line to import script -->
-    <script src=".. /public/vendor/lodash.dll.js"></script>
</body>
</html>
Copy the code

Run the project

Open the command line and execute the following command:

# Package projects
$ npm run build
Copy the code
  • Now look at the dist folder in the project, you can see that js files in the Vendor folder in the public directory have been automatically copied to the vendor folder in the dist directory

  • Open the index.html file in the Dist folder and you can see that the generated script file has been automatically imported

  • Open index.html in your browser and you can see that ‘Hello, DllPlugin’ also works

For more information about add-asset-html-webpack-plugin, see github address: AddAssetHtmlPlugin


conclusion

  • The use of Dll dynamic link libraries can speed up project construction, because heavily reused modules can be compiled in advance and only need to be compiled once, and then the use of these modules will not be re-compiled later in the development

  • The DllPlugin and DllReferencePlugin need to be used together

    • DllPlugin is used to package individual dynamic link library files and generate corresponding master manifest files describing which modules are included in the dynamic link library
    • The DllReferencePlugin is used to introduce the DllPlugin plugin wrapped dynamic link library file into the main manifest file
  • You can use AddAssetHtmlPlugin to copy the generated dynamic link library file to the export folder, and HTMLWebpackPlugin will automatically inject the script file into the generated HTML file

  • ** If you want to test the build speed, you can comment the DllReferencePlugin and AddAssetHtmlPlugin in webpack.config.js, run the NPM run build, and observe the packaging time; Then open the comment, run NPM run build, observe the packaging time, compare and find the difference

For the first time, run NPM Run Build: DLL to generate the dynamic link library.

This article Demo address: source address. Welcome to Star!