Webpack the Bundle Split and Code Split the difference and applications

Editor's note: This article is reprinted from the front and Node SF study notes column, reprinted by the author Oliveryoung authorized odd dance magazine.

Before saying this is some vague concept of chunk, and a lot of time online article describes the most dynamic loading of code in separating the focus of the class. The purpose of writing this article also want others to those like me who is not very clear on the concept of children's shoes have a clear understanding. Ado, began to dry!

Let’s Dive in!

Webpack document separating comprises two parts, a Bundle is to separate, a separate code Code:

Bundle splitting: in fact, is to create a number of smaller files, parallel load, to get a better buffer effect; the main role is to make the browser downloaded in parallel, increase download speed. And use the browser cache, only the code is modified, the hash value of the file name will be changed to load again.

Code splitting: load only some users need most, the rest of the code compliance policies lazy loaded; main role is to speed up page loading, not loading unnecessary stuff loaded.

Preparations
during the preparatory work before the document separation, let's write some code:

Entry file src / index.js:

const { getData } = require(’./main’)

const { findMaxIndex } = require(’./math’)

let arr = [1,2,123,21,3,21,321,1]

findMaxIndex(arr)

getData(’./index.html’)

Two dependent modules:

src/main.js:

const axios = require ( 'axios')

const getData = url => {

axios.get(url).then(d => {

    console.log(d.status)

    console.log(d.data.length)

})

}

module.exports = {

getData

}

src/math.js:

const _ = require(‘lodash’)

const findMaxIndex = arr => {

let x = _.max(arr)

let r = Array.prototype.indexOf.call(arr, x)

console.log(r);

}

module.exports = {

findMaxIndex

}

Add a webpack profile webpack.config.js:

const path = require(‘path’)

module.exports = {

mode: 'development',

entry: path.resolve(__dirname, 'src/index.js'),

output: {

    path: path.resolve(__dirname, 'dist'),

    filename: '[name].[contenthash].js'

},

}

Packaging effect before the file separation
before bundle split and code split operation, we look at the effect of the current default package:

All rely are packaged into main.xxx.js go, size is 609k

Start separating operation
Bundle Split
main task is to Bundle Split module and a plurality of reference packet separation, to avoid all rely on a package file

Basic usage
Webpack 4 optimization.splitChunks need to use the configuration:

const path = require(‘path’)

module.exports = {

mode: 'development',

entry: path.resolve(__dirname, 'src/index.js'),

output: {

    path: path.resolve(__dirname, 'dist'),

    filename: '[name].[contenthash].js'

},

optimization: {

    splitChunks: {

        chunks: 'all'

    }

}

}

optimization.splitChunks mean all depend from node_modules of all packaged isolated, this time we look at the packed file is what it looks like:

Increased splitChunks configuration, we third-party modules are packaged into vendors ~ main.xxx.js go, the file size 604k, while import documents main.xxx.js only 7k

Although this third-party modules will be able to go out alone packages to reduce the size of the file entry, but this is still not a small file; this small test project, we used to axios and lodash Both third-party modules, so we hope the two modules should be singled out two separate files, but not all vendors into a go, we continue to configure webpack.config.js:

Each package npm separate out
where we need to use this plugin to webpack.HashedModuleIdsPlugin

