Vitejs开源项目实践指南(三)

“我正在参加「掘金·启航计划」”

前景概要

本文以开源项目vue-vben-admin作为案例,来介绍怎样在vite+vue项目中引入和使用插件。

拿到一个项目后,若想快速上手项目,首先应查看项目的README.mdpackage.json,同时在项目根目录中展示了项目中使用到的相关依赖或插件的配置文件,比如vite.config.ts就是vite插件的配置文件。如果你想了解项目中的vite配置情况,在了解上述README.mdpackage.json后,就应当将重心放在vite.config.ts当中,其他插件类同此例。

本文的内容顺序依次是:

  • 使用插件:介绍插件的简要使用说明
  • vue-vben-admin源码实战

使用插件

vite已经内置了rollup项目中常用的插件功能,可以在功能指引中查看相关内容。除此之外,若你想使用一些其他未内置的功能,可以在GitHub awesome-vitenpm Vite 插件搜索链接或通过其他方式去查找相关插件,然后在vite.config.ts中引入相关插件。下面是引入插件的步骤:

  1. 安装插件
# 将插件作为开发时依赖
npm install plugin-name -D
  1. 使用插件
import type { UserConfig, ConfigEnv } from 'vite'
// 导入插件
import pluginName from 'plugin-name'

export default ({ command, mode}: ConfigEnv): UserConfig => {
  return {
    // 使用插件
    plugins: [pluginName()]
  }
}

你还可以对插件进行更加详细的配置,比如配置enforce字段来修改插件的执行顺序,以及配置apply字段以在特定的模式下执行插件,下列是使用说明:

// 由于篇幅限制,代码片段内容接上述使用插件的内容
{
  plugins: [
    {
      /**
       * 通过类型查找可知每个插件的引入类型是:type PluginOption
       * type PluginOption = Plugin | false | null | undefined | PluginOption[]
       * 而plugin是一个包含多个字段的对象类型,所以此处可用展开运算符...语法
       */
      ...pluginName(),
      /**
       * enforce值说明:
       *    pre:表示在核心插件(vite core plugins)之前调用该插件
       *    post:表示在构建插件(vite build plugins)之后调用该插件
       *    当未指定时,默认在核心插件(vite core plugins)之后调用该插件
       */
      enforce: 'pre',
      /**
       * apply值说明:
       *    serve:在开发模式下调用该插件
       *    build:在生产模式下调用该插件
       *    函数形式(config, env) => boolean,表示在特定条件下调用该插件
       *    未指定时,默认可在任何模式下调用该插件
       */
      apply: 'serve'
    }
  ]
}

vue-vben-admin源码实战

下面将分析在vue-vben-admin项目中是怎么使用相关的vite插件的。

vite.config.ts文件内可以看到,该项目将用户配置对象UserConfig的plugins字段的值和其它字段一样抽离成调用一个函数createVitePlugins的形式,以便于代码管理,通过调用导入的/build/vite/plugin文件下的createVitePlugins函数(/build/vite/plugin就是/build/vite/plugin/index.ts),来获取到字段plugins的值:

// /vite.config.ts

import type { UserConfig, ConfigEnv } from 'vite'
import { loadEnv } from 'vite'
import { createVitePlugins } from './build/vite/plugin'
import { wrapperEnv } from './build/utils'

export default ({ command, mode }: ConfigEnv): UserConfig => {
  const env = loadEnv(mode, root)
  const viteEnv = wrapperEnv(env)
  const isBuild = command === 'build'
  return {
    // 调用函数,获取plugins的值
    // 不明白可直接忽略参数viteEnv(其功能是获取.env文件对象形式的数据)
    plugins: createVitePlugins(viteEnv, isBuild)
  }
}

下面再来描述一下/build/vite/plugin/index.ts文件的大致结构,从文件中可看出createVitePlugins导出了一个插件数组vitePlugins,vitePlugins先是定义了一个初始化数组,然后通过push的形式导入其他插件。

由文件分析,可对vben引入的插件分为3类,分别是:

  • 第一类:核心功能插件,有vue、vueJsx、VitePluginCertificate
  • 第二类:其他插件,有legacy等
  • 第三类:vben自身创建的插件,这类插件都进行了二次详细配置,存放在同文件夹下
// /build/vite/plugin/index.ts

import { PluginOption } from 'vite'
// 第一类
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import VitePluginCertificate from 'vite-plugin-mkcert'
// 第二类
import legacy from '@vitejs/plugin-legacy'
// 第三类:使用相对路径`./xx`在同文件夹下导入的,是vben项目自身创建的插件
import { configHtmlPlugin } from './html'

// 类型ViteEnv已在/types/global.d.ts中声明
export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
  // 获取.env环境变量对象
  const {
    VITE_LEGACY
  } = viteEnv

  // 使用的插件对象列表
  const vitePlugins: (PluginOption | PluginOption[])[] = [
    // 该插件提供了vue3的单文件组件支持
    vue(),
    vueJsx(),
    /**
     * 使用 mkcert 为 vite https 开发服务提供证书支持,该插件的功能:
     *    希望使用 http/2 解决 vite http dev server 请求的并发限制时,却发现浏览器缓存无效的情况
     *    希望浏览器不要出现烦人的 https 证书错误
     */
    VitePluginCertificate({
      // 指定 mkcert 的下载源
      source: 'coding'
    })
  ]

  // 当环境文件.env[.xxx]中VITE_LEGACY有值 且是构建环境时,才调用该插件
  VITE_LEGACY && isBuild && vitePlugins.push(legacy())

  // 针对vben自身封装的插件,vben又对其进行了一层抽离
  vitePlugins.push(configHtmlPlugin(viteEnv, isBuild))
}

总结

通过上述的代码演练,可见在vite中使用一个插件也不是一个难事,无非就是老生常谈的话题:将繁冗的内容抽离再抽离,使得代码间的展示方式更加简洁和合理。可从实践指南2到这篇文章,将近过去了2个月,之前的畏难之心,在此刻却并未浮现出来。在写作或初次学习时,还是不能够高强度运转或太过于较真,不然过大的心理压力,没有足够的停歇,未必是一件好事。适当的一时半解之乎者也,抛去一些无关紧要的内容,是一个明智之举。

系列文章

Vitejs开源项目实践指南(一)
Vitejs开源项目实践指南(二)

原文链接:https://juejin.cn/post/7231089810298732605 作者:司营

(0)
上一篇 2023年5月10日 上午10:47
下一篇 2023年5月10日 上午10:57

相关推荐

发表回复

登录后才能评论