在vue-cli3.0中,由于将webpack的基础配置全部内嵌了,那我们如何修改配置呢?当然,vue-cli3.0中,我们可以通过新建vue.config.js文件来修改,进行自定义配置。vue.config.js 也是一个可选的配置文件,如果项目的 (和 package.json 同级的) 根目录中存在这个文件,那么它会被 @vue/cli-service 自动加载。关于vue.config.js配置,在此自己测试时,做的一个简单记录,存档用。
官方文档:https://cli.vuejs.org/zh/config/
https://cli.vuejs.org/zh/guide/webpack.html
一、基本的配置(端口、路径等)
文档:https://cli.vuejs.org/zh/config/#vue-config-js
在项目根目录下新建vue.config.js文件(有的代码是上一节环境变量配置所留,没删完),写入:
module.exports = { publicPath: '/', //基本路径 //publicPath: process.env.NODE_ENV !== 'production' ? process.env.VUE_APP_URL : '/', //基本路径 outputDir: 'dist', //生产环境构建输出目录 //outputDir: process.env.VUE_APP_outputDir assetsDir: '', //放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录 lintOnSave: false, // 是否开启eslint在保存的时候检查 ,false不开启 devServer: { open: true, // 启动服务后是否自动打开浏览器,true-每次启动都会打开新的 host: '0.0.0.0', // 允许外部ip访问 port: 8081, // 端口 https: false, // 是否启用https }, //判断不同环境下使用不同配置 configureWebpack: config =>{ if (process.env.NODE_ENV === "development") { config.devtool = 'source-map'; } else if (process.env.NODE_ENV === "production") { config.devtool = "eval-source-map"; } } }
二、开发时的跨域设置
文档:https://cli.vuejs.org/zh/config/#devserver-proxy
https://www.webpackjs.com/configuration/dev-server/#devserver
https://webpack.docschina.org/configuration/dev-server/
具体可以根据文档配置自己的需求。
如果我们有单独的后端开发服务器 API,并且希望在同一域名下发送 API 请求 ,则代理某些 URL 会很有用。
//webpack-dev-server 相关配置 devServer: { // 跨域代理配置---可配置更多控制行为 proxy: { '/api': { target: 'http//api.qianduan8.com', ws:true, //是否允许跨域 secure: false, // 如果是https接口,需要配置这个参数 changeOrigin: true, // 如果接口跨域,需要进行这个参数配置 pathRewrite:{ '^/api':'' //重写路径--匹配 /api ,然后变为'', } } } }比如我们请求/api/users 现在会被代理到请求 http//api.qianduan8.com/api/users ,重写后呢?变成http//api.qianduan8.com/users
使用devServer.before加载本地json数据
devServer.before提供在服务器内部的所有其他中间件之前执行定制中间件的功能。这可以用来定义自定义处理程序。
比如我们项目根目录下建一个data文件夹,里面有一个goods.json文件。
如何使用呢?我们先在vue.config.js最上面引入
const goods = require('./data/goods.json');然后在devServer配置:
before(app){ //访问地址:http://localhost:8081/api/goods app.get('/api/goods', function(req, res) { res.json(goods); }); }运行npm run serve,然后我们在浏览器里输入http://localhost:8081/api/goods 就可以拿到数据了。
三、css相关配置
文档:https://cli.vuejs.org/zh/guide/css.html#css-modules
https://vue-loader.vuejs.org/zh/guide/css-modules.html
//css相关配置 css: { extract: true, // 是否使用css分离插件 ExtractTextPlugin。Default: 生产环境下是 true,开发环境下是 false sourceMap: false, // 开启 CSS source maps? modules: false, //是否开启css-modules模式, 默认值为flase loaderOptions: { css: { // 这里的选项会传递给 css-loader }, postcss: { // 这里的选项会传递给 postcss-loader }, // css预设器配置项 sass: { // @/ 是 src/ 的别名 data: `@import "~@/variables.css";` // 向所有 Sass 样式传入共享的全局变量 } } }
1、全局引入sass\less
sass全局引入用上面的就可以了,
相关文档: https://cli.vuejs.org/zh/guide/css.html#css-modules
如果是less的话会有点不同,需安装style-resources-loader插件
vue add style-resources-loader然后会自动在vue.config.js生成基础代码,配置上我们的less地址就可以了。如:
pluginOptions: { 'style-resources-loader': { preProcessor: 'less', patterns: [ path.resolve(__dirname, './src/assets/css/common.less'), path.resolve(__dirname, './src/assets/css/base.less') ] } }
有一点注意一下,全局less的背景图片路径可以如下引用
background: url(~@/assets/images/icon.png);
四、启用CDN加速引入
对于一些常用的不经常改动的库,比如: vue、vuex、vue-router、axios等等,或者一些UI库比如vuetify,我们可以用CDN的方式引入,让webpack不对他们进行打包,这样可以减少文件大小,也可以节约一点服务器的带宽。
const externals = { vue: 'Vue', 'vue-router': 'VueRouter', vuex: 'Vuex', vuetify: 'vuetify', axios: 'axios' } const cdn = { // 开发环境 dev: { css: [ 'https://cdn.bootcss.com/vuetify/1.5.5/vuetify.min.css' ], js: [ 'https://cdn.bootcss.com/vuetify/1.5.5/vuetify.min.js' ] }, // 生产环境 build: { css: [ 'https://cdn.bootcss.com/vuetify/1.5.5/vuetify.min.css' ], js: [ 'https://cdn.bootcss.com/vue/2.6.10/vue.min.js', 'https://cdn.bootcss.com/vue-router/3.0.3/vue-router.min.js', 'https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js', 'https://cdn.bootcss.com/axios/0.19.0/axios.min.js', 'https://cdn.bootcss.com/vuetify/1.5.5/vuetify.min.js' ] } } configureWebpack: config => { if (process.env.NODE_ENV === "production") { //externals里的模块不打包 Object.assign(config, { externals: externals }) } }, chainWebpack: config => { // 对vue-cli内部的 webpack 配置进行更细粒度的修改 config.plugin('html').tap(args => { if (process.env.NODE_ENV === 'production') { args[0].cdn = cdn.build } if (process.env.NODE_ENV === 'development') { args[0].cdn = cdn.dev } return args }) }然后在入口index.html页面使用esj语法可以读取到配置中的参数,代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <title>vue-cli31</title> <!-- 使用CDN加速的CSS文件,配置在vue.config.js下 --> <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %> <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style" /> <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet" /> <% } %> </head> <body> <noscript> <strong>We're sorry but vue-cli31 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> <!-- 使用CDN加速的JS文件,配置在vue.config.js下 --> <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %> <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script> <% } %> </body> </html>
因为html-webpack-plugin是webpack的一个插件,可以动态的创建和编辑html内容,在webpack中使用cdn是在打包生成静态资源的时候做处理,主要原理是使用html-webpack-plugin动态插入cdn链接。如link标签和script标签。
参考的文章:基于vue-cli3.0构建功能完善的移动端架子
五、修改uglifyOptions去除console来减少文件大小
安装uglifyjs-webpack-plugin
npm i -D uglifyjs-webpack-plugin
安装后在vue.config.js中引入
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')加入如下代码:
configureWebpack: config => { if (process.env.NODE_ENV === 'production') { // 上线压缩去除console等信息 config.plugins.push( new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false, drop_console: true, drop_debugger: false, pure_funcs: ['console.log'] // 移除console } }, sourceMap: false, parallel: true }) ) } }
compress参数文档:https://github.com/mishoo/UglifyJS2/tree/harmony#compress-options
六、开启Gzip
Gzip是一种压缩技术。它将浏览器请求的文件先在服务器端进行压缩,然后传递给浏览器,浏览器解压之后再进行页面的解析工作。在服务端开启Gzip支持后就可以自行压缩了,当然我们前端也可以提前提供资源压缩包,可以更加优化,通过compression-webpack-plugin插件build提供压缩。
npm install compression-webpack-plugin --save-dev
const CompressionWebpackPlugin = require('compression-webpack-plugin'); const productionGzipExtensions = ['js', 'css']; configureWebpack: config => { if (process.env.NODE_ENV === 'production') { // 打包生产.gz压缩包 config.plugins.push(new CompressionWebpackPlugin({ algorithm: 'gzip', test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'), threshold: 10240, minRatio: 0.8 })) } }七、设置alias目录别名
resolve.alias用来创建 import 或 require 的别名,来确保模块引入变得更简单,因为有时候我们项目中使用引入文件有时候路径比较深,所以可以使用webpack的别名alias配置来解决。
官方文档:https://www.webpackjs.com/configuration/resolve/#resolve-alias
如果没有安装path模块需要先安装path
npm i -D path
const path = require('path'); function resolve (dir) { return path.join(__dirname, dir) } chainWebpack: config => { config.resolve.alias .set('_c', resolve('src/components')) .set('api', resolve('src/api')) }
比如:components目录下有一个HelloWord.vue文件,在App.vue里我们就可以这样引用了。
import HelloWorld from '_c/HelloWorld'