webpack4之splitChunks.name

概要

这个配置用于控制webpack打包时被拆分出来的bundle的名称。

我们来看下官方文档上是怎样描述的:

boolean = truefunction (module, chunks, cacheGroupKey) => stringstring

Also available for each cacheGroup:
splitChunks.cacheGroups.{cacheGroup}.name.

The name of the split chunk. Providing true will automatically
generate a name based on chunks and cache group key.

Providing a string or a function allows you to use a custom name.
Specifying either a string or a function that always returns the same
string will merge all common modules and vendors into a single chunk.
This might lead to bigger initial downloads and slow down page loads.

If you choose to specify a function, you may find the chunk.name and
chunk.hash properties (where chunk is an element of the chunks array)
particularly useful in choosing a name for your chunk.

If the splitChunks.name matches an entry point name, the entry point
will be removed.

It is recommended to set splitChunks.name to false for production
builds so that it doesn’t change names unnecessarily.

上面所说的意思大概如下:

扫描二维码关注公众号,回复: 9675199 查看本文章

该配置的值有三种选择,可以是一个布尔值(true和false),也可以是一个函数(形式如function (module, chunks, cacheGroupKey) => string),又或许是一个单纯的String类型。

当然该配置也可以在缓存组中单独配置,如:splitChunks.cacheGroups.{缓存组的名称}.name。

该配置控制被拆分出来的chunk名称。

如果配置为一个布尔值,比如默认下该配置为true,对于生成的chunk的名称,将会基于打包过程中chunks和缓存组名称自动生成。

你可以通过给该配置配置一个字符串或者函数来自定义定制打包后chunk的名称。如果配置的字符串是静态的或者配置的函数返回的是一个静态的字符串,将会使得被另外单独拆分的所有chunk都被打包到一个单独的文件中,这会导致页面首次加载增加,减慢页面的加载。

如果给该配置赋值为一个函数,你会发现参数中的chunk.name和chunk.hash对于定制打包后生成的name非常方便。(这里所说的chunk是参数chunks参数的某一项,chunks是所有chunk的集合)

如果splitChunks.name匹配到一个入口点名称,打包后生成的bundle中该入口点将会被删除。

我们推荐在生产环境下将splitChunks.name配置成false,这将保证不会不必要地更改名称。

接下来,我们将基于官方给出的介绍提供一系列的案例。

准备工作

  1. 目录
root
——dist(打包之后的文件夹)
——node_modules(下载的包)
——src(项目脚本目录)
————entry(入口点脚本)
————modules(入口点中引入的模块)
——package.json(包管理文件)
——webpack.config.js(webpack配置文件)
  1. webpack配置
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  entry: {
    entry1: './src/entry/entry1.js',
    entry2: './src/entry/entry2.js'
  },
  plugins: [
    new CleanWebpackPlugin()
  ],
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  optimization: {
    splitChunks: {
      chunks: 'initial',
      name: true,
      minSize: 1,
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 1,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  }
  // default config
  // optimization: {
  //   splitChunks: {
  //     chunks: 'async',
  //     minSize: 30000,
  //     minChunks: 1,
  //     maxAsyncRequests: 5,
  //     maxInitialRequests: 3,
  //     automaticNameDelimiter: '~',
  //     automaticNameMaxLength: 30,
  //     name: true,
  //     cacheGroups: {
  //       vendors: {
  //         test: /[\\/]node_modules[\\/]/,
  //         priority: -10
  //       },
  //       default: {
  //         minChunks: 2,
  //         priority: -20,
  //         reuseExistingChunk: true
  //       }
  //     }
  //   }
  // }
}
  1. package.json
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "clean-webpack-plugin": "^3.0.0",
    "webpack": "^4.41.2",
    "webpack-cli": "^3.3.10"
  }
}

案例

  1. demo1
################################
webpack.config.js:

splitChunks.name设为true

################################
modules/add.js:

export default function add (a, b) {
  return a + b
}

################################
modules/subtract.js

export default function subtract (a, b) {
  return a - b
}

################################
entry/entry1.js:

import add from '../modules/add.js'

