在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'
