Vite2 + vue3 + TS + ElementPlus 从零搭建后台管理系统(七)

6,273 阅读3分钟

上一章主要完成了 添加 mockjs模拟数据 Vite2 + vue3 + TS + ElementPlus 从零搭建后台管理系统(六)

这一章将完善配置文件,以及添加常用插件

1. 获取 .env 配置的环境变量

在项目中可以通过 import.meta.env 来获取到 .env.*文件中的环境变量

但是 import.meta.env 在 vite.config.ts 配置文件中使用不了

这里先在 vite.config.ts 中拿到环境变量参数

  • 修改 .env.development 文件:

VITE_PORT = 60001

VITE_USE_MOCK = true

VITE_GLOB_APP_TITLE = Vue3-ElementPlus-Vite2

VITE_GLOB_API_URL = /basic-api

VITE_PUBLIC_PATH = /

VITE_BUILD_COMPRESS = 'none'

VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false

.env.production 文件 后面同 .env.development文件做相应修改

  • 新增 src/utils/env.ts 文件 处理环境变量

env.ts:

export function wrapperEnv(envConf: Recordable): ViteEnv {
  const ret: any = {};
  for (const envName of Object.keys(envConf)) {
    let realName = envConf[envName].replace(/\\n/g, '\n');
    realName = realName === 'true' ? true : realName === 'false' ? false : realName;

    if (envName === 'VITE_PORT') {
      realName = Number(realName);
    }
    ret[envName] = realName;
    process.env[envName] = realName;
  }
  return ret;
}

在 vite.config.ts 文件中引入 wrapperEnv,并且从'vite'中引入 loadEnv :

import { wrapperEnv } from './src/utils/env'

import { defineConfig, ConfigEnv, UserConfigExport, loadEnv } from 'vite'

然后通过 loadEnv 和 wrapperEnv 最终可获取到环境变量的组成的对象 viteEnv :

export default ({ command, mode }: ConfigEnv): UserConfigExport => {
  const isBuild = command === 'build'

  const root = process.cwd() // 新增
  const env = loadEnv(mode, root) // 新增
  const viteEnv = wrapperEnv(env) // 新增
  const {
    VITE_PORT,
    VITE_USE_MOCK,
    VITE_BUILD_COMPRESS,
    VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE
  } = viteEnv // 新增

  return defineConfig({
    ......
  })
}

2. 添加 vite-plugin-svg-icons

  • vite-plugin-svg-icons:处理 svg/icon 图片插件

之前 svgBuilder 也实现了 处理 svg/icon 图片插件,实现的比较粗糙,但是能了解到vite 插件开发的思路。这里可以先删除 src/plugins/svgBuilder.js

  • 安装

npm install vite-plugin-svg-icons -D

  • 在 src/plugins目录下新增:configSvgIconsPlugin.ts

configSvgIconsPlugin.ts:

/**
 *  Vite Plugin for fast creating SVG sprites.
 * https://github.com/anncwb/vite-plugin-svg-icons
 */
 import type { Plugin } from 'vite';
import SvgIconsPlugin from 'vite-plugin-svg-icons';
import path from 'path';

export function configSvgIconsPlugin(isBuild: boolean):Plugin {
  const svgIconsPlugin:Plugin = SvgIconsPlugin({
    iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
    svgoOptions: isBuild,
    // default
    symbolId: 'icon-[dir]-[name]',
  });
  return svgIconsPlugin;
}

然后在 vite.config.ts 文件中引入 configSvgIconsPlugin ,在 plugins 中使用

import { configSvgIconsPlugin } from './src/plugins/configSvgIconsPlugin'

plugins:[
  ...
  configSvgIconsPlugin(isBuild)
]

插件使用文档看这里:vite-plugin-svg-icons

3. 完善 vite-plugin-style-import

  • vite-plugin-style-import:按需加载组件库插件

目前 element-plus 按需加载使用的插件 vite-plugin-style-import的方式不太优雅,这里优化一下

  • 先删除 styleImport 相关代码

  • 安装

npm install vite-plugin-style-import -D

  • 再在 src/plugins目录下新增:configStyleImportPlugin.ts

configStyleImportPlugin.ts:

 import type { Plugin } from 'vite';
 import styleImport from 'vite-plugin-style-import';

export function configStyleImportPlugin(isBuild?: boolean):Plugin{
  return styleImport({
    libs: [
      {
        libraryName: 'element-plus',
        esModule: true,
        ensureStyleFile: true,
        resolveStyle: (name) => {
          name = name.slice(3)
          return `element-plus/packages/theme-chalk/src/${name}.scss`
        },
        resolveComponent: (name) => {
          return `element-plus/lib/${name}`
        }
      }
    ]
  }) 
} 

然后在 vite.config.ts 文件中引入 configStyleImportPlugin ,在 plugins 中使用

