API参考http://npm.taobao.org/package/webpack-chain
使用链式调用
1、代码更加简洁
2、维护性强
3、编程性强
4、对程序员的业务能力要求高
webpack-chain 简介
链式包装器
引入 webpack-chain 后,我们所有的 webpack 配置通过一个链式包装器便可生成了:
const Config = require('webpack-chain');
const config = new Config();
// 链式生成配置
...
// 导出 webpack 配置对象
export default config.toConfig();
安装webpack-chain
npm install webpack-chain -D 或者 yarn add webpack-chain -D
分离配置文件
目录结构

/**
* @file webpack基本配置文件
*/
'use strict'
const path = require('path')
const Config = require('webpack-chain')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const webpackConfig = new Config()
webpackConfig
.mode(process.env.NODE_ENV)
.target('web') //编译为类浏览器环境里可用
.context(path.resolve(__dirname, '../'))
.entry('app')
.add(`./src/index.js`)
.end()
webpackConfig.output
.path(path.resolve(__dirname, "../dist"))
.filename('[name].js')
.end()
webpackConfig.resolve
.set('symlinks', false) // 将符号链接(symlink)解析到它们的符号链接位置
.extensions
.merge(['.js', '.jsx', '.vue', '.json']) // 自动解析确定的扩展
.end()
.alias
.set('@', path.join(__dirname, '..', 'src'))
.set('vue$', utils.isDev() ? 'vue/dist/vue.esm.js' : 'vue/dist/vue.runtime.esm.js')
// resolveLoader-----------------
webpackConfig.resolveLoader.modules
.add('node_modules')
.add(path.join(__dirname, './loaders'))
//react处理js配置
webpackConfi.module
.rule('compile')
.test(/\.js$/)
.pre()
.include
.add(basePath)
.end()
.use('babel')
.loader('babel-loader?cacheDirectory=true')
.options({
presets: ['es2015', 'react', 'stage-1','babel-polyfill']
})
.end()
.use('react-hot-loader/webpack')
.loader('react-hot-loader/webpack')
.end()
.end()
//处理vue文件
webpackConfig.module
.rule('vue')
.test(/\.vue$/)
.use('vue-loader')
.loader('vue-loader')
.options({
compilerOptions: {
preserveWhitespace: false
}
})
.end()
// 静态资源配置 --------------------
webpackConfig.module
.rule('images')
.test(/\.(png|jpe?g|gif|webp)(\?.*)?$/)
.use('url-loader')
.loader('url-loader')
.options({
limit: 5000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
})
/ svg 不用内联方式
// see https://github.com/facebook/create-react-app/pull/1180
webpackConfig.module
.rule('svg')
.test(/\.(svg)(\?.*)?$/)
.use('file-loader')
.loader('file-loader')
.options({
name: utils.assetsPath('img/[name].[hash:7].[ext]')
})
webpackConfig.module
.rule('fonts')
.test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/i)
.use('url-loader')
.loader('url-loader')
.options(genUrlLoaderOptions('fonts'))
//css文件配置,我这用的是sass
webpackConfig.module
.rule('scss')
.test(/\.scss$/)
.use('css-hot-loader')
.loader('css-hot-loader')
.end()
.use('mini-css-extract-loader')
.loader(devMode ? MiniCssExtractPlugin.loader : 'style-loader')
.end()
.use('css-loader')
.loader('css-loader')
.options({
importLoaders: 2
})
.end()
.use('postcss-loader')
.loader('postcss-loader')
.end()
.use('sass-loader')
.loader('sass-loader')
.end()
.end()
// 插件-------------------------
// 导出html
webpackConfig
.plugin('html')
.use(require('html-webpack-plugin'), [{
filename: 'index.html',
template: './src/index.html',
inject: true
}])
// 复制静态资源
webpackConfig
.plugin('copy-static')
.use(CopyWebpackPlugin, [[
{ from: path.join(__dirname, '../', 'static'), to: config.meshProp('outputRoot') }
]])
// 打包前清除输出目录
if (!utils.isDev()) {
webpackConfig
.plugin('clean')
.use(require('clean-webpack-plugin'))
}
//多线程
webpackConfig
.plugin('HappyPack')
.use(HappyPack,[{
//用id来标识 happypack处理那里类文件
id: 'happyBabel',
//如何处理 用法和loader 的配置一样
loaders: [{
loader: 'babel-loader?cacheDirectory=true',
}],
//共享进程池threadPool: HappyThreadPool 代表共享进程池,即多个 HappyPack 实例都使用同一个共享进程池中的子进程去处理任务,以防止资源占用过多。
threadPool: happyThreadPool,
//允许 HappyPack 输出日志
verbose: true,
}])
//把css提取成单独的css文件
webpackConfig
.plugin('MiniCssExtractPlugin')
.use(MiniCssExtractPlugin, [{
filename: devMode ? 'css/[name].[hash].css' : 'css/[name].css',
chunkFilename: devMode ? 'css/[name].[hash].css' : 'css/[name].css'
}])
module.exports = config.toConfig();
2、webpack.dev.conf.js(webpack基本配置文件)
/**
* @file 开发环境webpack配置文件
*/
'use strict'
const path = require('path')
const webpackConfig = require('./webpack.base.conf')
// 获取本地IP
function getLocalIP () {
let interfaces = os.networkInterfaces()
for(let devName in interfaces){
let iface = interfaces[devName]
for(let i=0;i<iface.length;i++){
let alias = iface[i];
if(alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal){
return alias.address;
}
}
}
return 'localhost'
}
webpackConfig
.mode('development')
webpackConfig.devtool('cheap-module-eval-soure-map')
webpackConfig
.devServer
.hot(true) // 是否支持热替换【热替换有问题,先置为false,保证可以自动刷新页面】
// .inline(true)
.contentBase(path.resolve(__dirname, "../dist"))
.watchContentBase(true)
.host(getLocalIP)
.port(8080)
.compress(false)
.open(true) // 是否自动打开浏览器
.overlay({warnings: false, errors: true}) //页面是否增加遮罩层显示错误信息
webpackConfig.watch(true)
webpackConfig.watchOptions({
aggregateTimeout: 500, //防止重复保存频繁重新编译,500毫秒内重复保存不打包
poll: 1000, //每秒询问的文件变更的次数
ignored: /node_modules/ //忽略不需要坚挺的目录
})
webpackConfig.plugin('HotModuleReplacementPlugin')
.use(webpack.HotModuleReplacementPlugin)
//console.log('>>>>>>>>>>>>>\n', config.toString())
//可以打印出来看看配置的文件格式是什么样子的
module.exports = merge(commonConfig,config.toConfig())
2、webpack.pro.conf.js(webpack基本配置文件)
/**
* @file 生产环境webpack配置文件
*/
'use strict'
const webpackConfig = require('./webpack.base.conf')
const merge = require('webpack-merge')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;//打印出来文件的大小分布情况
webpackConfig.mode('production')
webpackConfig.mode('production')
webpackConfig.entry('pollify')
.add('babel-polyfill')
webpackConfig.devtool('cheap-module-source-map')
const splitConfig = {
vendors: {
name: `vendors`,
minChunks: 2,
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: 'initial'
},
common: {
name: 'common',
minChunks: commonMinChunks,
priority: -20,
chunks: 'initial',
reuseExistingChunk: true
},
async: {
name: 'async-common',
minChunks: 2,
maxAsyncRequests: 3,
priority: -30,
chunks: 'async',
reuseExistingChunk: true
}
}
webpackConfig
.optimization.splitChunks({ name: false, cacheGroups: splitConfig })
webpackConfig.optimization
.minimizer('css')
.use(OptimizeCSSAssetsPlugin, [{ cssProcessorOptions: { safe: true }}]) //压缩css
module.exports = merge(commonConfig, config.toConfig())
总结:大家不妨试试webpack的链式调用,相信大家会发现它的独特之处,鄙人初来乍到,如有错误之处,还请指出,希望能帮到您