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 portconst 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, // 生成文件的最大体积 } }}