从0到1,带你搭建Vite+Vue3+Unocss+Pinia+Naive UI后台(二) - 配置篇(上)

7,545 阅读3分钟

预览地址:vue-naive-admin

前言

没有前言,文接上篇从0到1,带你搭建Vite+Vue3+Pinia+Naive UI后台(一) - 前置篇 - 掘金 (juejin.cn),直接开始

配置篇

配置篇分上中下三部分,本篇主要介绍环境配置 + vite配置

  1. 环境配置 + vite配置
  2. 插件配置
  3. eslint+prettier配置

环境配置

在根目录下新建三个文件,.env, .env.development, .env.production

.env

VITE_APP_TITLE = 'Admin'

VITE_PORT = 3100

.env.development

# 资源公共路径,需要以 /开头和结尾
VITE_PUBLIC_PATH = '/'

# proxy
VITE_PROXY = [["/api","http://localhost:8080"]]

.env.production

# 资源公共路径,需要以 /开头和结尾
VITE_PUBLIC_PATH = '/'

在vite项目中,以VITE_ 为前缀的环境变量可以通过 import.meta.env.xxx的方式访问,.env文件的环境变量会在所有环境中加载,但是优先级更低,会被当前模式下的同名变量覆盖

但是,在node环境中(如vite.config.js文件),并不能通过import.meta.env.xxx这种方式使用环境变量,但我们却有这样的需求,因此我们需要处理一下,让node环境也可以使用我们定义的环境变量

第一步:在根目录下新建build/utils.js

build/utils.js

