vue3+ts项目中.env配置环境变量与情景配置

一、环境变量配置

官网https://cn.vitejs.dev/guide/env-and-mode.html#intellisense

1. 新建.env开头的文件在根目录

为了防止意外地将一些环境变量泄漏到客户端,只有以 VITE_ 为前缀的变量才会暴露给经过 vite 处理的代码

.env 所有环境默认加载
.env.development 开发模式默认加载
.env.production 生产模式默认加载
.env.check 自定义环境文件

示例:如.env文件

# title
VITE_APP_TITLE = vue-guide-project
a. 模式

默认情况下,开发服务器 (dev 命令) 运行在 development (开发) 模式,而 build 命令则运行在 production (生产) 模式。
这意味着当执行 vite build 时,它会自动加载 .env.production 中可能存在的环境变量。
在某些情况下,若想在 vite build 时运行不同的模式来渲染不同的标题,可以通过传递 --mode 选项标志来覆盖命令使用的默认模式。例如,如果你想在 staging (预发布)模式下构建应用:

vite build --mode staging

# package.json
{
  # ...
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build --mode staging",
  },
}

还需要新建一个 .env.staging 文件:

# .env.staging
VITE_APP_TITLE = My App (staging)
b. 简单了解下NODE_ENV和模式Mode
  • NODE_ENV
    定义:技术上讲,NODE_ENV是一个由Node.js暴露给执行脚本的系统环境变量。
    作用:通常用于确定服务器工具、构建脚本和客户端library在开发环境(development)还是生产环境(production)下的行为。它的值通常为"production"或"development",用于区分不同环境下的逻辑行为。
  • 模式(Mode):
    定义:模式指项目运行或构建时的一种特定状态或配置。
    作用:在前端框架中,模式用于定义项目在不同阶段(如开发、生产、测试)下的行为和配置。它可以包含多个环境变量,并通过特定的文件(如.env.production.env.development等)来管理这些变量。

所以,我们所写的.env可以理解为创建的不同的模式变量

2. TypeScript 智能提示,设置全局类型定义

就是在编码过程中应用这些自定义环境变量的时候,给出的智能提示。

  1. src 目录下创建一个 vite-env.d.ts 或者 env.d.ts 文件
  2. src同级别types目录下创建文件env.d.ts
/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_APP_TITLE: string
  // 更多环境变量...
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}

interface ViteEnv  extends ImportMetaEnv {}
  1. tsconfig.app.json文件中

专门用于处理项目src文件中的TypeScript配置文件,

  • include配置项加入文件:(会提示自定义设置的环境变量)
"include": [
  // ...
  // 第一种方式对应配置
  "vite-env.d.ts", // 或者 "env.d.ts" 
  // 第二种方式对应配置
  "types/**.d.ts" // 或者直接 "types" 
],

效果图:
在这里插入图片描述

  • 或者compilerOptions中加入types:(只会提示默认环境变量)
{
  "compilerOptions": {
    // ...
    "types": ["vite/client"]
  }
}

效果图:
在这里插入图片描述

3. 访问环境变量

  1. 客户端源码(就是src文件)中访问:import.meta.env.VITE_APP_TITLE
  2. html中访问环境变量:%VITE_APP_TITLE%,如果环境变量不存在,则会将被忽略而不被替换,
  3. 在配置(src文件外)文件中访问环境变量

Vite 默认是不加载 .env 文件的,因为这些文件需要在执行完 Vite 配置后才能确定加载哪一个,举个例子,rootenvDir 选项会影响加载行为。不过当你的确需要时,你可以使用 Vite 导出的 loadEnv 函数来加载指定的 .env 文件。

import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({ command, mode }) => {
  // command: "build" | "serve" 
  // mode 当前模式
  // 根据当前工作目录中的 `mode` 加载 .env 文件
  // 设置第三个参数为 '' 来加载所有环境变量,而不管是否有 `VITE_` 前缀。
  const env = loadEnv(mode, process.cwd(), '')
  return {
    // vite 配置
    define: {
      __APP_ENV__: JSON.stringify(env.APP_ENV),
    },
  }
})

输出:console.log(env)

在这里插入图片描述

二、情景配置-根据不同模式使用不同插件

1. 新建build/getEnv.ts 文件处理环境文件变量

loadEnv()获取的环境变量env从输出的值可以看出,全是字符串,所以我们可以自定义方法去转换变量类型

/* eslint-disable */
// Read all environment variable configuration files to process.env
export function wrapperEnv(envConf: any): 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)
    }
    if (envName === 'VITE_PROXY' && realName) {
      try {
        realName = JSON.parse(realName.replace(/'/g, '"'))
      } catch (error) {
        realName = ''
      }
    }
    ret[envName] = realName
  }
  return ret
}

