业务背景

近些年来,随着前端工程架构发展,使得前端项目中也能拥有如后端工程的模块能力。正所谓 “能力(越)越大(来),责任(越)越大(卷)”,现在的前端工程不仅仅要满足业务需求,还伴随更多复杂的环境适配问题,例如:

  • api请求的域名会根据不同环境而不同;
  • 线上环境和测试环境在打包策略有所不同「如线上要隔离sourceMap、屏蔽vue|react devtools等...」;
  • 前端spa组件根据不同环境做出不同逻辑;

老板恨不得把所有应用端都收归到一个项目里面,什么微前端、uniapp多端方案接踵而至。。。但无论是什么方案,都离不开一个核心点:环境变量和多环境适配。那么,今天我们就来聊下如何在Vite中实现一套拓展能力强的多环境适配方案。

多环境场景的业务形态

我们先来了解,在多环境下要求前端工程架构流程是怎样的?

如上图所示,在工程启动 / 构建时:

  • 环境变量注入:一般通过命令参数模式,可在package.json里配置;
  • 多模式文件:Vite根据环境变量来读取配置文件,把文件参数抽取出来做特性区分,这块也称为Vite的环境模式;
  • 环境收集器:简单理解为1个函数,做的事情就是把第二步的特性参数归整到一处并做些特定的逻辑,之后通过插件生成客户端的最终参数并吐出;
  • 客户端环境差异定制化:客户端(也就是工程里面的.vue、.ts、.tsx等前端文件)获取到环境参数做一些特定区分逻辑;
  • 构建和发布:之后就是项目根据以上几步产出的环境特性文件来打包,最终推送到服务端完成整个前端工程的生产。

以上是大体流程,接下来会每步细分给大家讲解如何实现。方便大家理解,本次笔者专门开了个新GitHub项目来存放本文所有实现代码,有兴趣的同学可以拿下来实操下🌹🌹。

Vite多环境方案实现

多模式文件配置

自定义环境变量

Vite通过 多模式 来配置不同启动场景下的特性环境变量,你可以创建自定义的模式文件,如下:

这个项目创建了4种模式分别兼容release、beta、测试、本地环境,每种模式下有自己特定的环境变量,例如.env.local的内如如下:

# .env._local
# 透传客户端参数
VITE_NODE_ENV=local
VITE_OWNER=Tom
VITE_POSITION=广州,天河
# 私有参数,仅在vite server获取到,
# 假如你的项目包含此类敏感变量。应该将文件添加到你的 .gitignore 中,以避免它们被 git 检入。
MODE_KEY=PRIVATE_KEY_LOCAL

根据Vite的约定规则,只有以“VITE_”开头的变量才会在客户端被捕获,捕获方式为:import.meta.env.{参数名}。

至于非“VITE_”开头的变量属于私有属性,不会传递出去。假如你的项目包含此类敏感变量。应该将文件添加到你的 .gitignore 中,以避免它们被 git 检入。

完成上述配置后,我们只需要在package.json增加对应的启动命令就可以让Vite获取哪个模式来运行项目了:

{
  "name": "vite-mul-env-learn",
  "version": "0.0.0",
  "scripts": {
    "dev:local": "vite --mode _local",
    "dev:test": "vite --mode test",
    "build:beta": "vite build --mode beta",
    "build:release": "vite build --mode release",
    "lint": "eslint --fix --ext .js,.vue,ts src"
  }
}

Vite默认环境变量

Vite 在一个特殊的 import.meta.env 对象上暴露环境变量。这里有一些在所有情况下都可以使用的内建变量:

import.meta.env.MODE: {string} 应用运行的模式。

import.meta.env.BASE_URL: {string} 部署应用时的基本 URL。他由base 配置项决定。

import.meta.env.PROD: {boolean} 应用是否运行在生产环境。

import.meta.env.DEV: {boolean} 应用是否运行在开发环境 (永远与 import.meta.env.PROD相反)。

import.meta.env.SSR: {boolean} 应用是否运行在服务器渲染环境。

这里补充说明下,DEV 和 PROD分别对应package.json中启动dev和build命令决定的,而SSR则是对应了Vite启动时设定的middlewareMode变量决定的:

const { createServer: createViteServer } = require('vite')
const vite = await createViteServer({
    server: { middlewareMode: 'ssr' }
  })

通过插件透传环境变量

很多情况下,我们的环境变量不仅仅是简单的字符串,而是通过vite服务中二次计算才能得到最终结果,有点类似Vue中computed或React中useMemo、useCallback的效果。 像这类非静态的环境变量,我们需要借助插件能力来让它们也能够返回客户端,插件很多,这里推荐vite-plugin-environment,使用大概是这样子的:

You can provide a list of environment variable names to expose to your client code:

import { defineConfig } from 'vite'
import EnvironmentPlugin from 'vite-plugin-environment'
export default defineConfig({
  plugins: [
    EnvironmentPlugin(['API_KEY', 'DEBUG']),
  ],
})

And then use them as:

const apiKey = process.env.API_KEY

在这个基础上,我们还能配合模式文件进行联合判断:

