vue 配置【详解】 vue.config.js ( 含 webpack 配置 )【转载】
使用 vue-cli 3.x 以上的脚手架创建的 vue 项目不再有 build文件夹,若需要进行相关配置,需在项目目录下新建文件 vue.config.js
常用配置
1 // 后端服务器地址 2 let url = 'http://localhost:8888' 3 module.exports = { 4 publicPath: './', // 【必要】静态文件使用相对路径 5 outputDir: "./dist", //打包后的文件夹名字及路径 6 devServer: { // 开发环境跨域情况的代理配置 7 proxy: { 8 // 【必要】访问自己搭建的后端服务器 9 '/api': { 10 target: url, 11 changOrigin: true, 12 ws: true, 13 secure: false, 14 pathRewrite: { 15 '^/api': '/' 16 } 17 }, 18 // 【范例】访问百度地图的API 19 // vue文件中使用方法 this.$http.get("/baiduMapAPI/place/v2/search" 20 // 最终实际访问的接口为 http://api.map.baidu.com/place/v2/search 21 // 遇到以/baiduMapAPI开头的接口便使用此代理 22 '/baiduMapAPI': { 23 // 实际访问的服务器地址 24 target: 'http://api.map.baidu.com', 25 //开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样客户端和服务端进行数据的交互就不会有跨域问题 26 changOrigin: true, 27 ws: true, // 是否启用websockets 28 secure: false, // 使用的是http协议则设置为false,https协议则设置为true 29 // 将接口中的/baiduMapAPI去掉(必要) 30 pathRewrite: { 31 '^/baiduMapAPI': '' 32 } 33 }, 34 } 35 } 36 }
完整配置
1 const path = require("path"); 2 const resolve = dir => path.join(__dirname, dir); 3 //用于生产环境去除多余的css 4 const PurgecssPlugin = require("purgecss-webpack-plugin"); 5 //全局文件路径 6 const glob = require("glob-all"); 7 //压缩代码并去掉console 8 const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); 9 //代码打包zip 10 const CompressionWebpackPlugin = require("compression-webpack-plugin"); 11 const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i; 12 module.exports = { 13 // 废弃baseUrl 一般运维会配置好的 14 publicPath: process.env.NODE_ENV === "production" ? "/configtest/" : "/", 15 //打包的输出目录 16 outputDir: "dist/configtest", 17 //保存时是否校验 18 lintOnSave: true, 19 //如果文件等设置 20 pages: { 21 index: { 22 entry: "src/main.js", 23 template: "public/index.html", 24 filename: "index.html" 25 } 26 }, 27 //静态资源打包路径 28 assetsDir: "static", 29 //默认false 可以加快打包 30 productionSourceMap: false, 31 //打包后的启动文件 32 indexPath: "congfigtest.html", 33 //打包文件是否使用hash 34 filenameHashing: true, 35 runtimeCompiler: false, 36 transpileDependencies: [], 37 //打包的css路径及命名 38 css: { 39 modules: false, 40 //vue 文件中修改css 不生效 注释掉 extract:true 41 extract: { 42 filename: "style/[name].[hash:8].css", 43 chunkFilename: "style/[name].[hash:8].css" 44 }, 45 sourceMap: false, 46 loaderOptions: { 47 css: {}, 48 less: { 49 // 向全局less样式传入共享的全局变量 50 // data: `@import "~assets/less/variables.less";$src: "${process.env.VUE_APP_SRC}";` 51 }, 52 // postcss 设置 53 postcss: { 54 plugins: [ 55 require("postcss-px-to-viewport")({ 56 viewportWidth: 750, // 视窗的宽度,对应的是我们设计稿的宽度,一般是750 57 viewportHeight: 1334, // 视窗的高度,根据750设备的宽度来指定,一般指定1334,也可以不配置 58 unitPrecision: 3, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除) 59 viewportUnit: "vw", // 指定需要转换成的视窗单位,建议使用vw 60 selectorBlackList: [".ignore", ".hairlines"], // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名 61 minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值 62 mediaQuery: false // 允许在媒体查询中转换`px` 63 }) 64 ] 65 } 66 } 67 }, 68 //webpack 链式配置 默认已经配置好了 node_moudles/@vue 69 chainWebpack: config => { 70 // 修复HMR 71 config.resolve.symlinks(true); 72 // 修复Lazy loading routes 按需加载的问题,如果没有配置按需加载不需要写,会报错 73 // config.plugin("html").tap(args => { 74 // args[0].chunksSortMode = "none"; 75 // return args; 76 // }); 77 //添加别名 78 config.resolve.alias 79 .set("@", resolve("src")) 80 .set("assets", resolve("src/assets")) 81 .set("components", resolve("src/components")) 82 .set("layout", resolve("src/layout")) 83 .set("base", resolve("src/base")) 84 .set("static", resolve("src/static")); 85 // 压缩图片 86 config.module 87 .rule("images") 88 .use("image-webpack-loader") 89 .loader("image-webpack-loader") 90 .options({ 91 mozjpeg: { progressive: true, quality: 65 }, 92 optipng: { enabled: false }, 93 pngquant: { quality: "65-90", speed: 4 }, 94 gifsicle: { interlaced: false }, 95 webp: { quality: 75 } 96 }); 97 }, 98 //webpack 配置 99 configureWebpack: config => { 100 const plugins = []; 101 //去掉不用的css 多余的css 102 plugins.push( 103 new PurgecssPlugin({ 104 paths: glob.sync([path.join(__dirname, "./**/*.vue")]), 105 extractors: [ 106 { 107 extractor: class Extractor { 108 static extract(content) { 109 const validSection = content.replace( 110 /<style([\s\S]*?)<\/style>+/gim, 111 "" 112 ); 113 return validSection.match(/[A-Za-z0-9-_:/]+/g) || []; 114 } 115 }, 116 extensions: ["html", "vue"] 117 } 118 ], 119 whitelist: ["html", "body"], 120 whitelistPatterns: [/el-.*/], 121 whitelistPatternsChildren: [/^token/, /^pre/, /^code/] 122 }) 123 ); 124 //启用代码压缩 125 plugins.push( 126 new UglifyJsPlugin({ 127 uglifyOptions: { 128 compress: { 129 warnings: false, 130 drop_console: true, 131 drop_debugger: false, 132 pure_funcs: ["console.log"] //移除console 133 } 134 }, 135 sourceMap: false, 136 parallel: true 137 }) 138 ), 139 //代码压缩打包 140 plugins.push( 141 new CompressionWebpackPlugin({ 142 filename: "[path].gz[query]", 143 algorithm: "gzip", 144 test: productionGzipExtensions, 145 threshold: 10240, 146 minRatio: 0.8 147 }) 148 ); 149 config.plugins = [...config.plugins, ...plugins]; 150 }, 151 parallel: require("os").cpus().length > 1, 152 pluginOptions: {}, 153 pwa: {}, 154 //设置代理 155 devServer: { 156 port: 8080, 157 host: "0.0.0.0", 158 https: false, 159 open: true, 160 openPage: "about", 161 hot: true, 162 disableHostCheck: true, 163 proxy: { 164 "/api": { 165 target: "https://cdn.awenliang.cn", 166 ws: true, 167 changeOrigin: true 168 }, 169 "/foo": { 170 target: "https://cdn.awenliang.cn", 171 ws: true, 172 changeOrigin: true 173 } 174 } 175 } 176 };