2. build/plugins/index.ts

新建build/plugins 文件夹处理各种plugins,将每一个plugin配置单独抽离

  • plugins文件目录
    在这里插入图片描述

  • 入口文件build/plugins/index.ts

// 插件配置 入口文件index.ts
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import { PluginOption } from 'vite'
import VueDevTools from 'vite-plugin-vue-devtools'

import { Px2remPlugin } from './Px2rem' // rem
import { svgLoaderPlugin } from './SvgLoader' // SVG
import { UnocssPlugin } from './Unocss' // unocss
import { VisualizerPlugin } from './Visualizer' // 打包分析
import { ViteCompressionPlugin } from './ViteCompression' // 压缩gzip
import { ViteImageOptimizerPlugin } from './ViteImageOptimizer' // 图片压缩
import { ViteRestartPlugin } from './ViteRestartPlugin' // 修改配置文件自动重启

export const usePlugins = (isBuild: boolean, viteEnv: ViteEnv) => {
  const { VITE_OPEN_VISUALIZER, VITE_OPEN_SVG_LOADER, VITE_OPEN_PX2REM, VITE_OPEN_COMPRESSION } =
    viteEnv
  const plugins: PluginOption[] = [vue(), vueJsx()]

  plugins.push(UnocssPlugin())
  if (VITE_OPEN_PX2REM) plugins.push(Px2remPlugin())
  if (VITE_OPEN_SVG_LOADER) plugins.push(svgLoaderPlugin())

  // 开发模式下
  if (!isBuild) {
    plugins.push(VueDevTools())
    plugins.push(ViteRestartPlugin())
  }

  if (isBuild) {
    plugins.push(ViteImageOptimizerPlugin())
    // 压缩gzip
    VITE_OPEN_COMPRESSION && plugins.push(ViteCompressionPlugin())
    // 打包分析
    VITE_OPEN_VISUALIZER && plugins.push(VisualizerPlugin())
  }
  return plugins
}

  • 单个plugin示例:
    在这里插入图片描述

4. tsconfig.node.json

专门用于Node.js环境中的TypeScript配置文件,它定义了用于Node.js应用程序的TypeScript编译器选项

tsconfig.node.json文件中:

"include": [
  // ...
  "build/**/*.ts",
  "types" // 全局类型
],

5. .eslintrc.cjs中添加:

overrides: [
  {
    files: ['*.ts', '*.tsx', '*.vue'],
    rules: {
      // 解决 ts 全局类型定义后,eslint报错的问题
      'no-undef': 'off'
    }
  }
],
// ...
'no-unused-expressions': 'off' // 关闭禁止使用表达式

3. vite.config.ts

import { usePlugins } from './build/plugins'
// ...
export default defineConfig(({ command, mode }) => {
  const isBuild = command === 'build'
  const root = process.cwd()
  const env = loadEnv(mode, root)
  const viteEnv = wrapperEnv(env)
  return {
    plugins: usePlugins(isBuild, viteEnv),
    // ...
  }
})

三、情景配置-serverbuild配置

build文件夹中创建server.tsbuild.ts文件

1. 将build配置写入build.ts文件中

export const useBuild = () => {
  return {
    // 10kb以下,转Base64
    assetsInlineLimit: 1024 * 10,
    // chunkSizeWarningLimit: 1500,//配置文件大小提醒限制,默认500
    rollupOptions: {
      output: {
        // 每个node_modules模块分成一个js文件
        manualChunks(id: string) {
          if (id.includes('node_modules')) {
            return 'vendor'
            // return id.toString().split('node_modules/.pnpm/')[1].split('/')[0].toString()
          }
          return undefined
        },
        // 用于从入口点创建的块的打包输出格式[name]表示文件名,[hash]表示该文件内容hash值
        entryFileNames: 'assets/js/[name].[hash].js', // 用于命名代码拆分时创建的共享块的输出命名
        chunkFileNames: 'assets/js/[name].[hash].js', // 用于输出静态资源的命名,[ext]表示文件扩展名
        assetFileNames: 'assets/[ext]/[name].[hash].[ext]'
      }
    }
  }
}

2. 将server配置写入server.ts文件中

import type { ProxyOptions } from 'vite'

type ProxyItem = [string, string]
type ProxyList = ProxyItem[]
type ProxyTargetList = Record<string, ProxyOptions>

/**
 * 创建代理,用于解析 .env.development 代理配置
 */
