我在前幾天的《vue項目打包優化之webpack-parallel-uglify-plugin》一文中提到過happypack,我說它有些雞肋,爲何這麼說呢,若是項目較小,可能打包時間優化的並非太好,甚至可能還會延長打包時間。不過在公司項目中我再使用webpack-parallel-uglify-plugin以後項目打包時間大概在3分鐘左右,在此基礎上使用happypack優化以後,時間縮短了將近一分鐘。javascript
如今我將happypack配置作個記錄和說明,以本身的demo爲例。項目是用vuecli腳手架搭建。css
id: String
用惟一的標識符 id。加載程序使用它來知道它應該與哪一個插件進行通.loaders: Array
用法和 webpack Loader 配置中同樣.threads: Number
表明開啓幾個子進程去處理這一類型的文件。默認爲:3
verbose: Boolean
啓用此選項可將狀態消息從HappyPack記錄到STDOUT,默認是 true。threadPool: HappyThreadPool
表明共享進程池,即多個 HappyPack 實例都使用同一個共享進程池中的子進程去處理任務,以防止資源佔用過多。默認爲:null
verboseWhenProfiling: Boolean
若是您但願HappyPack即便在webpack --profile
運行時仍能生成其輸出,請啓用此選項。默認爲:false
debug: Boolean
啓用此選項可將診斷消息從HappyPack記錄到STDOUT。用於故障排除。默認 false
。npm i happypack -D複製代碼
//"happypack": "^5.0.1",demo中happypack版本
//"webpack": "^3.6.0",demo中webpack版本複製代碼
一、修改webpack.base.conf.js文件vue
const HappyPack = require('happypack');
const os = require('os');
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });複製代碼
提示:因爲HappyPack 對file-loader、url-loader 支持的不友好,因此沒修改相應loader使用。
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.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'),
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'happypack/loader?id=vueLoader',
},
{
test: /\.js$/,
loader: 'happypack/loader?id=babelLoader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
},
plugins:[
new HappyPack({
//用id來標識 happypack處理那裏類文件
id: 'vueLoader',
//如何處理 用法和loader 的配置同樣
loaders: [
{
loader:'vue-loader',
options: vueLoaderConfig
}
],
//共享進程池
threadPool: happyThreadPool,
//容許 HappyPack 輸出日誌
verbose: true,
}),
new HappyPack({
//用id來標識 happypack處理那裏類文件
id: 'babelLoader',
//如何處理 用法和loader 的配置同樣
loaders: [
{
loader:'babel-loader',
}
],
//共享進程池
threadPool: happyThreadPool,
//容許 HappyPack 輸出日誌
verbose: true,
})
]}複製代碼
二、修改utils.js文件java
const HappyPack = require('happypack');
const os = require('os');
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });複製代碼
提示:因爲HappyPack 對less-loader、sass-loader、stylus-loader支持的不友好,因此沒修改相應loader使用。
exports.styleLoaders = function (options) {
const output = []
const plugins = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
if(extension!='less'&&extension!='sass'&&extension!='scss'&&extension!='stylus'&&extension!='styl'){
output.push({
test: new RegExp('\\.' + extension + '$'),
use: [`happypack/loader?id=${extension}Loader`]
})
plugins.push(
new HappyPack({
//用id來標識 happypack處理那裏類文件
id: `${extension}Loader`,
//如何處理 用法和loader 的配置同樣
loaders: loader,
//共享進程池
threadPool: happyThreadPool,
//容許 HappyPack 輸出日誌
verbose: true,
})
)
}else{
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
}
return {output,plugins}
}複製代碼
因爲更改了css的規則,因此須要修改相關引用處的配置node
三、修改webpack.dev.conf.js文件webpack
const styleLoaders= utils.styleLoaders({ sourceMap: config.dev.cssSourceMap,
usePostCSS: true
})複製代碼
const devWebpackConfig = merge(baseWebpackConfig, {plugins:styleLoaders.plugins},{
module: {
rules: styleLoaders.output
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
...
})
複製代碼
四、修改webpack.prod.conf.js文件web
const styleLoaders= utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})複製代碼
const webpackConfig = merge(baseWebpackConfig, {plugins:styleLoaders.plugins},{
module: {
rules: styleLoaders.output
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
...
})複製代碼
TIME!npm