移除插件某些包,减少插件体积
比如说通用的日期库是moment.js,这个库会占用很大的体积,因为当引用这个库的时候,所有的locale文件都被引入,而这些文件甚至在整个库的体积中占了大部分, 要想对此进行优化必须在webpack打包时移除这部分内容
webpack自带的IgnorePlugin插件便会处理进行优化
plugins:[
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]复制代码
以上配置忽略了时间格式化moment.js中的语言包
优化前
优化后
模块化引入 按需导出
我们在引入lodash这种重型的js库的时候,我们可能只需要引用里面部分函数,但是当我们全部引入打包lodash.js体积就会很庞大
优化前
import _ from 'lodash';
console.log(_.map)
//ƒ map(collection,iteratee){var func=isArray(collection)?arrayMap:baseMap;return func(collection,getIteratee(iteratee,3));}复制代码
但是我们如果按需导入 这样就会减少很大体积
优化后
import map from 'lodash/map';
console.log(map)
//ƒ map(collection, iteratee) {
var func = isArray(collection) ? arrayMap : baseMap;
return func(collection, baseIteratee(iteratee, 3));
}复制代码
优化resolve.extensions配置 设置解析文件后缀
设置解析文件后缀,可以加速文件寻找速度
resolve: {
extensions: ['.js', '.json', 'jsx']
}复制代码
优化resolve.modules配置
resolve: {
// 使用绝对路径指明第三方模块存放的位置,以减少搜索步骤
modules: [path.resolve(__dirname,'node_modules')]
}复制代码
优化loader配置 缩小文件搜索范围
由于Loader对文件的转换操作很耗时,所以需要让尽可能少的文件被Loader处理。我们可以通过以下3方面优化Loader配置:
(1)优化正则匹配
(2)通过cacheDirectory选项开启缓存
(3)通过include、exclude来减少被处理的文件。
module: {
rules: [
{
test:/\.js$/,
//babel-loader支持缓存转换出的结果,通过cacheDirectory选项开启
loader:'babel-loader?cacheDirectory',
//只对项目根目录下的src 目录中的文件采用 babel-loader
include: [path.resolve('src')],
//排除 node_modules 目录下的文件,node_modules 目录下的文件都是采用的 ES5 语法,没必要再通过 Babel 去转换
exclude: path.resolve(__dirname, 'node_modules')
}
]
}复制代码
optimization.splitChunks 提取公共代码
Webpack 4 移除了 CommonsChunkPlugin取而代之的是两个新的配置项 optimization.splitChunks 和 optimization.runtimeChunk。
CommonsChunkPlugin
webpack 将多个模块打包之后的代码集合称为 chunk。为了将一些很少变化的常用库(react、redux、lodash)与业务代码分开,或者是一些不同入口共同使用的公共模块,开发者常常需要将它们单独打包,这些都可以通过配置 CommonsChunkPlugin 来实现。
entry: {
app:'./main.js',
vendor: ['react','react-dom']
},
plugins:
new webpack.optimize.CommonsChunkPlugin({names:['vendor']})
]
复制代码
webpack 4 准备通过 optimization.splitChunks 和 optimization.runtimeChunk 属性来简化代码分割的配置
optimization.splitChunks
通过设置 optimization.splitChunks.chunks: "all" 来启动默认的代码分割配置项。
当满足如下条件时,webpack 会自动打包 chunks:
1)当前模块是公共模块(多处引用)或者模块来自 node_modules
2)当前模块大小大于 30kb 如果此模块是按需加载,并行请求的最大数量小于等于 5
3)如果此模块在初始页面加载,并行请求的最大数量小于等于 3
optimization: {
splitChunks: {
chunks: 'all',
name: true,
automaticNameDelimiter: '-', // 模块间的连接符,默认为"~"
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10 // 优先级,越小优先级越高
},
default: { // 默认设置,可被重写
minChunks: 2,
priority: -20,
reuseExistingChunk: true // 如果本来已经把代码提取出来,则重用存在的而不是重新产生
}
}
}
}复制代码
用 Happypack 来加速代码构建
由于有大量文件需要解析和处理,构建是文件读写和计算密集型的操作,特别是当文件数量变多后,Webpack 构建慢的问题会显得严重。
运行在 Node.js 之上的 Webpack 是单线程模型的,也就是说 Webpack 需要处理的任务需要一件件挨着做,不能多个事情一起做。 文件读写和计算操作是无法避免的,那能不能让 Webpack 同一时刻处理多个任务,HappyPack 就能让 Webpack 做到这点,它把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程。
当同时读取多个loader文件资源时,比如`babel-loader`需要 transform 各种jsx,es6的资源文件。在这种同步计算同时需要大量耗费 cpu 运算的过程中,node的单进程模型就无优势了,而 Happypack 就是针对解决此类问题而生的存在
const HappyPack = require('happypack');
module: { rules: [
{
test:/\.js/,
//loader:'babel-loader',
include: [path.resolve('src')],
// 排除 node_modules 目录下的文件,node_modules 目录下的文件都是采用的 ES5 语法,没必要再通过 Babel 去转换
exclude: path.resolve(__dirname, 'node_modules'),
// 把对 .js 文件的处理转交给 id 为 babel 的 HappyPack 实例
loader: 'happypack/loader?id=babel'
}
]
},
plugins:[ new HappyPack({
// 用唯一的标识符 id 来代表当前的 HappyPack 是用来处理一类特定的文件
id: 'babel',
// 如何处理 .js 文件,用法和 Loader 配置中一样
loaders: ['babel-loader?cacheDirectory'],
// ... 其它配置项
})
]
复制代码
未完待续................