console.log('index', add(1, 2))

################################
entry/entry2.js:

import subtract from '../modules/subtract'

console.log('index', subtract(1, 2))

打包结果如下:

Hash: 2b419949ee0e8b5f82f1
Version: webpack 4.41.5
Time: 204ms
Built at: 2020/01/27 下午6:37:51
                   Asset       Size  Chunks             Chunk Names
default~entry1.bundle.js  122 bytes       0  [emitted]  default~entry1
default~entry2.bundle.js  123 bytes       1  [emitted]  default~entry2
        entry1.bundle.js   1.47 KiB       2  [emitted]  entry1
        entry2.bundle.js   1.47 KiB       3  [emitted]  entry2
Entrypoint entry1 = default~entry1.bundle.js entry1.bundle.js
Entrypoint entry2 = default~entry2.bundle.js entry2.bundle.js
[0] ./src/entry/entry1.js + 1 modules 122 bytes {0} [built]
    | ./src/entry/entry1.js 68 bytes [built]
    | ./src/modules/add.js 54 bytes [built]
[1] ./src/entry/entry2.js + 1 modules 140 bytes {1} [built]
    | ./src/entry/entry2.js 81 bytes [built]

这个是默认值下的打包结果。

  1. demo2

这次,我们将name配置成静态的字符串

################################
webpack.config.js:

splitChunks.name设为bundle

################################
modules/add.js:

export default function add (a, b) {
  return a + b
}

################################
modules/subtract.js

export default function subtract (a, b) {
  return a - b
}

################################
entry/entry1.js:

import add from '../modules/add.js'

console.log('index', add(1, 2))

################################
entry/entry2.js:

import subtract from '../modules/subtract'

console.log('index', subtract(1, 2))

打包后结果为:

Hash: 91b2729a492df74124e1
Version: webpack 4.41.5
Time: 72ms
Built at: 2020/01/27 下午6:45:15
           Asset       Size  Chunks             Chunk Names
bundle.bundle.js  184 bytes       0  [emitted]  bundle
entry1.bundle.js   1.47 KiB       1  [emitted]  entry1
entry2.bundle.js   1.47 KiB       2  [emitted]  entry2
Entrypoint entry1 = bundle.bundle.js entry1.bundle.js
Entrypoint entry2 = bundle.bundle.js entry2.bundle.js
[0] ./src/entry/entry1.js + 1 modules 122 bytes {0} [built]
    | ./src/entry/entry1.js 68 bytes [built]
    | ./src/modules/add.js 54 bytes [built]
[1] ./src/entry/entry2.js + 1 modules 140 bytes {0} [built]
    | ./src/entry/entry2.js 81 bytes [built]
    | ./src/modules/subtract.js 59 bytes [built]

之前在demo1中被拆分出来的default~entry1.js和default~entry2.js被打包到同一个文件bundle.bundle.js中。

  1. demo3
################################
webpack.config.js:

splitChunks.name设为bundle

################################
modules/add.js:

export default function add (a, b) {
  return a + b
}

################################
modules/subtract.js

export default function subtract (a, b) {
  return a - b
}

################################
modules/module.js

import add from './add'

export default function () {
  console.log(add(3, 4) + 10)
}

################################
entry/entry1.js:

import add from '../modules/module.js'

console.log('index', add(1, 2))

################################
entry/entry2.js:

import subtract from '../modules/subtract'
import add from '../modules/add'

console.log('index', subtract(1, 2) + add(1, 0))

打包后结果为:

Hash: 02717c30530f50f5a05c
Version: webpack 4.41.5
Time: 212ms
Built at: 2020/01/27 下午7:11:25
           Asset       Size  Chunks             Chunk Names
bundle.bundle.js  348 bytes       0  [emitted]  bundle
entry1.bundle.js   1.47 KiB       1  [emitted]  entry1
entry2.bundle.js   1.47 KiB       2  [emitted]  entry2
Entrypoint entry1 = bundle.bundle.js entry1.bundle.js
Entrypoint entry2 = bundle.bundle.js entry2.bundle.js
[0] ./src/modules/add.js 54 bytes {0} [built]
[1] ./src/entry/entry1.js + 1 modules 161 bytes {0} [built]
    | ./src/entry/entry1.js 71 bytes [built]
    | ./src/modules/module.js 85 bytes [built]
