[vue]優化並加快vue cli打包的速度
前言
相信大部份使用vue single file做開發的人,幾乎都是使用vue cli的方式,但隨著專案越來越大,依賴的第三方越來越多,速度也就越來越慢了,此篇則是筆者爬了很多文章之後,最後自己成功實做,也確實加快了不少速度,所以筆記下來也供各個讀者參考看看。
導覽
用ParallelUglifyPlugin來取代UglifyJsPlugin
我們都知道javascript或node.js是單線程的,所以cli預設用的就是單線程的Uglify,那我們可以去下載第三方的來加快一點點速度
npm i webpack-parallel-uglify-plugin --D
接著我們到webpack.prod.config.js,修改一下把原本的Uglify改掉,把原本程式碼註解改成如下
// new webpack.optimize.UglifyJsPlugin({
// compress: {
// warnings: false
// },
// sourceMap: true
// }),
new ParallelUglifyPlugin({
cacheDir: '.cache/',
uglifyJS: {
output: { comments: false },
compress: { warnings: false }
}
}),
這部份則需要去自定哪些第三方的package在webpack打包的時候,不要加入編譯的部份,如果我們想要編譯第三方的話,我們則需要另下指令,自行去打包這些第三方的library,首先新增一支webpack.dll.config.js,並輸入如下內容
const path = require("path")
const webpack = require("webpack")
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')
module.exports = {
entry: {
vendor: ['vue/dist/vue.esm.js', 'axios', 'element-ui', 'idb', 'jquery', 'jquery-ui', 'lodash', 'moment',
'vuedraggable', 'vuex']
},
output: {
path: path.join(__dirname, '../static/js'),
filename: '[name].dll.js',
library: '[name]_library'
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, '.', '[name]-manifest.json'),
name: '[name]_library',
context: __dirname
}),
new ParallelUglifyPlugin({
cacheDir: '.cache/',
uglifyJS: {
output: { comments: false },
compress: { warnings: false }
}
})
]
}
接著我們去package.json,新增dll的指令如下
"dll": "webpack --config ./build/webpack.dll.config.js",
此時我們輸入npm run dll的話,就應該會編出一支預先編好的dll,在此我們需得把此檔案放在index.html的所有js的上面就行了,接著我們在webpack.dev.config.js和webpack.prod.config.js加入下面內容
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./vendor-manifest.json')
}),
緊接著執行就可以感受到變快了許多了。
這個也是很簡單,我們使用babel的時候,如果可以做個快取,下次就不會每次都要從無到有的去編譯,這樣也會加快一點點速度,我們只需要在使用babel-loader加入options就行了,請到webpack.base.config.js改成如下
{
test: /\.js$/,
exclude:'/node_modules',
loader: 'babel-loader',
options: {
cacheDirectory: true
},
include: [resolve('src'), resolve('test')]
},
這步其實也能加快很多,廢話不多說就是貼上程式碼示例,但是這邊得特別注意一下,就是url-loader無法支援哦。
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
const HappyPack = require('happypack')
function resolve(dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
entry: {
app: process.env.NODE_ENV === 'development' ? './src/main.js' : './src/main.build.js'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
"pages": resolve('src/pages'),
"components": resolve('src/components'),
"services": resolve('src/services/'),
"utilitys": resolve('src/utilitys'),
"images": resolve('src/assets/images')
}
},
plugins: [
new HappyPack({
id: 'babel-loader',
loaders: [{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}]
}),
new HappyPack({
id: 'vue-loader',
loaders: [{
loader: 'vue-loader'
}]
}),
new HappyPack({
loaders: [{
path: 'vue-loader',
query: {
vueLoaderConfig
}
}]
}),
new HappyPack({
id: 'eslint-loader',
loaders: [{
loader: 'eslint-loader',
options: {
formatter: require('eslint-friendly-formatter')
}
}]
})
],
module: {
rules: [
{
test: /\.(js|vue)$/,
loader: 'happypack/loader?id=eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
exclude: '/node_modules'
},
{
test: /\.vue$/,
loader: 'happypack/loader?id=vue-loader',
exclude: '/node_modules',
options: vueLoaderConfig
},
{
test: /\.js$/,
exclude: '/node_modules',
loader: 'happypack/loader?id=babel-loader',
include: [resolve('src'), resolve('test')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[ext]')
}
}
]
}
}
最後來比較一下優化前和優化後時間的差別吧。
優化前
優化後
結論
經過優化之後增加了不少速度,雖然程式碼也變得複雜了一點點,但是還在控制範圍裡面,如果各位讀者有任何更好的建議,再請告知筆者哦。