import { defineConfig, ConfigEnv, loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
import EnvironmentPlugin from 'vite-plugin-environment';
import { fetchEnv } from './server/envUitls';
// https://vitejs.dev/config/
export default defineConfig(({ command, mode }: ConfigEnv) => {
  const env = loadEnv(mode, __dirname);
  const { proxy } = fetchEnv(env.VITE_NODE_ENV); // 设置域名和端口
  return {
    base: './',
    plugins: [
      vue(),
      EnvironmentPlugin({
        PROXY: proxy
      })
    ]
  };
});

const env = loadEnv(mode, __dirname);

可以获取.env._local是所有非私密参数,接下来程序可以根据模式参数来计算最终的环境变量,通过插件返回到客户端。

fetchEnv方法可以理解成环境收集器,里面可以写逻辑让环境参数得到统一整合。

客户端环境差异定制

这块就很好理解了,无非就是通过指定方法获取环境变量,来条件渲染vue或React组件。

下面做了个demo:

<script setup lang="ts">
import { ref } from 'vue';
import { proxy } from '@/api/proxy';
interface IEnv extends ImportMetaEnv {
  VITE_NODE_ENV: string;
  VITE_OWNER: string;
  VITE_POSITION: string;
}
const viteEnv: IEnv = import.meta.env;
</script>
<template>
  <div class="app">
    <img alt="Vue logo" src="./assets/logo.png" />
    <section class="main">
      <div class="card">
        <h4>①通过环境文件传入的参数</h4>
        <div class="tips">说明:只包含"VITE_"开头参数</div>
        <div>项目owner:{{ viteEnv.VITE_OWNER }}</div>
        <div>owner位置:{{ viteEnv.VITE_POSITION }}</div>
        <div>项目mode:{{ viteEnv.VITE_NODE_ENV }}</div>
      </div>
      <div class="card">
        <h4>②环境插件传递的参数</h4>
        <div class="tips">
          说明:通过vite-plugin-environment插件传递过来,一般为二次计算后的参数。假如是静态参数值则直接通过方案①传回来即可。
        </div>
        <p>服务请求域:{{ proxy }}</p>
      </div>
      <div class="card">
        <h4>③Vite环境自带参数</h4>
        <div class="tips">
          说明:Vite默认参数,参考
          <a href="https://cn.vitejs.dev/guide/env-and-mode.html#env-variables" rel="external nofollow" 
            >Vite环境变量</a
          >
        </div>
        <p>是否为SSR模式:{{ viteEnv.SSR }}</p>
        <p>是否为本地开发模式:{{ viteEnv.DEV }}</p>
        <p>是否为构建模式:{{ viteEnv.PROD }}</p>
        <p>当前启动命令读取的mode为:{{ viteEnv.MODE }}</p>
        <p>部署应用时的基本 URL:{{ viteEnv.BASE_URL }}</p>
      </div>
    </section>
  </div>
</template>
<style lang="less" scoped>
.app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.main {
  display: flex;
  .card {
    margin: 10px;
    padding: 10px;
    width: 300px;
    text-align: left;
    background-color: #dbf1e7;
    font-size: 14px;
    h4 {
      margin-bottom: 0;
    }
    .tips {
      margin-bottom: 10px;
      font-size: 12px;
      color: #898989;
    }
  }
}
</style>

效果图

解决的业务场景思考

除了本文 “业务背景” 模块所说的最直观的场景外,其实还可以做很多项目工程化相关的高阶操作。

假如项目构建操作放在远程服务器进行,那么在构建打包前就可以联动服务api来生产出不同版本、不同模式的构建包,甚至可以把SSR逻辑放到这块来做,达到“千人千面”的效果。

以上就是Vite多环境配置项目高定制化能力详解的详细内容,更多关于Vite多环境配置项目高定制的资料请关注Devmax其它相关文章!

Vite多环境配置项目高定制化能力详解的更多相关文章

  1. 使用Vite+Vue3+Vant全家桶快速构建项目步骤详解

    这篇文章主要为大家介绍了使用Vite+Vue3+Vant全家桶快速构建项目步骤详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  2. Vite创建Vue3项目及Vue3使用jsx详解

    vite是新一代的前端构建工具,下面这篇文章主要给大家介绍了关于Vite创建Vue3项目以及Vue3使用jsx的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

  3. vite插件打包更顺畅使用技巧示例

    这篇文章主要为大家介绍了vite插件打包更顺畅的使用技巧示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. 一步步带你用vite简单搭建ts+vue3全家桶

    Vue3与TS的联合是大趋势,下面这篇文章主要给大家介绍了关于用vite简单搭建ts+vue3全家桶的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

  5. Anaconda+pycharm安装及环境配置全过程

    在使用pyCharm进行开发时,需要用到Anaconda创建的环境,下面这篇文章主要给大家介绍了关于Anaconda+pycharm安装及环境配置的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

  6. vite创建一个标准vue3+ts+pinia项目

    本文主要介绍了vite创建一个标准vue3+ts+pinia项目,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  7. 创建项目及包管理yarn create vite源码学习

    这篇文章主要为大家介绍了创建项目及包管理yarn create vite源码学习分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  8. 如何使用Vue3+Vite+TS快速搭建一套实用的脚手架

    Vite是一个面向现代浏览器的一个更轻、更快的 Web 应用开发工具,下面这篇文章主要给大家介绍了关于如何使用Vue3+Vite+TS快速搭建一套实用脚手架的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

  9. vite的搭建与使用的详细步骤

    本文主要介绍了vite的搭建与使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  10. 利用Vite搭建Vue3+ElementUI-Plus项目的全过程

    vue3如今已经成为默认版本了,相信大多数公司已经全面拥抱vue3了,下面这篇文章主要给大家介绍了关于利用Vite搭建Vue3+ElementUI-Plus项目的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部