[2] ./src/entry/entry2.js + 1 modules 190 bytes {0} [built]
    | ./src/entry/entry2.js 126 bytes [built]
    | ./src/modules/subtract.js 59 bytes [built]

效果是和demo2是一样的。

  1. demo4

基于demo3,如果是一个返回’bundle’字符串的函数,结果又是怎样的呢?

################################
webpack.config.js:

splitChunks.name设为() => 'bundle'

################################
modules/add.js:

export default function add (a, b) {
  return a + b
}

################################
modules/subtract.js

export default function subtract (a, b) {
  return a - b
}

################################
modules/module.js

import add from './add'

export default function () {
  console.log(add(3, 4) + 10)
}

################################
entry/entry1.js:

import add from '../modules/module.js'

console.log('index', add(1, 2))

################################
entry/entry2.js:

import subtract from '../modules/subtract'
import add from '../modules/add'

console.log('index', subtract(1, 2) + add(1, 0))

打包结果如下:

Hash: 02717c30530f50f5a05c
Version: webpack 4.41.5
Time: 203ms
Built at: 2020/01/27 下午7:22:50
           Asset       Size  Chunks             Chunk Names
bundle.bundle.js  348 bytes       0  [emitted]  bundle
entry1.bundle.js   1.47 KiB       1  [emitted]  entry1
entry2.bundle.js   1.47 KiB       2  [emitted]  entry2
Entrypoint entry1 = bundle.bundle.js entry1.bundle.js
Entrypoint entry2 = bundle.bundle.js entry2.bundle.js
[0] ./src/modules/add.js 54 bytes {0} [built]
[1] ./src/entry/entry1.js + 1 modules 161 bytes {0} [built]
    | ./src/entry/entry1.js 71 bytes [built]
    | ./src/modules/module.js 85 bytes [built]
[2] ./src/entry/entry2.js + 1 modules 190 bytes {0} [built]
    | ./src/entry/entry2.js 126 bytes [built]
    | ./src/modules/subtract.js 59 bytes [built]

发现和demo3是一样的效果,也就验证了官方所说的设置成静态字符串和返回静态字符串的函数时,被单独拆分出的chunk将会被打包到同一个文件中。

  1. demo5

官方说过“如果splitChunks.name匹配到一个入口点名称,该入口点将会被删除”,所以我们将splitChunks.name设置成’entry1’会是什么效果呢?

同样我们基于demo1来尝试一下:

################################
webpack.config.js:

splitChunks.name设为entry1

################################
modules/add.js:

export default function add (a, b) {
  return a + b
}

################################
modules/subtract.js

export default function subtract (a, b) {
  return a - b
}

################################
entry/entry1.js:

import add from '../modules/add.js'

console.log('index', add(1, 2))

################################
entry/entry2.js:

import subtract from '../modules/subtract'

console.log('index', subtract(1, 2))

打包结果如下:

Hash: 3102679a393dff2295ee
Version: webpack 4.41.5
Time: 197ms
Built at: 2020/01/27 下午7:32:20
           Asset       Size  Chunks             Chunk Names
entry1.bundle.js  184 bytes       0  [emitted]  entry1
entry2.bundle.js   1.47 KiB       1  [emitted]  entry2
Entrypoint entry2 = entry1.bundle.js entry2.bundle.js
[0] ./src/entry/entry1.js + 1 modules 122 bytes {0} [built]
    | ./src/entry/entry1.js 68 bytes [built]
    | ./src/modules/add.js 54 bytes [built]
[1] ./src/entry/entry2.js + 1 modules 140 bytes {0} [built]
    | ./src/entry/entry2.js 81 bytes [built]
    | ./src/modules/subtract.js 59 bytes [built]

和demo2一样,原来的default~entry1.js和default~entry2.js被打包到同一个文件entry1.bundle.js中。但和demo2不同的是,原来的entry.bundle.js被删除了。

  1. demo6

