手把手教你構建vue項目(微信h5以及hybrid混合開發)(三)——vue.config.js的配置和開發、生產、測試環境的全局變量配置以及使用

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章