import { configStyleImportPlugin } from './src/plugins/configStyleImportPlugin'

plugins:[
  ...
  configStyleImportPlugin(isBuild)
]

插件使用文档看这里:vite-plugin-style-import

4. 添加 vite-plugin-html

  • vite-plugin-html: html 中 EJS 标签处理

这个 插件可以在 在 index.html 中增加 EJS 标签,例如:

<head>
  <meta charset="UTF-8" />
  <link rel="icon" href="/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title><%- title %></title>
  <%- injectScript %>
</head>

其中 title 和 injectScript 就是可以注入的数据

  • 安装

npm install vite-plugin-html -D

  • 在 src/plugins目录下新增: configHtmlPlugin.ts

configHtmlPlugin.ts:

 import type { Plugin } from 'vite';

 import html from 'vite-plugin-html';
 
 import pkg from '../../package.json';


 export function configHtmlPlugin(env: ViteEnv, isBuild: boolean) {
   const { VITE_GLOB_APP_TITLE, VITE_PUBLIC_PATH } = env;
 
   const path = VITE_PUBLIC_PATH.endsWith('/') ? VITE_PUBLIC_PATH : `${VITE_PUBLIC_PATH}/`;
 
   const getAppConfigSrc = () => {
     return `${path || '/'}_app.config.js?v=${pkg.version}-${new Date().getTime()}`;
   };

   const htmlPlugin: Plugin[] = html({
     minify: isBuild,
     inject: {
       // Inject data into ejs template
       injectData: {
         title: VITE_GLOB_APP_TITLE,
       },
       // Embed the generated app.config.js file
       tags: isBuild?[
            {
            tag: 'script',
            attrs: {
              src: getAppConfigSrc(),
            },
          },
        ]:[]
     },
   });
   return htmlPlugin;
 }
 

然后在 vite.config.ts 文件中引入 configHtmlPlugin ,在 plugins 中使用

import { configHtmlPlugin } from './src/plugins/configHtmlPlugin'

plugins:[
  ...
  configHtmlPlugin(viteEnv, isBuild),
]

插件使用文档看这里:vite-plugin-html

5. 添加 vite-plugin-compression

  • vite-plugin-compression: 资源压缩插件
  • 安装

npm install vite-plugin-compression -D

  • 在 src/plugins目录下新增: configCompressPlugin.ts

configCompressPlugin.ts:

 import type { Plugin } from 'vite';

 import compressPlugin from 'vite-plugin-compression';
 
 export function configCompressPlugin(
   compress: 'gzip' | 'brotli' | 'none',
   deleteOriginFile: boolean = false
 ): Plugin | Plugin[] {
   const compressList = compress.split(0);
 
   const plugins: Plugin[] = [];
 
   if (compressList.includes('gzip')) {
     plugins.push(
       compressPlugin({
         ext: '.gz',
         deleteOriginFile,
       })
     );
   }
   if (compressList.includes('brotli')) {
     plugins.push(
       compressPlugin({
         ext: '.br',
         algorithm: 'brotliCompress',
         deleteOriginFile,
       })
     );
   }
   return plugins;
 }
 

然后在 vite.config.ts 文件中引入 configCompressPlugin ,在 plugins 中使用

import { configCompressPlugin } from './src/plugins/configCompressPlugin'

plugins:[
  ...
  configCompressPlugin( VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE)
]

插件使用文档看这里:vite-plugin-compression

6. 添加全局 TS 类型声明

在configHtmlPlugin.ts 文件中使用了 ViteEnv 类型声明但是未声明,现在来添加

  • 在根目录下新增: types/global.d.ts

global.d.ts:


declare type Recordable<T = any> = Record<string, T>

interface ImportMetaEnv extends ViteEnv {
  __: unknown
}

declare interface ViteEnv {
  VITE_GLOB_APP_TITLE: string
  VITE_PUBLIC_PATH: string
  VITE_GLOB_API_URL: string
  VITE_PORT: number
  VITE_USE_MOCK: boolean
  VITE_BUILD_COMPRESS: string
  VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE: boolean
}

但是会发现使用了 ViteEnv 地方还是有错误提示: 解决办法:修改 tsconfig.json 配置项 typeRoots 和 include

{
  compilerOptions:{
    ...
     "typeRoots": ["./node_modules/@types/", "./types"],// 声明文件目录,默认时node_modules/@types
     "include": [
      "src/**/*.ts",
      "src/**/*.d.ts",
      "src/**/*.tsx",
      "src/**/*.vue", 
      "mock/**/*.ts",
      "types/**/*.d.ts",
      "types/**/*.ts",
    ]
  }
}

如此就可以在 global.d.ts 中写一些全局的类型声明了

最后

到目前为止,基本完善了后台管理系统环境配置。

欢迎大家的指点,期待你的点赞哦。😄😄😄