本次案例同样基于demo2,我们通过function的形式来自定义配置name。

################################
webpack.config.js:

splitChunks.name设为(module, chunks, cacheGroupKey) => { console.log(chunks); return chunks[0].name + 'test' }

################################
modules/add.js:

export default function add (a, b) {
  return a + b
}

################################
modules/subtract.js

export default function subtract (a, b) {
  return a - b
}

################################
entry/entry1.js:

import add from '../modules/add.js'

console.log('index', add(1, 2))

################################
entry/entry2.js:

import subtract from '../modules/subtract'

console.log('index', subtract(1, 2))

打包结果如下:

Hash: 8cb43813051625b1e900
Version: webpack 4.41.5
Time: 92ms
Built at: 2020/01/27 下午8:28:26
               Asset       Size  Chunks             Chunk Names
    entry1.bundle.js   1.47 KiB       0  [emitted]  entry1
entry1test.bundle.js  122 bytes       1  [emitted]  entry1test
    entry2.bundle.js   1.47 KiB       2  [emitted]  entry2
entry2test.bundle.js  123 bytes       3  [emitted]  entry2test
Entrypoint entry1 = entry1test.bundle.js entry1.bundle.js
Entrypoint entry2 = entry2test.bundle.js entry2.bundle.js
[0] ./src/entry/entry1.js + 1 modules 122 bytes {1} [built]
    | ./src/entry/entry1.js 68 bytes [built]
    | ./src/modules/add.js 54 bytes [built]
[1] ./src/entry/entry2.js + 1 modules 140 bytes {3} [built]
    | ./src/entry/entry2.js 81 bytes [built]
  1. demo7

官方提到了建议在生产环境下将配置设为false,我们将mode设为production,并将splitChunks.name设为false,看看打包的结果如何。

同样我们基于demo2:

################################
webpack.config.js:

mode设为production
splitChunks.name设为false

################################
modules/add.js:

export default function add (a, b) {
  return a + b
}

################################
modules/subtract.js

export default function subtract (a, b) {
  return a - b
}

################################
entry/entry1.js:

import add from '../modules/add.js'

console.log('index', add(1, 2))

################################
entry/entry2.js:

import subtract from '../modules/subtract'

console.log('index', subtract(1, 2))

打包结果为:

Hash: 7bd7d270daa2650d639f
Version: webpack 4.41.5
Time: 200ms
Built at: 2020/01/27 下午8:42:18
           Asset       Size  Chunks             Chunk Names
     2.bundle.js  122 bytes       2  [emitted]  
     3.bundle.js  123 bytes       3  [emitted]  
entry1.bundle.js   1.47 KiB       0  [emitted]  entry1
entry2.bundle.js   1.47 KiB       1  [emitted]  entry2

从上面可以看出,当将name设为false时就不会基于打包过程中chunks和缓存组名称生产拆分bundle的名称,而仅仅使用chunk的名称。官方字面意思是“这将保证不会不必要的更改名称”,对于这句话,个人不是很理解,之后通过个人研究再补上或者对此比较了解的小伙伴希望能够指点一下,谢谢。

  1. demo8

上面的案例我们都是建立在chunks设置为initial的情况下,那么对于按需加载的module,该配置也是有效的吗,我们来验证一下。

首先我们以一个在chunks: initial下按需引入module的案例来试验一下:

################################
webpack.config.js:

chunks设为initial
splitChunks.name设为bundle

################################
modules/add.js:

export default function add (a, b) {
  return a + b
}

################################
modules/subtract.js

export default function subtract (a, b) {
  return a - b
}

################################
entry/entry1.js:

import add from '../modules/add.js'

console.log('index', add(1, 2))

################################
entry/entry2.js:

import('../modules/subtract').then(subtract => {
  console.log('index', subtract(2, 1))
})

打包后结果如下:

Hash: dbb88add54eaa55bace0
Version: webpack 4.41.5
Time: 224ms
Built at: 2020/01/27 下午9:43:57
           Asset       Size  Chunks             Chunk Names
     3.bundle.js  164 bytes       3  [emitted]  
