調整 webpack 配置最簡單的方式就是在 vue.config.js 中的 configureWebpack 選項提供一個對象:
// vue.config.js
module.exports = {
configureWebpack: {
plugins: [
new MyAwesomeWebpackPlugin()
]
}
}
該對象將會被 webpack-merge 合並入最終的 webpack 配置。
如果你需要基於環境有條件地配置行為,或者想要直接修改配置,那就換成一個函數 (該函數會在環境變量被設置之后懶執行)。該方法的第一個參數會收到已經解析好的配置。在函數內,你可以直接修改配置,或者返回一個將會被合並的對象:
// vue.config.js
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
// 為生產環境修改配置...
} else {
// 為開發環境修改配置...
}
}
}
鏈式操作 (高級)
Vue CLI 內部的 webpack 配置是通過 webpack-chain 維護的。這個庫提供了一個 webpack 原始配置的上層抽象,使其可以定義具名的 loader 規則和具名插件,並有機會在后期進入這些規則並對它們的選項進行修改。
它允許我們更細粒度的控制其內部配置。接下來有一些常見的在 vue.config.js 中的 chainWebpack 修改的例子。
修改 Loader 選項
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
// 修改它的選項...
return options
})
}
}
添加一個新的 Loader
// vue.config.js
module.exports = {
chainWebpack: config => {
// GraphQL Loader
config.module
.rule('graphql')
.test(/\.graphql$/)
.use('graphql-tag/loader')
.loader('graphql-tag/loader')
.end()
// 你還可以再添加一個 loader
.use('other-loader')
.loader('other-loader')
.end()
}
}
替換一個規則里的 Loader
// vue.config.js
module.exports = {
chainWebpack: config => {
const svgRule = config.module.rule('svg')
// 清除已有的所有 loader。
// 如果你不這樣做,接下來的 loader 會附加在該規則現有的 loader 之后。
svgRule.uses.clear()
// 添加要替換的 loader
svgRule
.use('vue-svg-loader')
.loader('vue-svg-loader')
}
}
修改插件選項
// vue.config.js
module.exports = {
chainWebpack: config => {
config
.plugin('html')
.tap(args => {
return [/* 傳遞給 html-webpack-plugin's 構造函數的新參數 */]
})
}
}
你需要熟悉 webpack-chain 的 API 並閱讀一些源碼以便了解如何最大程度利用好這個選項,但是比起直接修改 webpack 配置,它的表達能力更強,也更為安全。
比方說你想要將 index.html
默認的路徑從 /Users/username/proj/public/index.html 改為 /Users/username/proj/app/templates/index.html。通過參考 html-webpack-plugin 你能看到一個可以傳入的選項列表。我們可以在下列配置中傳入一個新的模板路徑來改變它:
// vue.config.js
module.exports = {
chainWebpack: config => {
config
.plugin('html')
.tap(args => {
args[0].template = '/Users/username/proj/app/templates/index.html'
return args
})
}
}
chainWebpack 常用操作快速記憶
configureWebpack
除了上述使用 chainWebpack 來改變 webpack 內部配置外,我們還可以使用 configureWebpack 來進行修改,兩者的不同點在於 chainWebpack 是鏈式修改,而 configureWebpack 更傾向於整體替換和修改。示例代碼如下:
// vue.config.js
module.exports = {
...
// config 參數為已經解析好的 webpack 配置
configureWebpack: config => {
// config.plugins = []; // 這樣會直接將 plugins 置空
// 使用 return 一個對象會通過 webpack-merge 進行合並,plugins 不會置空
return {
plugins: []
}
}
...
}
configureWebpack 可以直接是一個對象,也可以是一個函數,如果是對象它會直接使用 webpack-merge 對其進行合並處理,如果是函數,你可以直接使用其 config 參數來修改 webpack 中的配置,或者返回一個對象來進行 merge 處理。
vue-cli3 已經有的優化
首先,通過官方文檔中的配置參考可以了解到一部分默認配置。通過 vue-inspect
命令,可以查看默認的webpack配置。例如babel-loader
,已經配置了exclude
,並且開啟了cacheDirecorty
,那么不用考慮優化loader了。
其次,從Vue-cli官方文檔中,注意到parallel這個配置有如下說明。
是否為 Babel 或 TypeScript 使用 thread-loader。該選項在系統的 CPU 有多於一個內核時自動啟用,僅作用於生產構建。
此外,webpack4中,mode為production時會自動開啟代碼壓縮和Tree Shaking。