01 构建配置抽离成npm包;
php
复制代码
意义:
通用性: 业务开发者无需关注构建配置 统一团队构建脚本
可维护性:构建配置合理的拆分
质量:冒烟测试 单元测试 持续集成
构建配置管理的可选方案:
1 通过多个配置文件管理不同环境的构建:在package.json文件中进行配置。 项目中默认配置文件,
webpack.config.js, 可以设置开发环境的文件 webpack.dev.js 生产环境 webpack.pro.js
webpack --config webpack.dev.js 开发环境
webpack --config webpack.pro.js 生成环境
2 将构建配置设计成一个库 比如 hjs-webpack Neutrino webpack-blocks等
3 抽成一个工具进行管理 比如 create-react-app
02 构建配置包设计
javascript
复制代码
通过多个配置文件管理不同环境的webpakc配置
基础配置 webpack.base.js
开发环境 webpack.dev.js
生产环境 webpack.pro.js
SSR环境 webpack.ssr.js
抽离成一个npm包统一管理
规范:Git commit日志 README ESLint Semver
质量 冒烟测试 单元测试 测试覆盖率和CI
03 通过webpack-merge合并配置
javascript
复制代码
const merge = require('webpack-merge')
module.exports = merge(baseConfig,devConfig)
合并规则如下:
merge({a:[1],b:5,c:23},{a:[2],b:6,c:40,d:60})
{a:[1,2],b:6,c:40,d:60}
04 目录结构的设计
05 各文件之间的功能
06 构建统计信息,可以查看各个文件打包后的大小
package.json中使用stats
"scripts":{
"build:stats":"webpack --env production --json > stats.json"
}
07 webpack打包的速度分析,分析每个loader和插件打包的速度。
javascript
复制代码
第一步 进行插件的安装:
npm install --save-dev speed-measure-webpack-plugin
第二步 插件的导入
const SpeedMeasureWebpackPlugin = require('speed-measure-webpack-plugin ')
第三步 创建插件的对象
const smp = new SpeedMeasureWebpackPlugin()
第四步 将要导出的配置进行包裹
module.exports = smp.wrap({entry:'',output:'',mode:'',...})
08 webpack打包后分析体积:需要借助webpack-bundle-analyzer;
javascript
复制代码
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
Plugins:[
new BundleAnalyzerPlugin()
]
}
项目在8888端口可以使用可视化的图标查看打包后的体积
09 多进程/多实例:使用thread-loader解析资源,加快打包的速度。
javascript
复制代码
原理:每次webpack解析一个模块,thread-loader会将它及它的依赖分配给worker线程中
module.exports = {
module:{
rules:[
{test:/.js$/,use:[{loader:'thread-loader',options:{workers:3}},'babel-loader']}
]
}
}
10 多进程/多实例 并行压缩代码:使用terser-webpack-plugin开启parallel参数;
javascript
复制代码
const TerserPlugin = require('terser-webpack-plugin')
module.exports = {
optimization:{
minimizer:[
new TerserPlugin({parallel:true})
]
}
}
11 webpack设置分包:预编译资源模块:
javascript
复制代码
思路:将react react-dom redux react-redux 基础包和业务基础包打包成一个文件
方法:使用DLLPlugin 进行分包, DllReferencePlugin对manifest.json引用
第一步 项目根目录下创建一个webpack.dll.js文件
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry:{
library:['react','redux','react-redux','react-dom']
},
output:{
filename:'[name]_[chunkhash].dll.js',
path:path.join(__dirname,'build/library'),
library:'[name]'
},
plugins:[
new webpack.DllPlugin({
name:'[name]_[hash]',
path: path.join(__dirname,'build/library/[name].json')
})
]
}
第二步 package.json文件中
"scripts":{
"dll":"webpack --config webpack.dll.js"
}
第三步 执行 npm run dll :
将会在build / library目录下打包出一个library_xxxx.js的文件
第四步 在webpack.config.js文件中引入打包后的文件
module.exports = {
plugins:[
new webpack.DllReferencePlugin({manifest:require('./build/library/library_xxx.json')})
]
}
12 利用缓存提升二次构建的速度
javascript
复制代码
缓存思路:
1 babel-laoder 开启缓存
2 terser-webpack-plugin 开启缓存
module.exports = {
optimization:{
minimizer:[
new TerserPlugin({parallel:true,cache:true})
]
}
}
3 使用cache-loader 或者 hard-source-webpack-plugin
const HardSoirceWebpackPlugin = require('hard-source-webpack-plugin')
module.exports = {
plugins:[
new HardSoirceWebpackPlugin()
]
}
13 缩小构建目标,减少文件搜索范围
javascript
复制代码
优化 resolve.modules配置 减少模块搜索层级
优化 resolve.mainFields 配置
优化 resolve.extensions 配置
合理使用 alias
module.exports = {
resolve:{
alias:{
// 遇到react直接查找 这个目录下的就可以了
react:path.resolve(__dirname,'./node_module/react/dist/react.main.js'),
},
modules:[path.resolve(__dirname,'node_modules')], 查找依赖的路径
extensions:['.js'],
mainFields:['main']
}
}
14 打包排除没有使用到的css样式
javascript
复制代码
需要purgecss-webpack-plugin结合mini-css-extract-plugin使用
webpack.config.js文件中
const PurgecssWebpackPlugin = require('purgecss-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const PATHS = {src:path.join(__dirname.'src')}
module.exports = {
plugins:[
new PurgecssWebpackPlugin({
paths:glob.sync(`${PATHS.src}/**/*`,{nodir:true})
})
]
}
15 webpack对图片进行压缩
javascript
复制代码
rules: [{test:/.(giflpngljpe?glsvg)$/i,
use:[
'file-loader',
loader: 'image-webpack-loader',
options:{
mozjpeg:{
progressive: true,
quality: 65
}
// optipng.enabled: false will disable optipng
optipng:{
enabled: false,
}
pngquant: {
quality:'65-90',
speed: 4
}
gifsicle: {
interlaced: false,
}
// the webp option will enable WEBP
webp:{
quality:75
}
}
}
}