const userProxy = (proxyList: ProxyList = []) => {
  const ret: ProxyTargetList = {}

  proxyList.forEach((item) => {
    const [prefix, target] = item
    const httpsRE = /^https:\/\//
    const isHttps = httpsRE.test(target)
    ret[prefix] = {
      target,
      changeOrigin: true,
      ws: true,
      rewrite: (path: string) => path.replace(new RegExp(`^${prefix}`), ''),
      // https is require secure=false
      // Verify SSL certificate
      ...(isHttps ? { secure: false } : {})
    }
  })

  return ret
}

/**
 * server 配置
 * @returns
 */
export const useServer = (viteEnv: ViteEnv) => {
  const { VITE_PORT, VITE_PROXY } = viteEnv
  return {
    // 监听所有公共ip
    // host: '0.0.0.0',
    cors: true,
    port: VITE_PORT,
    proxy: userProxy(VITE_PROXY)
  }
}

3. 完整vite.config.ts文件

import { fileURLToPath, URL } from 'node:url'
import { defineConfig, loadEnv } from 'vite'

import { useBuild } from './build/build'
import { wrapperEnv } from './build/getEnv'
import { usePlugins } from './build/plugins'
import { useServer } from './build/server'

export default defineConfig(({ command, mode }) => {
  const isBuild = command === 'build'
  const root = process.cwd()
  const env = loadEnv(mode, root)
  const viteEnv = wrapperEnv(env)
  return {
    plugins: usePlugins(isBuild, viteEnv),
    server: useServer(viteEnv),
    build: useBuild(),
    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url))
      }
    },
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: `
          @use "./src/styles/variables.scss" as *;
          @use "./src/styles/mixin.scss" as *;`,
          javascriptEnabled: true
        }
      }
    }
  }
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/769687.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ 语法

一、头文件与源文件 头文件用于声明函数,类似于java中service层的接口; 源文件用于实现头文件函数,相当于java中serviceImpl层的实现类; 定义接口 实现接口 使用接口 二、指针概述 定义与使用 定义一个指针p用于存a变量的内存地址,即指针就是地址; 解引用可以获取或修改…

并发编程面试题1

一、原子性高频问题: 1.1 Java中如何实现线程安全? 多线程操作共享数据会出现问题。可以使用锁来解决: 悲观锁: 使用 synchronized 和 Lock乐观锁: 使用 CAS(Compare-And-Swap)可以根据业务情况选择 ThreadLocal,让每个线程处理自己的数据。 1.2 CAS底层实现 回答思…

Prometheus 监控服务器

Prometheus概述 组件化设置&#xff1a;nginx ,ceph , Prometheus 部署Prometheus服务器 配置时间 安装Prometheus服务器 访问web页面&#xff1a;http://192.168.88.5:9090/ 添加被监控端 监控方式&#xff1a; 拉取&#xff1a;pull。监控端联系被监控端&#xff0c;采集数…

116-基于5VLX110T FPGA FMC接口功能验证6U CPCI平台

一、板卡概述 本板卡是Xilinx公司芯片V5系列芯片设计信号处理板卡。由一片Xilinx公司的XC5VLX110T-1FF1136 / XC5VSX95T-1FF1136 / XC5VFX70T-1FF1136芯片组成。FPGA接1片DDR2内存条 2GB&#xff0c;32MB Nor flash存储器&#xff0c;用于存储程序。外扩 SATA、PCI、PCI expres…

STM32远程烧录程序

目录 简介 不同的程序下载方式 ICP&#xff1a;In-Circuit Programming ISP&#xff1a;In-System Programing IAP&#xff1a;In-Application Programming BootLoader Bootloader 是什么&#xff1f; STM32的启动方式 存储器组织 存储器映像 嵌入式SRAM 嵌入式FL…

【JVM系列】内存泄漏

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Python数据分析-股票数据分析(GARCH模型)

一、研究背景 随着金融市场的不断发展和全球经济的日益复杂&#xff0c;市场波动性和风险管理成为投资者和金融机构关注的焦点。波动率是衡量市场风险的重要指标&#xff0c;准确预测和评估波动率对于资产定价、风险控制和投资决策具有重要意义。在金融时间序列分析中&#xf…

唐山养老院哪家好---老了怎么过?到这里,享受生活的每一刻!

随着时间的流逝&#xff0c;我们每个人都将迎来老年时光&#xff0c;而"老了&#xff0c;怎么过&#xff1f;"这个问题&#xff0c;虽然简单&#xff0c;却深深触动了无数人的心。 面对老年生活&#xff0c;每个人都有不同的选择和追求。有的人选择顺其自然&#xf…

