angular项目,推荐使用angular-cli创建打包项目,但是有特殊的需求是就显然不是很灵活。
比如想自定义webpack一些参数的时候就发现无从下手。
这时候你就需要 ng命令的额外参数了
ng build --prod --extra-webpack-config webpack.extra.js
这个参数可以额外指定一个webpack config 文件
如:webpack config webpack.extra.js
文件内容
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin') ;
var ZipPlugin = require('zip-webpack-plugin')
module.exports = {
plugins: [
new HtmlWebpackPlugin({
filename: 'download.html',
excludeChunks: ['main','runtime','styles','polyfills'],
template: './src/download.html',
title: 'test Title'
}),
new ZipPlugin({
path:path.join(__dirname,'zip'),
filename: 'test.zip',
// pathPrefix: 'zip',
}),
],
}
webpack4.x 模块分离 - optimization + splitChunks
在 webpack4.x 中,我们使用 optimization.splitChunks 来分离公用的代码块。
这里说的分离,当然只是针对一些第三方库(一般来自 node_modules),以及我们自己定义的工具库(或公用方法)。不然,还分离啥呢?
不知如何下手?首先,我们来看官网给的一份默认配置:
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
接着,我们再来看下它们的含义:
chunks: 该属性值的数据类型可以是 字符串 或者 函数。如果是字符串,那它的值可能为 initial | async | all 三者之一。默认值的数据类型为 字符串,默认值为 async,但推荐用 all。它表示将哪种类型的模块分离成新文件。字符串参数值的作用分别如下:
initial:表示对异步引入的模块不处理
async:表示只处理异步模块
all:无论同步还是异步,都会处理
minSize: 该属性值的数据类型为数字。它表示将引用模块分离成新代码文件的最小体积,默认为 30000,单位为字节,即 30K(指min+gzip之前的体积)。这里的 30K 应该是最佳实践,因为如果引用模块小于 30K 就分离成一个新代码文件,那页面打开时,势必会多增加一个请求。
maxSize: 该属性值的数据类型为数字。它表示?
minChunks: 该属性值的数据类型为数字。它表示将引用模块如不同文件引用了多少次,才能分离生成新代码文件。默认值为 1
maxAsyncRequests: 该属性值的数据类型为数字,默认值为 5。它表示按需加载最大的并行请求数,针对异步。
maxInitialRequests: 该属性值的数据类型为数字,默认值为 3。它表示单个入口文件最大的并行请求数,针对同步。
automaticNameDelimiter: 该属性值的数据类型为字符串,默认值为 ~。它表示分离后生成新代码文件名称的链接符,比如说 app1.js 和 app2.js 都引用了 utils.js 这个工具库,那么,最后打包后分离生成的公用文件名可能是 xx~app1~app2.js 这样的,即以 ~ 符号连接。
name: 该属性值的数据类型可以是 布尔值 或者 函数(返回值为字符串),其中布尔值得为 true,此时,分离文件后生成的文件名将基于 cacheGroups 和 automaticNameDelimiter。如果设置为 false,则不会进行模块分离。
cacheGroups: 该属性值的数据类型为对象,它的值可以继承 splitChunks.* 中的内容。如果 cacheGroups存在与 splitChunks.* 同名的属性,则 cacheGroups 的属性值则直接覆盖 splitChunks.* 中设置的值。
test: 该属性值的数据类型可以为 字符串 或 正则表达式,它规定了哪些文件目录的模块可以被分离生成新文件。
priority: 该属性值的数据类型可以为数字,默认值为 0。它表示打包分离文件的优先级。
reuseExistingChunk: 该属性值的数据类型可以为布尔值。它表示针对已经分离的模块,不再重新分离。
分离第三方库
要将第三方库分离出来,我们需要调整配置文件,设置 chunks: 'all'
,即表示让所有加载类型的模块在某些条件下都能打包。
分离工具函数
打包中,我们发现,工具函数模块(utils)的源码被分别打包到了两个文件中,这显然是不对。之所以出现这种情况,是因为我们设置了 minSize: 30000,即分离成独立文件的最小体积为 30K,而这里的 工具函数(utils.js)只有几KB,所以,没被分离成单独的文件。
第三方库合并打包并重命名
有的时候,我们希望将所有来自 node_modules 的第三方库都打包到同一个文件中。显然,上面的打包配置并没有满足这个条件。并且,我们还希望可以对打包后的文件名进行重命名。
要完成,只需要在 cacheGroups 设置 name 属性即可。
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
name: 'lib'
},
default: {
minSize: 0,
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
name: 'utils'
}
}
}
}
}
如果你嫌打包后的业务文件大,还可以结合 optimization.runtimeChunk。它可以提取 entry chunk 中的 runtime函数部分,生成一个单独的文件.