const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir)
}
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
.BundleAnalyzerPlugin
// 代码压缩
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
// gzip压缩
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const port = 3000 // dev port
const proxy = {
'/apis/': {
target: 'http://192.168.110.218:2375',
// secure: true,
changeOrigin: true,
pathRewrite: {
// '^/proxy': '/'
}
},
'/wechat/': {
target: 'https://api.weixin.qq.com',
secure: true,
changeOrigin: true,
pathRewrite: {
'^/wechat': '/'
}
},
'/abc/': {
target: 'http://192.168.110.65:1010',
// secure: true,
changeOrigin: true,
pathRewrite: {
'^/abc': '/'
}
}
}
// cdn链接
const cdn = {
// cdn:模块名称和模块作用域命名(对应window里面挂载的变量名称)
externals: {
vue: 'Vue',
vuex: 'Vuex',
vant: 'vant',
'vue-router': 'VueRouter',
axios: 'axios',
moment: 'moment',
'vue-clipboard2': 'VueClipboard'
},
// cdn的css链接
css: [
'https://cdn.jsdelivr.net/npm/vant@2.12/lib/index.css'
],
// cdn的js链接
js: [
'https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js',
'https://cdn.jsdelivr.net/npm/vuex@3.1.2/dist/vuex.min.js',
'https://unpkg.com/vue-router@3.2.0/dist/vue-router.min.js',
'https://cdn.jsdelivr.net/npm/vant@2.12/lib/vant.min.js',
'https://cdn.jsdelivr.net/npm/axios@0.21.1/dist/axios.min.js',
'https://cdn.jsdelivr.net/npm/moment@2.18.1/min/moment.min.js',
'https://cdn.jsdelivr.net/npm/vue-clipboard2@0.3.1/dist/vue-clipboard.min.js'
]
}
module.exports = {
publicPath: process.env.NODE_ENV === 'development' ? '/' : '/qsbwechat/',
outputDir: 'qsbwechat',
assetsDir: 'static',
indexPath: 'index.html',
// filenameHashing: true, // 默认在生成的静态资源文件名中包含hash以控制缓存.
lintOnSave: process.env.NODE_ENV === 'development', // 是否在开发环境下通过eslint-loader在每次保存时lint代码(在生产构建时禁用 eslint-loader).
runtimeCompiler: false, // 是否使用包含运行时编译器的Vue构建版本.
transpileDependencies: [], // Babel显式转译列表.
productionSourceMap: process.env.NODE_ENV === 'development', // 如果你不需要生产环境的source map,可以将其设置为 false 以加速生产环境构建.
crossorigin: '', // 设置生成的HTML中<link rel="stylesheet">和<script>标签的crossorigin属性(注:仅影响构建时注入的标签).
integrity: false, // 在生成的HTML中的<link rel="stylesheet">和<script>标签上启用Subresource Integrity(SRI).
devServer: {
// 所有webpack-dev-server的选项都支持.
proxy: proxy,
port: port, // 端口
disableHostCheck: true // 解决域名访问本地运行出现 Invalid Host Header 的问题
},
css: {
// requireModuleExtension: false, // 当为true时,css文件名可省略module默认为false.
extract: process.env.NODE_ENV !== 'development', // 默认生产环境下是true,开发环境下是false.
sourceMap: false, // 是否为CSS开启source map.设置为true之后可能会影响构建的性能.
loaderOptions: { // 向CSS相关的loader传递选项(支持:css-loader postcss-loader sass-loader less-loader stylus-loader).
less: {
// 若 less-loader 版本小于 6.0,请移除 lessOptions 这一级,直接配置选项。
// lessOptions: {
// modifyVars: {
// // 直接覆盖变量
// 'text-color': '#111',
// 'border-color': '#eee',
// 'button-primary-background-color': '#d7b759'
// // // 或者可以通过 less 文件覆盖(文件路径为绝对路径)
// // hack: `true; @import "your-less-file-path.less";`
// }
// }
}
}
},
// 对内部的webpack配置(比如修改、增加Loader选项)(链式操作).
chainWebpack: config => {
console.log('chainWebpack',config);
if (process.env.NODE_ENV !== 'development') {
// const analyzer = new BundleAnalyzerPlugin({
// analyzerPort: 9999
// })
// config.plugin('webpack-bundle-analyzer').use(analyzer)
// csshansh
config.plugin('extract-css').tap(args => [{
filename: `css/[name].[contenthash:8].css`,
chunkFilename: `css/[name].[contenthash:8].css`
}])
// ============注入cdn start============
config.plugin('html').tap(args => {
// 生产环境或本地需要cdn时,才注入cdn
args[0].cdn = cdn
return args
})
}
config.resolve.alias
.set('@', resolve('src'))
.set('Sass', resolve('src/assets/sass'))
.set('Img', resolve('src/assets/images'))
.set('V', resolve('src/views'))
config.module.rules.delete('svg')
config.module
.rule('svg-smart')
.test(/\.svg$/)
.include.add(resolve('src/assets/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
},
// 如果这个值是一个对象,则会通过 webpack-merge 合并到最终的配置中.
// 如果你需要基于环境有条件地配置行为,或者想要直接修改配置,那就换成一个函数(该函数会在环境变量被设置之后懒执行).该方法的第一个参数会收到已经解析好的配置.在函数内,你可以直接修改配置,或者返回一个将会被合并的对象.
configureWebpack: config => {
// 用cdn方式引入,则构建时要忽略相关资源
if (process.env.NODE_ENV !== 'development') {
config.externals = cdn.externals
config.output.filename = `js/[name].[chunkhash:8].js`
config.output.chunkFilename = `js/[name].[chunkhash:8].js`
// 代码压缩
config.plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
// 生产环境自动删除console
compress: {
// warnings: false, // 若打包错误,则注释这行
drop_debugger: true,
drop_console: true,
pure_funcs: ['console.log']
}
},
sourceMap: false,
parallel: true
})
)
// gzip压缩
const productionGzipExtensions = ['html', 'js', 'css']
config.plugins.push(
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' + productionGzipExtensions.join('|') + ')$'
),
threshold: 10240, // 只有大小大于该值的资源会被处理 10240
minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
deleteOriginalAssets: false // 删除原文件
})
)
// 公共代码抽离
config.optimization = {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'all',
test: /node_modules/,
name: 'vendor',
minChunks: 1,
maxInitialRequests: 5,
minSize: 0,
priority: 100
},
common: {
chunks: 'all',
test: /[\\/]src[\\/]js[\\/]/,
name: 'common',
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
priority: 60
},
styles: {
name: 'styles',
test: /\.(sa|sc|c)ss$/,
chunks: 'all',
enforce: true
},
runtimeChunk: {
name: 'manifest'
}
}
}
}
}
config.performance = {
// hints: 'warning', // 警告 webpack 的性能提示
// maxEntrypointSize: 50000000, // 入口起点的最大体积
// maxAssetSize: 30000000, // 生成文件的最大体积
}
}
}