webpack-chain是什麼?經過鏈式的方式修改webpack的配置
。css
列出一些本人經常使用的使用webpack-chain的方式修改webpack配置. 整個文件爲:html
//vue.config.js
module.exports={
chainWebpack:(webpackConfig)=>{
}
}
複製代碼
chainWebpack: config => {
config.entryPoints.clear() // 會把默認的入口清空
config.entry('main').add('./src/main.js')//新增入口
config.entry('routes').add('./src/app-routes.js')//新增入口
config.output
.path("dist")
.filename("[name].[chunkhash].js")
.chunkFilename("chunks/[name].[chunkhash].js")
.libraryTarget("umd")
.library();
}
// 其他的output配置
config.output
.auxiliaryComment(auxiliaryComment)
.chunkFilename(chunkFilename)
.chunkLoadTimeout(chunkLoadTimeout)
.crossOriginLoading(crossOriginLoading)
.devtoolFallbackModuleFilenameTemplate(devtoolFallbackModuleFilenameTemplate)
.devtoolLineToLine(devtoolLineToLine)
.devtoolModuleFilenameTemplate(devtoolModuleFilenameTemplate)
.filename(filename)
.hashFunction(hashFunction)
.hashDigest(hashDigest)
.hashDigestLength(hashDigestLength)
.hashSalt(hashSalt)
.hotUpdateChunkFilename(hotUpdateChunkFilename)
.hotUpdateFunction(hotUpdateFunction)
.hotUpdateMainFilename(hotUpdateMainFilename)
.jsonpFunction(jsonpFunction)
.library(library)
.libraryExport(libraryExport)
.libraryTarget(libraryTarget)
.path(path)
.pathinfo(pathinfo)
.publicPath(publicPath)
.sourceMapFilename(sourceMapFilename)
.sourcePrefix(sourcePrefix)
.strictModuleExceptionHandling(strictModuleExceptionHandling)
.umdNamedDefine(umdNamedDefine)
複製代碼
const path = require('path');
function resolve (dir) {
return path.join(__dirname, dir)
}
module.exports = {
lintOnSave: true,
chainWebpack: (config)=>{
config.resolve.alias
.set('@$', resolve('src'))
.set('assets',resolve('src/assets'))
.set('components',resolve('src/components'))
.set('layout',resolve('src/layout'))
.set('base',resolve('src/base'))
.set('static',resolve('src/static'))
.delete('base') // 刪掉指定的別名
// .clear() 會把全部別名都刪掉
}
}
複製代碼
devServe的配置,請見這裏前端
chainWebpack: config => {
config.devServer.port(8888)
.open(true)
.proxy({'/dev': {
target: 'http://123.57.153.106:8080/',
changeOrigin: true,
pathRewrite: {
'^/dev': ''
}
}
})
}
// chain其餘隊proxy的配置
config.devServer
.bonjour(bonjour)
.clientLogLevel(clientLogLevel)
.color(color)
.compress(compress)
.contentBase(contentBase)
.disableHostCheck(disableHostCheck)
.filename(filename)
.headers(headers)
.historyApiFallback(historyApiFallback)
.host(host)
.hot(hot)
.hotOnly(hotOnly)
.https(https)
.inline(inline)
.info(info)
.lazy(lazy)
.noInfo(noInfo)
.open(open)
.openPage(openPage)
.overlay(overlay)
.pfx(pfx)
.pfxPassphrase(pfxPassphrase)
.port(port)
.progress(progress)
.proxy(proxy)
.public(public)
.publicPath(publicPath)
.quiet(quiet)
.setup(setup)
.socket(socket)
.staticOptions(staticOptions)
.stats(stats)
.stdin(stdin)
.useLocalIp(useLocalIp)
.watchContentBase(watchContentBase)
.watchOptions(watchOptions)
複製代碼
插件相關配置請見這裏vue
添加插件node
// 添加API
config
.plugin(name)
.use(WebpackPlugin, args)
// 一個例子
const fileManager = require("filemanager-webpack-plugin");
...
//注意:use部分,不能使用new的方式建立插件實例
webpackConfig.plugin("zip").use(fileManager, [
{
onEnd: {
archive: [
{
source: "dist",
destination: zipName
}
]
}
}
]);
複製代碼
修改插件參數react
// 可使用tap方式,修改插件參數
config
.plugin(name)
.tap(args => newArgs)
// 一個例子
config
.plugin('env')
//使用tag修改參數
.tap(args => [...args, 'SECRET_KEY']);
複製代碼
修改插件初始化webpack
config
.plugin(name)
.init((Plugin, args) => new Plugin(...args));
複製代碼
移除插件git
chainWebpack: config => {
config.plugins.delete('prefetch')
// 移除 preload 插件
config.plugins.delete('preload');
}
複製代碼
有時候須要xx插件在aa插件以前
調用。github
config
.plugin(name)
.before(otherName)
// 一個例子:ScriptExtWebpackPlugin插件在HtmlWebpackTemplate插件前調用
config
.plugin('html-template')
.use(HtmlWebpackTemplate)
.end()
.plugin('script-ext')
.use(ScriptExtWebpackPlugin)
.before('html-template');
複製代碼
有時候須要xx插件在aa插件以後
調用。web
config
.plugin(name)
.after(otherName)
// 一個例子html-template在script-ext以後調用
config
.plugin('html-template')
.after('script-ext')
.use(HtmlWebpackTemplate)
.end()
.plugin('script-ext')
.use(ScriptExtWebpackPlugin);
複製代碼
配置請見webpack參數:performance
config.performance
.hints(hints)//false | "error" | "warning"。打開/關閉提示
.maxEntrypointSize(maxEntrypointSize)//入口起點表示針對指定的入口,對於全部資源,要充分利用初始加載時(initial load time)期間。此選項根據入口起點的最大致積,控制 webpack 什麼時候生成性能提示。默認值是:250000
.maxAssetSize(maxAssetSize)//資源(asset)是從 webpack 生成的任何文件。此選項根據單個資源體積,控制 webpack 什麼時候生成性能提示。默認值是:250000
.assetFilter(assetFilter)//此屬性容許 webpack 控制用於計算性能提示的文件
複製代碼
config.optimization
.concatenateModules(concatenateModules)
.flagIncludedChunks(flagIncludedChunks)
.mergeDuplicateChunks(mergeDuplicateChunks)
.minimize(minimize) //boolean,默認爲true,是否開啓壓縮
.namedChunks(namedChunks)
.namedModules(namedModules)
.nodeEnv(nodeEnv)
.noEmitOnErrors(noEmitOnErrors)
.occurrenceOrder(occurrenceOrder)
.portableRecords(portableRecords)
.providedExports(providedExports)
.removeAvailableModules(removeAvailableModules)
.removeEmptyChunks(removeEmptyChunks)
.runtimeChunk(runtimeChunk)
.sideEffects(sideEffects)
.splitChunks(splitChunks)//object:代碼分割。默認狀況下,webpack v4 +爲動態導入的模塊提供了開箱即用的新通用塊策略。
.usedExports(usedExports)
//舉個例子
config.optimization.splitChunks({
chunks: "async", // 必須三選一: "initial" | "all"(推薦) | "async" (默認就是async)
minSize: 30000, // 最小尺寸,30000
minChunks: 1, // 最小 chunk ,默認1
maxAsyncRequests: 5, // 最大異步請求數, 默認5
maxInitialRequests : 3, // 最大初始化請求書,默認3
automaticNameDelimiter: '~',// 打包分隔符
name: function(){}, // 打包後的名稱,此選項可接收 function
cacheGroups:{ // 這裏開始設置緩存的 chunks
priority: 0, // 緩存組優先級
vendor: { // key 爲entry中定義的 入口名稱
chunks: "initial", // 必須三選一: "initial" | "all" | "async"(默認就是async)
test: /react|lodash/, // 正則規則驗證,若是符合就提取 chunk
name: "vendor", // 要緩存的 分隔出來的 chunk 名稱
minSize: 30000,
minChunks: 1,
enforce: true,
maxAsyncRequests: 5, // 最大異步請求數, 默認1
maxInitialRequests : 3, // 最大初始化請求書,默認1
reuseExistingChunk: true // 可設置是否重用該chunk
}
}
});
複製代碼
webpack4.x默認使用的TerserPlugin作代碼壓縮。
//使用
config.optimization.minimizer.use(WebpackPlugin,args);
//刪除
config.optimization.minimizers.delete(name)
// 一個例子
config.optimization
.minimizer('css')
.use(OptimizeCSSAssetsPlugin, [{ cssProcessorOptions: { safe: true } }])
// Minimizer plugins can also be specified by their path, allowing the expensive require()s to be
// skipped in cases where the plugin or webpack configuration won't end up being used.
config.optimization
.minimizer('css')
.use(require.resolve('optimize-css-assets-webpack-plugin'), [{ cssProcessorOptions: { safe: true } }])
//是要tap修改插件參數
config.optimization
.minimizer('css')
.tap(args => [...args, { cssProcessorOptions: { safe: false } }])
複製代碼
首先請先了解一下webpack如何配置loader. 官網連接
config.module
.rule(name)
.use(name)
.loader(loader)
.options(options)
// 一個例子
config.module
.rule('graphql')
.test(/\.graphql$/)
.use('graphql-tag/loader')
.loader('graphql-tag/loader')
.end()
// 若是是非webpack-chain的話
module:{
rules:[
{
test:/\.graphql$/,
use::[
{
loader:"graphql-tag/loader"
}
]
}
]
}
複製代碼
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
// 修改它的選項...
return options
})
}
}
複製代碼
注意 對於 CSS 相關 loader 來講,咱們推薦使用
css.loaderOptions
而不是直接鏈式指定 loader。這是由於每種 CSS 文件類型都有多個規則,而 css.loaderOptions 能夠確保你經過一個地方影響全部的規則。
// 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')
}
}
複製代碼
consif.when(condition,truthyFunc,falsyFunc)
// 一個例子,當構建生產包時添加minify插件,不然設置構建類型爲source-map
// devtool請見:https://www.webpackjs.com/configuration/devtool/
config
.when(process.env.NODE_ENV === 'production',
config => config.plugin('minify').use(BabiliWebpackPlugin),
config => config.devtool('source-map')
);
複製代碼
注意 使用toString()
生成的數據,不能直接在webpack
上使用。
config
.module
.rule('compile')
.test(/\.js$/)
.use('babel')
.loader('babel-loader');
config.toString();
/*
{
module: {
rules: [
/* config.module.rule('compile') */
{
test: /\.js$/,
use: [
/* config.module.rule('compile').use('babel') */
{
loader: 'babel-loader'
}
]
}
]
}
}
*/
複製代碼
歡迎關注個人公衆號,天天定時推送前端相關知識