Refer to the official documentation ( https://webpack.js.org/plugins/split-chunks-plugin/#optimization-splitchunks )

Directly on the code:

const path = require(‘path’)

const webpack = require(‘webpack’)

module.exports = {

mode: 'development',

entry: path.resolve(__dirname, 'src/index.js'),

plugins: [

    new webpack.HashedModuleIdsPlugin() // 根据模块的相对路径生成 HASH 作为模块 ID

],

output: {

    path: path.resolve(__dirname, 'dist'),

    filename: '[name].[contenthash].js'

},

optimization: {

    runtimeChunk: 'single',

    splitChunks: {

        chunks: 'all', // 默认 async 可选值 all 和 initial

        maxInitialRequests: Infinity, // 一个入口最大的并行请求数

        minSize: 0, // 避免模块体积过小而被忽略

        minChunks: 1, // 默认也是一表示最小引用次数

        cacheGroups: {

            vendor: {

                test: /[\\/]node_modules[\\/]/, // 如果需要的依赖特别小,可以直接设置成需要打包的依赖名称

                name(module, chunks, chcheGroupKey) { // 可提供布尔值、字符串和函数,如果是函数,可编写自定义返回值

                    const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1] // 获取模块名称

                    return `npm.${packageName.replace('@', '')}` // 可选,一般情况下不需要将模块名称 @ 符号去除

                }

            }

        }

    }

}

}

Here we did a few things:

In order to avoid changes in the file hash of each package, we can use the built-in webpack HashedModuleIdsPlugin, avoid file hash changes each packed

MaxInitialRequests and arranged to increase the first Infinity, specifies the maximum number of concurrent requests the document inlet

MinSize minChunks and then set to 0 and 1, respectively, even if the module is very small it is also extracted, and the module reference number 1 should be extracted

And final match the configuration-dependent file name format isolated

In addition, we will run out of time separating the code, this code can also tie InlineManifestWebpackPlugin inserted directly into the HTML file. Here we will set this configuration single, about to run all the chunk of code into a file package

Such Bundle Split basic operation is complete, let us see how it works:

Are dependent on several modules are separated out.

This plug-in will use HtmlWebpackPlugin js code injection html file.

npm i -D html-webpack-plugin

Modify webpack.config.js file:

// profiles introduced this plugin

var HtmlWebpackPlugin = require(‘html-webpack-plugin’);

// …

module.exports = {

// ...

plugins: [

    new HtmlWebpackPlugin(),

    new webpack.HashedModuleIdsPlugin() // 根据模块的相对路径生成 HASH 作为模块 ID

],

// ...

}

Http-server installation or use vscode plug Live Server code into a local server, open the Debug window of the browser into the Network panel:

We can see the parallel load module separated out alone, so a lot faster than loading a large bag alone, then we have to separate the code, load the unnecessary delay in loading modules

Code Split
the code separation is actually only loads the user needs to use part of the code, not necessary for the time being does not load.

Here we use this method to get to require.ensure dependent, will increase the run-time code after this webpack packaged, get this dependence will trigger at a set good condition.

In ES6 we can use Dynamic Imports to replace the above scheme, if the syntax you need to use ES6 babel babel and plug-syntax-Dynamic-plugin Import ( https://babeljs.io/docs/en/babel-plugin- Import-Dynamic-syntax / # installation ), in your browser in order to ensure compatibility, also you need to install polyfill promise, usage similar, direct observation of official documents webpack ( https://webpack.js.org/guides/code -splitting / # Dynamic-Imports )

Modify our code:

const { getData } = require(’./main’)

let arr = [1,2,123,21,3,21,321,1]

getData(’./index.html’)

setTimeout(() => {

require.ensure(['./math'], function(require) {

    const { findMaxIndex } = require('./math')

    console.log(findMaxIndex(arr))

})

}, 3000)

We set a timer, and only in 3000 milliseconds later, the browser will go to request the math module

After compilation, open the Debug panel refresh your browser:

After the page just loaded, the browser will attempt to get above so few modules, because the module is very small quickly loaded the

Around 3500ms, the browser will go to get math module requie.ensure method definition, because math module also contains rely lodash, so this lodash third-party modules will be loaded on demand.

So that we completed the code separate operations, do not require such advantage is the first time the module is loaded, you can defer loaded with the page loading speed. Of course, the above timeout timer can replace the other events, such as clicking a button to trigger the like.

  Dalian Bohai Hospital, mobile.bhnkyy.net

  Dalian abortion hospital mobile.120dlbh.com

Guess you like

Origin blog.csdn.net/qq_42894764/article/details/93735480