這一章主要是有關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圖片了