原有的vue-cli,create-react-app在项目较大时编译时间过长,扩展性很差。重写了一套,优化了构建速度和体积。主要从如下优化了webpackcss
开启多线程压缩有多种方式,happy-pack/thread-loader/parallel-webpack
等,happy-pack
在webpack3
时很受欢迎,主要是在webpack
compile
后经过happy-pack
建立的线程池分模块构建,处理后从新传到主线程,目前官方已经再也不维护,推荐使用的webpack4
的thread-loader
。在webpack
解析一个模块时, thread-loader
会将它及它的依赖分配到 worker 线程中,添加thread-loader
以下:html
//1. 安装依赖
npm install --save-dev thread-loader (以后方法省略该步骤)
//2. module中引入
module: {
rules: [
{
test: /\.js$/,
include: path.resolve(__dirname, '../src'),
//多线程编译 项目不大不建议使用
use: [{
loader: 'thread-loader',
options: {
workers: 3
}
},
'babel-loader?cacheDirectory=true']
}
]
}
复制代码
一样多种方式: parallel-uglify-plugin/ugilfyjs-wepack-plugin/terser-webpack-plugin ,而terser-webpack-plugin
支持压缩ES6语法。使用一样简单:vue
//安装后添加到optimization中
optimization: {
minimizer: [
new TerserPlugin({
//开启并行压缩,true为默认值,可设数值, 一样项目小不建议使用,可能反而延长时间
parallel: true,
//开启压缩缓存
cache: true
})
],
},
复制代码
使用html-webpack-externals-plugin指定引入包CDNnode
new HtmlWebpackExternalsPlugin({
externals: [
{
module: 'jquery',
entry: '//unpkg.com/jquery@3.2.1/dist/jquery.min.js',
global: 'jQuery',
},
{
module: 'react',
entry: '//unpkg.com/react@16/umd/react.production.min.js',
global: 'React',
},
],
})
复制代码
此方法需手动引入,同时会致使页面打入多个<script>
标签进行引用,对于SplitChunk仍是会对基础包进行分析。项目不大可使用。推荐使用DLLreact
这是webpack自带的神器,此插件专门用于单独的webpack配置中,以建立dll的捆绑包。它建立一个manifest.json文件,DllReferencePlugin使用它来映射依赖项。webpack详情jquery
能够先建立webpack.dll.js
文件,将公共包提出来(如下文件都存在config文件夹,__dirname目录可能补同)webpack
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: {
//将一下包打成library文件
library:[
'react',
'react-dom',
'redux',
'react-redux',
'axios'
],
},
output:{
filename:'[name]_[hash].js',
//路径不要存在dist中,不然会被cleanwebpackplugin清理
path: path.join(__dirname,'../build/library'),
library:'[name]'
},
plugins:[
//使用dll
new webpack.DllPlugin({
name:'[name]_[hash]',
path: path.join(__dirname,'../build/library/[name].json'),
})
]
}
复制代码
在pack.json
中新加一条命令运行:ios
"dll": "webpack --config ./config/webpack.dll.js",
复制代码
run后会产生build文件夹web
在原webpack production
模式下添加vue-cli
plugins:[
new webpack.DllReferencePlugin({
manifest:require(path.resolve(__dirname,'../build/library/library.json')),
})
]
复制代码
会发现速度提高,同时打包体积变小。此时需在编译后的html文件中手动添加library文件夹。可以使用copy-webpack-plugin
和 html-webpack-tags-plugin
实现自动添加:
plugins:[
new HtmlWebpackPlugin(),
new HtmlWebpackTagsPlugin({
//须要引入的文件
tags: [`${require('../build/library/library.json').name}.js`],
//加载末尾
append: false
}),
]
复制代码
注:html-webpack-tags-plugin
必须配合html-webpack-plugin
,而且在此以后引入。同时,该插件彷佛和speed-measure-webpack-plugin
冲突,如果引用了speed-measure-webpack-plugin
建议在构建时暂时关闭。
在production
配置中添加:
plugins:[
new CopyWebpackPlugin([
//目录从项目根文件开始,从复制build/lirary文件到当前,须要更多配置可查询官方
{ from: 'build/library', to: '' },
]),
]
复制代码
此时运行能够自动添加文件。
缓存对于二次编译具备很大的提升。一般有几种方法:
开启babel-loaer
缓存(直接在babel-loader
后添加?cacheDirectory=true
方法1中)
开启terser-webpack-plugin
缓存(方法二中)
使用hard-source-webpack-plugin
提高模块转换阶段缓存
plugins:[
// ...
new HardSourceWebpackPlugin(),
]
复制代码
缩小构建目标,减小每次构建文件查找范围也能提升速度,有如下状况:
// 1. 排除或缩小目录
module: {
rules: [
{
test: /\.js$/,
//只在解析src下文件
include: path.resolve(__dirname, '../src'),
//排除 node_module文件夹,一般不须要同时使用。
exclude: 'node_module',
use: [{
loader: 'thread-loader',
options: {
workers: 3
}
},
'babel-loader?cacheDirectory=true']
}
]
}
//2.resolve模块使用
resolve: {
//合理使用别名,减小搜索层级
alias: {
//import react能够直接找到
"react": path.resolve(__dirname, "../node_module/react/dist/react.min.js"),
},
modules:[path.resolve(__dirname,"../node_module")]
//后缀名,如import 'index'时会自动按extensions顺序查找,可选多个,但查找速度慢,指定为一下数组中类型时,其余类必须写明后缀,不然没法找到
extensions:[.js],
//packjson指定的入口文件
mainFeilds:['main']
}
复制代码
基于Node库的Imagemin
(定制选项,能够引入第三方优化插件,能够处理多种图片格式)
使用:配置image-webpack-loader
快速入口
module:{
rules:[
{
test: /\.(gif|png|jpe?g|svg|blob)$/,
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
}
}
},
],
},
]
}
复制代码
Mac OS 可能因为libpng错误,官方建议安装或更新libpng
brew install libpng
复制代码
若还有错误,可能因为node引发
node rebuild
复制代码
从新编译可能时间长
webpack3
中使用purifyCSS
,已经中止维护,4中可以使用purgecss-webpack-plugin
进行treeshaking
,删除未使用的css;
const PATHS = {
src: path.join(__dirname, '../src')
}
plugins:[
new MiniCssExtractPlugin(),
//必须和mini-css-extract-plugin配合使用
new PurgecssPlugin({
paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }),
}),
]
复制代码
Polyfill通常占用很大,不少时候不是必须的。通常经常使用的方法是使用babel-polyfill
,体积会很大。可使用polyfill-service
按需加载。polyfill-service
主要经过UA来判断该引用哪些polyfill。因此缺点也明显,各大浏览器会伪造UA来抢占,这会形成 service判断困难。
CDN:
除了对项目和速度进行优化,也能够对webpack
展现优化,提升友好性。
plugins:[
// 提示框
new WebpackBuildNotifyerPlugin({
//提示项目名
title: 'project',
suppressSuccess: true
}),
//进度条
new ProgressBarPlugin(),
//仪表盘,看须要
//new DashboardPlugin(),
//错误提示,须要同stats使用
new FriendlyErrorsWebpackPlugin(),
// 体积分析,须要的时候加上,有多种分析插件
// new BundleAnalyzerPlugin(),
]
复制代码