bundle.bundle.js  207 bytes       0  [emitted]  bundle
entry1.bundle.js   1.51 KiB       1  [emitted]  entry1
entry2.bundle.js   2.22 KiB       2  [emitted]  entry2
Entrypoint entry1 = bundle.bundle.js entry1.bundle.js
Entrypoint entry2 = bundle.bundle.js entry2.bundle.js
[0] ./src/modules/subtract.js 59 bytes {3} [built]
[1] ./src/entry/entry2.js 90 bytes {0} [built]
[2] ./src/entry/entry1.js + 1 modules 122 bytes {0} [built]
    | ./src/entry/entry1.js 68 bytes [built]
    | ./src/modules/add.js 54 bytes [built]

可以看到的是,webpack只将直接引入的模块打包进一个文件中,而对于按需引入的部分不在处理范围之内。

那么在chunks为async和all情况下呢,结果又是如何呢?经过测试,当chunks为async时,也是没有效果,但是当chunks为all时,原本在name默认值的情况下的default~entry1.js、default~entry2.js,以及按需引入的subtract.js都被打包进同一个文件中,名称为bundle.bundle.js,也就是说该配置仅仅在chunks为all情况下才对按需引入的包有效。(不过,需要注意的是,如果name的赋值形式是function,并根据chunks等信息来自定义name规则时,只对直接引入的部分有效,对按需引入无效,而对于返回一个静态字符串和直接赋值静态字符串是有效的,其他的情况也是有效的)

总结

  • splitChunks.name用于控制webpack打包时被拆分出来的bundle的名称;
  • 该配置的值有三种选择,可以是一个布尔值(true和false),也可以是一个函数(形式如function (module, chunks, cacheGroupKey) => string),又或许是一个单纯的String类型;
  • 该配置也可以在缓存组中单独配置,如:splitChunks.cacheGroups.{缓存组的名称}.name;
  • 如果配置为一个布尔值,比如默认下该配置为true,对于生成的chunk的名称,将会基于打包过程中chunks和缓存组名称自动生成,如果值为false,将会直接使用chunk名称;
  • 你可以通过给该配置配置一个字符串或者函数来自定义定制打包后chunk的名称。如果配置的字符串是静态的或者配置的函数返回的是一个静态的字符串,将会使得被另外单独拆分的所有chunk都被打包到一个单独的文件中,这会导致页面首次加载增加,减慢页面的加载;
  • 如果给该配置赋值为一个函数,我们可以很好地利用参数中的chunk.name和chunk.hash来定制打包后生成的name(这里所说的chunk是参数chunks参数的某一项,chunks是所有chunk的集合);
  • 如果splitChunks.name匹配到一个入口点名称,打包后生成的bundle中该入口点将会被删除;
  • 对于按需引入的模块,仅在chunks为all时有效,并且值得注意的是,如果name的赋值形式是function,并根据chunks等信息来自定义name规则时,只对直接引入的部分有效,对按需引入无效,而对于返回一个静态字符串和直接赋值静态字符串是有效的,其他的情况也是有效的;
  • 官方建议在生产环境时将name设置为false,为了“it doesn’t change names unnecessarily”(这将保证不会不必要地更改名称),具体怎样去理解个人暂时还不清楚;

last(最后)
非常感谢您能阅读完这篇文章,您的阅读是我不断前进的动力。如果上述内容或许有些错误或者有些个人理解比较偏离实际,还望指出,谢谢!!!

对于上面所述,有什么新的观点或发现有什么错误,希望您能指出。

最后,附上个人常逛的社交平台:
知乎:https://www.zhihu.com/people/bi-an-yao-91/activities
csdn:https://blog.csdn.net/YaoDeBiAn
github: https://github.com/yaodebian

个人目前能力有限,并没有自主构建一个社区的能力,如有任何问题或想法与我沟通,请通过上述某个平台联系我,谢谢!!!

发布了80 篇原创文章 · 获赞 91 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/YaoDeBiAn/article/details/104094167
今日推荐