手把手教你构建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图片了

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