跳到主要内容

webpack-chain

介绍

webpack-chain 尝试通过提供可链式或顺流式的 API 创建和修改webpack 配置。API的 Key 部分可以由用户指定的名称引用,这有助于 跨项目修改配置方式 的标准化。

关联

Vue-Cli 与 webpack-chain

Vue-ClichainWebpack配置项是通过webpack-chain来维护的。通过配置chainWebpack达到在Vue-Cli中链式配置webpack的目的

// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
// 修改它的选项...
return options
})
}
}

安装

yarn 方式

yarn add --dev webpack-chain

npm 方式

npm install --save-dev webpack-chain

语法

初始化链式对象

const Config = require('webpack-chain');
const config = new Config();

config.entry

// 回到 config.entryPoints : ChainedMap
config.entry(name) : ChainedSet

config
.entry(name)
.add(value)
.add(value)

config
.entry(name)
.clear()

config.output

config.output : ChainedMap

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)

config.plugin

  • 添加插件
config
.plugin(name)
.use(WebpackPlugin, args)

// 例如
config
.plugin('hot')
.use(webpack.HotModuleReplacementPlugin);

// 插件也可以由它们的路径指定,从而允许在不使用插件或webpack配置的情况下跳过昂贵的 require s。
config
.plugin('env')
.use(require.resolve('webpack/lib/EnvironmentPlugin'), [{ 'VAR': false }]);
  • 修改插件
config
.plugin(name)
.tap(args => newArgs)

// 例如
config
.plugin('env')
.tap(args => [...args, 'SECRET_KEY']);
  • 删除插件
config.plugins.delete(name)

config.module

  • 创建
config.module.rules{}.uses : ChainedMap

config.module
.rule(name)
.use(name)
.loader(loader)
.options(options)

// Example

config.module
.rule('compile')
.use('babel')
.loader('babel-loader')
.options({ presets: ['@babel/preset-env'] });
  • 修改
config.module
.rule(name)
.use(name)
.tap(options => newOptions)

// 例如

config.module
.rule('compile')
.use('babel')
.tap(options => merge(options, {
plugins: ['@babel/plugin-proposal-class-properties']
}));

  • 删除
config.module
.rule('eslint').delete();

config.resolve

  • config.resolve
config.resolve : ChainedMap

config.resolve
.cachePredicate(cachePredicate)
.cacheWithContext(cacheWithContext)
.enforceExtension(enforceExtension)
.enforceModuleExtension(enforceModuleExtension)
.unsafeCache(unsafeCache)
.symlinks(symlinks)
  • config.resolve.alias
config.resolve.alias : ChainedMap

config.resolve.alias
.set(key, value)
.set(key, value)
.delete(key)
.clear()
  • config.resolve.modules
config.resolve.modules : ChainedSet

config.resolve.modules
.add(value)
.prepend(value)
.clear()
  • config.resolve.aliasFields
config.resolve.aliasFields : ChainedSet

config.resolve.aliasFields
.add(value)
.prepend(value)
.clear()
  • config.resolve.descriptionFields
config.resolve.descriptionFields : ChainedSet

config.resolve.descriptionFields
.add(value)
.prepend(value)
.clear()
  • config.resolve.extensions
config.resolve.extensions : ChainedSet

config.resolve.extensions
.add(value)
.prepend(value)
.clear()
  • config.resolve.mainFields
config.resolve.mainFields : ChainedSet

config.resolve.mainFields
.add(value)
.prepend(value)
.clear()
  • config.resolve.mainFiles
config.resolve.mainFiles : ChainedSet

config.resolve.mainFiles
.add(value)
.prepend(value)
.clear()

config.devServer

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)

config.performance

config.performance : ChainedMap

config.performance
.hints(hints)
.maxEntrypointSize(maxEntrypointSize)
.maxAssetSize(maxAssetSize)
.assetFilter(assetFilter)

config.optimization

config.optimization : ChainedMap

config.optimization
.concatenateModules(concatenateModules)
.flagIncludedChunks(flagIncludedChunks)
.mergeDuplicateChunks(mergeDuplicateChunks)
.minimize(minimize)
.namedChunks(namedChunks)
.namedModules(namedModules)
.nodeEnv(nodeEnv)
.noEmitOnErrors(noEmitOnErrors)
.occurrenceOrder(occurrenceOrder)
.portableRecords(portableRecords)
.providedExports(providedExports)
.removeAvailableModules(removeAvailableModules)
.removeEmptyChunks(removeEmptyChunks)
.runtimeChunk(runtimeChunk)
.sideEffects(sideEffects)
.splitChunks(splitChunks)
.usedExports(usedExports)

实践

常规写法

module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js'
},
module:{
rules:[
{
test:/\.jpg|png/,
use:{
loader:'url-loader',
}
},
]
},
devServer: {
static:{
directory:path.resolve(__dirname,"public")
},
port: 8090,
open: true,
hot: true,
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
template: './public/index.html',
filename: 'index.html',
title:'学习webpack'
}),
new CleanWebpackPlugin(),
]
};

链式写法

const path = require('path');
const webpack = require('webpack');
const Config = require('webpack-chain');
const config = new Config();
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin');

config.entry('entry').add("./src/index.js").end();
config.output.path(path.resolve(__dirname, 'dist')).filename('index.js').end();
config.module.rule('url').test(/\.jpg|png/).use('url-loader').end();
config.plugin('clean').use(CleanWebpackPlugin).end();
config.plugin('html').use(HtmlWebpackPlugin,[{
template: './public/index.html',
filename: 'index.html',
title:'学习webpack'
}]);
config.plugin('hot').use(new webpack.HotModuleReplacementPlugin()).end();
module.exports=config.toConfig();