单目相机减速带检测以及测距

单目相机减速带检测以及测距项目是一个计算机视觉领域的应用&#xff0c;旨在使用一个摄像头&#xff08;单目相机&#xff09;来识别道路上的减速带&#xff0c;并进一步估计车辆与减速带之间的距离。这样的系统对于智能驾驶辅助系统&#xff08;ADAS&#xff09;特别有用&…

新章节:全设备通用调度算法-通讯重构

新章节&#xff1a;全设备通用调度算法-通讯重构 文章目录 新章节&#xff1a;全设备通用调度算法-通讯重构前言一、重构了TCP和UDP通讯二、优化了OPC和OPCUA三、升级了监控客户端四、升级了通讯的图形化其他升级 前言 现在真的很懒也很少写代码了&#xff0c;写代码和更新进度…

Android 15 应用适配默认全屏的行为变更(Android V的新特性)

简介 Android V 上默认会使用全面屏兼容方式&#xff0c;影响应用显示&#xff0c;导致应用内跟导航标题重合&#xff0c;无法点击上移的内容。 默认情况下&#xff0c;如果应用以 Android 15&#xff08;API 级别 35&#xff09;为目标平台&#xff0c;在搭载 Android 15 的设…

【网络安全的神秘世界】SQL注入(下)

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 3.7 二次注入 不好挖这个漏洞&#xff0c;需要搞懂业务逻辑关系 二次注入通常是指在存入数据库时做了过滤&#xff0c;但是取…

vue中自定义设置多语言,并且运行js脚本自动生成多语言文件

在项目中需要进行多个国家语言的切换时&#xff0c;可以用到下面方法其中一个 一、自定义设置多语言 方法一: 可以自己编写一个设置多语言文件 在项目新建js文件&#xff0c;命名为&#xff1a;language.js&#xff0c;代码如下 // language.js 文档 let languagePage {CN…

Rocky Linux yum/dnf repo/mirrors 国内镜像列表及更换方法

Rocky Linux yum/dnf repo/mirrors 国内镜像列表及更换方法 Rocky Linux Mirrors 请访问原文链接&#xff1a;https://sysin.org/blog/rocky-linux-mirrors/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 高校镜像推荐 mirr…

聚观早报 | 微信升级视频功能;一加Ace 3 Pro开启销售

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 7月4日消息 微信升级视频功能 一加Ace 3 Pro开启销售 享界S9将亮相门店 澎湃OS出行助手将陆续升级 特斯拉公布二…

DDOS攻击不懂?看完让你秒懂!

什么是DDOS攻击&#xff1f; DDoS攻击&#xff0c;全称分布式拒绝服务攻击&#xff08;Distributed Denial of Service attack&#xff09;&#xff0c;是一种常见的网络安全攻击方式。以下是对DDoS攻击的详细解释: DDoS攻击是指攻击者利用大量被控制的计算机或设备&#xff…

如何查看JDK使用的垃圾收集器

在Java开发中&#xff0c;垃圾收集器&#xff08;Garbage Collector, GC&#xff09;是管理内存的关键组件&#xff0c;不同的垃圾收集器对应用性能有着显著影响。了解当前JDK使用的垃圾收集器对于性能调优至关重要。本文将介绍如何查看JDK使用的垃圾收集器。 JDK中的垃圾收集…

提升Android Studio开发体验:使用Kelp插件实现颜色和图标预览

提升Android Studio开发体验&#xff1a;使用Kelp插件实现颜色和图标预览 在Android开发中&#xff0c;自动补全功能对于提高开发效率至关重要。然而&#xff0c;默认的Android Studio并不能预览颜色和图标&#xff0c;这使得开发者在选择资源时常常感到困惑。本文将介绍如何使…

Linux中cat命令的英文含义

我之前一直在想cat不是猫的意思吗&#xff0c;但是cat命令在Linux中并不是指"猫"这个动物&#xff0c;而是来源于它的功能&#xff1a;concatenate&#xff08;连接&#xff09;和typeset&#xff08;打印&#xff09;。这个命令的名称是这两个功能的首字母缩写。尽管…

「电子数据」龙信助力鞍山市公安局电子数据取证竞赛

文章关键词&#xff1a;电子数据取证、服务支持、电子数据取证竞赛服务、取证人才培养 为进一步推动电子数据取证分析专业人才队伍建设&#xff0c;不断提高电子数据取证分析能力&#xff0c;7月1日&#xff0c;鞍山市公安局网安支队举办了电子数据取证竞赛&#xff0c;并取得…