export function wrapperEnv(envOptions) {
  if (!envOptions) return {}
  const rst = {}

  for (const key in envOptions) {
    let val = envOptions[key]
    if (['true', 'false'].includes(val)) {
      val = val === 'true'
    }
    if (['VITE_PORT'].includes(key)) {
      val = +val
    }
    if (key === 'VITE_PROXY' && val) {
      try {
        val = JSON.parse(val.replace(/'/g, '"'))
      } catch (error) {
        val = ''
      }
    }
    rst[key] = val
    if (typeof key === 'string') {
      process.env[key] = val
    } else if (typeof key === 'object') {
      process.env[key] = JSON.stringify(val)
    }
  }
  return rst
}

第二步:在vite.config.js中调用刚才定义的方法以初始化环境变量至process.env

vite.config.js

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { wrapperEnv } from './build/utils'

export default defineConfig(({ command, mode }) => {
  const env = loadEnv(mode, process.cwd())
  const viteEnv = wrapperEnv(env)
  
  // 这样就可以拿到定义好的环境变量了,也可以使用process.env.xxx这种方式进行访问
  const { VITE_PORT, VITE_PUBLIC_PATH, VITE_PROXY } = viteEnv
  
  return {
    plugins: [vue()],
    base: VITE_PUBLIC_PATH || '/',
  }
})

vite配置

1. 配置项目根目录

项目根目录,也就是index.html所在的位置,一般情况下并不需要去修改它,确实有这个需求请参考 Vite 官方中文文档 (vitejs.dev)

2. 设置别名

vite.config.js

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

import { wrapperEnv } from './build/utils'

export default defineConfig(({ command, mode }) => {
  // ...
  
  return {
    // ...
    resolve: {
      // 设置别名
      alias: {
        '@': path.resolve(__dirname, 'src'),
      },
    },
  }
})

3. 配置scss全局变量

第一步: 先安装sass依赖(此项目使用scss,如需使用less也是同理,具体配置请查阅Vite 官方中文文档 (vitejs.dev)

pnpm i sass -D

第二步: 新建文件/src/styles/variables.scss,并定义scss变量

/src/styles/variables.scss

$primaryColor: #316c72;

vite.config.js

export default defineConfig(({ command, mode }) => {
  // ...
  return {
    //...
    css: {
      preprocessorOptions: {
        //define global scss variable
        scss: {
          additionalData: `@import '@/styles/variables.scss';`,
        },
      },
    },
  }
})

第三步: 使用我们刚才定义好的变量,看是否生效,修改App.vue的style部分

App.vue

<style lang="scss">
#app {
  background-color: $primaryColor;
}
</style>

然后重启项目就可以看到定义的变量已经生效了,如果没有生效请看下这篇文章,关于Vite配置preprocessorOptions.scss.additionalData全局引入scss文件无效问题 - 掘金 (juejin.cn)

4. 配置devserver

封装创建代理的方法,在/build/utils.js

/build/utils.js

const httpsReg = /^https:\/\//

// ...

export function createProxy(list = []) {
  const rst = {}
  for (const [prefix, target] of list) {
    const isHttps = httpsReg.test(target)

    // https://github.com/http-party/node-http-proxy#options
    rst[prefix] = {
      target: target,
      changeOrigin: true,
      ws: true,
      rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''),
      // https is require secure=false
      ...(isHttps ? { secure: false } : {}),
    }
  }
  return rst
}

vite.config.js

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

import { wrapperEnv, createProxy } from './build/utils'

export default defineConfig(({ command, mode }) => {
  const env = loadEnv(mode, process.cwd())
  const viteEnv = wrapperEnv(env)
  const { VITE_PORT, VITE_PUBLIC_PATH, VITE_PROXY } = viteEnv
  
  return {
    //...
    server: {
      host: '0.0.0.0',  // 默认为'127.0.0.1',如果将此设置为 `0.0.0.0` 或者 `true` 将监听所有地址,包括局域网和公网地址
      port: VITE_PORT,  // 端口
      proxy: createProxy(VITE_PROXY), // 代理
    }
  }
})

配置总览

最终文件修改如下:

vite.config.js

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

import { wrapperEnv, createProxy  } from './build/utils'

export default defineConfig(({ command, mode }) => {
  const env = loadEnv(mode, process.cwd())
  const viteEnv = wrapperEnv(env)
  const { VITE_PORT, VITE_PUBLIC_PATH, VITE_PROXY } = viteEnv
  
  return {
    plugins: [vue()],
    base: VITE_PUBLIC_PATH || '/',
    resolve: {
      // 设置别名
      alias: {
        '@': path.resolve(__dirname, 'src'),
      },
    },
    css: {
      preprocessorOptions: {
        //define global scss variable
        scss: {
          additionalData: `@import '@/styles/variables.scss';`,
        },
      },
    },
    server: {
      host: '0.0.0.0',  // 默认为'127.0.0.1',如果将此设置为 `0.0.0.0` 或者 `true` 将监听所有地址,包括局域网和公网地址
      port: VITE_PORT,  // 端口
      proxy: createProxy(VITE_PROXY), // 代理
    }
  }
})

build/utils.js

const httpsReg = /^https:\/\//

export function wrapperEnv(envOptions) {
  if (!envOptions) return {}
  const rst = {}

  for (const key in envOptions) {
    let val = envOptions[key]
    if (['true', 'false'].includes(val)) {
      val = val === 'true'
    }
    if (['VITE_PORT'].includes(key)) {
      val = +val
    }
    if (key === 'VITE_PROXY' && val) {
      try {
        val = JSON.parse(val.replace(/'/g, '"'))
      } catch (error) {
        val = ''
      }
    }
    rst[key] = val
    if (typeof key === 'string') {
      process.env[key] = val
    } else if (typeof key === 'object') {
      process.env[key] = JSON.stringify(val)
    }
  }
  return rst
}

export function createProxy(list = []) {
  const rst = {}
  for (const [prefix, target] of list) {
    const isHttps = httpsReg.test(target)

    // https://github.com/http-party/node-http-proxy#options
    rst[prefix] = {
      target: target,
      changeOrigin: true,
      ws: true,
      rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''),
      // https is require secure=false
      ...(isHttps ? { secure: false } : {}),
    }
  }
  return rst
}

如有跟着一起做的朋友可以git提交一下代码,如有错误之处请在评论区提醒指正,下一篇再见~

总结

开源不易,还请各位赏个star


源码-github:vue-naive-admin (github.com)

源码-gitee:vue-naive-admin (gitee.com)

下一篇: 从0到1,带你搭建Vite+Vue3+Pinia+Naive UI后台(二) - 配置篇(中) - 掘金 (juejin.cn)