这一章主要是有关vue.config.js的配置和开发、生产、测试环境的全局变量配置以及使用
在这里我直接先将我的vue.config.js代码贴出来,可以直接拿来使用,代码优化的内容后面会再集中写一篇文章
'use strict'
const path = require('path')
const isProduction =
(process.env.NODE_ENV === process.env.NODE_ENV) !== 'development' // 开发和测试环境一样的配置
function resolve(dir) {
return path.join(__dirname, dir)
}
// All configuration item explanations can be find in https://cli.vuejs.org/config/
module.exports = {
/**
* You will need to set publicPath if you plan to deploy your site under a sub path,
* for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
* then publicPath should be set to "/bar/".
* In most cases please use '/' !!!
* Detail: https://cli.vuejs.org/config/#publicpath
*/
publicPath: process.env.BASE_URL,
// publicPath: './',
outputDir: 'dist',
assetsDir: 'static',
// lintOnSave: process.env.NODE_ENV === 'development',
lintOnSave: false,
productionSourceMap: false,
css: {
loaderOptions: {
scss: {
// 配置全局的公共样式
prependData: `@import "~@/styles/_variable.scss"; @import "~@/styles/_mixins.scss";`
}
}
},
devServer: {
open: true,
overlay: {
warnings: false,
errors: true
},
proxy: {
// change xxx-api/login => mock/login
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://0.0.0.0:8090`, // api地址
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''
}
}
}
},
chainWebpack(config) {
config.plugins.delete('preload') // TODO: need test
config.plugins.delete('prefetch') // TODO: need test
// 配置别名
config.resolve.alias.set('@', resolve('src'))
config
.entry('index')
.add('babel-polyfill')
.end()
// set svg-sprite-loader 配置雪碧图
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
// set preserveWhitespace
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
options.compilerOptions.preserveWhitespace = true
return options
})
.end()
/* 开发环境 */
config
// https://webpack.js.org/configuration/devtool/#development
.when(process.env.NODE_ENV === 'development', config =>
config.devtool('cheap-source-map')
)
/* 非开发环境 */
config.when(process.env.NODE_ENV !== 'development', config => {
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [
{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime\..*\.js$/
}
])
.end()
config.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
vendor: {
name(module) {
const packageName = module.context.match(
/[\\/]node_modules[\\/](.*?)([\\/]|$)/
)[1]
return `npm.${packageName.replace('@', '')}`
},
test: /[\\/]node_modules[\\/]/,
minChunks: 1,
maxInitialRequests: 5,
minSize: 0,
priority: 100,
chunks: 'initial' // only package third parties that are initially dependent
},
styles: {
name: 'styles',
test: /\.(sa|sc|c)ss$/,
chunks: 'all',
enforce: true
},
vantUI: {
name: 'chunk-vantUI', // split vantUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_?vant(.*)/ // in order to adapt to cnpm
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
})
config.optimization.runtimeChunk('single')
config.optimization.minimize(true)
})
/* 生产环境 */
config.when(process.env.NODE_ENV === 'production', config => {
// 删除生产环境的console.log注释
config.optimization.minimizer('terser').tap(args => {
args[0].terserOptions.compress.drop_console = true
return args
})
})
}
}
1.配置环境
代码构建环境,一般分为生成production,测试stage,本地developement,分别在项目根目录新建.env.production , .env.stage, .env.development三个环境配置文件目录结构如下:
│ .env.production
│ .env.stage
│ .env.development
│ ....
│ babel.config.js
│ package.json
│ README.md
│ vue.config.js // vue-cli4.0中配置webpack的地方
│ yarn.lock
.env.production 生产环境
NODE_ENV = 'production' // stage | development 记得一定要在其他环境中写
# base api
VUE_APP_BASE_API = '/'
BASE_URL = '/'
# api ip address
VUE_APP_API_ADDRESS= 'https://www.domain.com'
这里要特别注意的是,配置自己的其他环境变量开头一定要加上VUE_APP,比如要我配置一个全局微信公众号appid可以这样写
#wechat appid
VUE_APP_WECHAT_APPID = wx666666666666666
.env.stage 测试环境和 .env.development 本地环境 的配置和生产环境一样,我这里就不赘述。
在项目其他地方使用环境变量比如,我再在utils目录下新建了一个test.js
src/utils/test.js
export function test() {
// 当前的环境变量值,一般为你配置的环境变量文件,比如stage,production,development
console.log(process.env.NODE_ENV)
// 自己配置的其他环境变量的使用
console.log(process.env.VUE_APP_WECHAT_APPID) // 这是我之前配置的微信appid
}
然后yarn build试试,可能你出现 Error: Cannot find module ‘babel-plugin-import’ 错误 安装一下缺失的包就可以了
yarn add babel-plugin-import
yarn add script-ext-html-webpack-plugin
测试环境的打包命令配置
在package.json中
{
"name": "demo-h5",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"stage": "vue-cli-service build --mode stage"
}
}
测试环境打包命令使用yarn stage
配置全局scss文件
vue.config.js相关配置
module.exports = {
css: {
loaderOptions: {
scss: {
// 配置全局的公共样式
prependData: `@import "~@/styles/_variable.scss"; @import "~@/styles/_mixins.scss";`
}
}
}
}
在src/styles目录下新建以下scss文件
└─src
├─styles // 放置一些通用的scss
│ _mixins.scss // 放置scss的mixin混合器
│ _variable.scss // 放置全局公共scss变量
│ common.scss // 放置一些公共的样式
_mixins.scss
/* 上下水平居中 */
@mixin flex-all-center {
display: flex;
justify-content: center;
align-items: center;
}
/* 上下居中 */
@mixin flex-x-center {
display: flex;
justify-content: center;
}
/* 上下居中 */
@mixin flex-y-center {
display: flex;
align-items: center;
}
/* flex-space-between */
@mixin flex-space-between {
display: flex;
justify-content: space-between;
}
_variable.scss
/* 主题颜色 */
$main-color: #f3f5f9;
/* 白色 */
$white: #ffffff;
/* 底部border颜色 */
$border-bottom-color: #f3f5f9;
$header-height: 40px;
/* 有关钱的数字颜色 */
$money-color: rgba(255, 65, 51, 1);
$test: env(safe-area-inset-bottom, 20px);
common.scss
/* page change */
$--transition-time: 300ms;
.back-enter-active,
.back-leave-active,
.forward-enter-active,
.forward-leave-active {
will-change: transform;
transition: transform $--transition-time;
position: absolute;
height: 100%;
backface-visibility: hidden;
perspective: 1000;
}
.back-enter {
opacity: 0.75;
transform: translate3d(-50%, 0, 0) !important;
}
.back-enter-active {
z-index: -1 !important;
transition: transform $--transition-time;
}
.back-leave-active {
transform: translate3d(100%, 0, 0) !important;
transition: transform $--transition-time;
}
.forward-enter {
transform: translate3d(100%, 0, 0) !important;
}
.forward-enter-active {
transition: transform $--transition-time !important;
}
.forward-leave-active {
z-index: -1;
opacity: 0.65;
transform: translate3d(-50%, 0, 0) !important;
transition: transform $--transition-time;
}
/* 公共部分 */
* {
box-sizing: border-box;
}
// html,
// body {
// height: 100%;
// background: $main-color;
// }
/* 修改placeholder默认颜色 */
::-webkit-input-placeholder {
/* WebKit browsers */
color: rgba(197, 197, 197, 1);
}
:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
color: rgba(197, 197, 197, 1);
}
::-moz-placeholder {
/* Mozilla Firefox 19+ */
color: rgba(197, 197, 197, 1);
}
:-ms-input-placeholder {
/* Internet Explorer 10+ */
color: rgba(197, 197, 197, 1);
}
/* 公共字体 */
// 数字字体加粗
@font-face {
font-family: 'number_bold';
src: url('~@/assets/font/TG-TYPE-Bold.otf');
}
// 数字字体常规
@font-face {
font-family: 'number_regular';
src: url('~@/assets/font/TG-TYPE-Regular.otf');
}
.number-bold {
font-family: number_bold;
}
.number-regular {
font-family: number_regular;
}
/* 像素 */
.onepx-border {
height: 1px;
background: $border-bottom-color;
transform: scaleY(0.5);
}
_mixins.scss和_variable.scss中的混合器和变量就可以全局使用了。
配置svg-sprite
1.首先安装svg-sprite-loader
yarn add svg-sprite-loader -D
然后再vue.config.js中配置
module.exports = {
chainWebpack(config) {
// set svg-sprite-loader 配置雪碧图
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
}
2.新建icon目录
目录结构如下
└─src
├─icons
│ │ index.js
│ │ svgo.yml
│ └─svg
│ back.svg
相关配置我放在了github上了,可以直接荡下来 地址
3.封装icon组件
目录结构如下
src/components/SvgIcon/index.vue
<template>
<svg class="svg-icon" aria-hidden="true" v-on="$listeners">
<use :xlink:href="iconName"></use>
</svg>
</template>
<script>
export default {
name: 'icon-svg',
props: {
iconClass: {
type: String,
required: true
}
},
computed: {
iconName() {
return `#icon-${this.iconClass}`
}
}
}
</script>
<style lang="scss">
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
4.在main.js中引入
// svg icon
import '@/icons'
5.使用
// icon-class为svg图片名,比如back.svg,那么icon-class就为back
<svg-icon icon-class="back" ></svg-icon>
6.最后一步
因为有时候ui给我们的svg会带有多余的元素,导致svg文件过大,可以安装svgo
yarn global add svgo
在package.json文件中配置
"scripts": {
...
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
},
最后使用yarn svgo就可以压缩icons目录下的所有svg图片了