Skip to content

vite 区分开发环境和生产环境以及配置

前言

一个项目可能会有开发版本、上线版本、测试版本等等多个版本,不同的环境会有不同请求 api 接口,就需更改一些基本配置,这时候就显得很麻烦,所以这里就使用了环境变量。我们只需做简单的配置,把环境状态切换的工作交给代码。

开发环境

也就是编码时运行的环境,即我们使用 npm run dev 或者 npm run serve 运行项目到本地时,项目处于的环境。

生产环境

项目部署到服务器上后处于的环境,我们使用 npm run build 将项目打包以后,再运行项目,项目就运行在生产环境中了。对于不同的环境,我们可以配置不同的环境变量,来实现开发和生产的兼容。

配置生产环境

1. 配置文件

(1) 在项目根目录下(与 package.json 同级)新建 .env 文件,在文件中配置环境变量,如:

  • .env

全局环境,没有设置其他环境变量的时候,会加载这个文件里的内容

比如 所有版本都使用的是同一个接口地址的时候,就可以写在一个文件里

bash
NODE_ENV = env
VITE_APP_ENV = env
VITE_NAME = "全局环境"
VITE_BASE_URL = "https://www.baidu.com"
VITE_TARGET = "https://www.jsopy.com"

(2) 在项目根目录下(与 package.json 同级)新建 .env.development 文件,在文件中配置环境变量,如:

  • .env.development

开发环境下的配置文件,执行命令 npm run dev 命令,会自动加载.env.development文件

会覆盖.env这个文件定义的环境变量

bash
NODE_ENV = development
VITE_APP_ENV = development
VITE_NAME = "开发环境"
VITE_BASE_URL = "/api"
VITE_TARGET = "https://www.jsopy.com"

(3) 在项目根目录下(与 package.json 同级)新建 .env.production 文件,在文件中配置环境变量,如:

  • .env.production

生产环境下的配置文件,执行命令 npm run build 命令,会自动加载.env.production文件

会覆盖.env这个文件里面定义的环境变量

bash
NODE_ENV = production
VITE_APP_ENV = production
VITE_NAME = "生产环境"
VITE_BASE_URL = "http://xxx.com/api"
VITE_TARGET = "https://www.jsopy.com"

在 package.json 文件中的配置

dev 默认在本地开启测试环境的服务(mode = 'development')

start 在本地开启正式环境服务(mode = 'production')

build 默认打包到正式环境(基础配置取.env.production 文件中的配置)

build:env 默认打包到测试环境(基础配置取.env.development 文件中的配置)

js

  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "lint": "eslint .",
    "preview": "vite preview",
    "dev:pro":" vite --mode development",
    "dev:stage":" vite --mode stage",
    "dev:testing":" vite --mode testing",
    "build:dev":" vite build --mode development",
    "build:pro":" vite build --mode production"
  },

具体使用

  • .env.[name]是可以自定义的,在 package.json 里面做对应的名称修改

  • 根据 Vite 的预定规则,只有以VITE_开头的变量才会在客户端倍捕获

  • import.meta.env.MODE:获取当前环境模式,如:development、production、stage、testing 等。然后重启服务

  • 执行 npm run dev 的时候,vite 会自动加载.env.development文件

  • 执行 npm run build 的时候,vite 会自动加载.env.production文件

开发环境打印变量

打印环境变量 console.log(import.meta.env),执行 npm run dev

浏览器查看打印结果:打印的是.env.development 文件中的内容,import.meta.env 这个环境变量是当前环境变量的内容。

在 vite.config.ts 中依据环境的不同动态切换路径

defineConfig 传入一个函数,方法可以接收一个对象,对象中两个参数:command, mode

command: server(npm run dev) build(npm run build)

mode: development 或 production

defineConfig 传入的方法可以接收一个对象

这个对象可以获取到 command 和 mode 这两个属性

所以 一般.env 文件命名是.env.development 和.env.production

因为这样可以直接将 mode 传入 loadEnv(mode,process.cwd())就可以了

loadEnd 接收三个参数

mode:模式

envDir: 环境变量配置文件所在目录

prefix:接受环境变量的前缀,默认为 VITE

在 vite 中默认是 VITE_

所以根据环境变量动态配置信息 我们可以写成如下

js
import { defineConfig, loadEnv } from "vite";
import react from "@vitejs/plugin-react";
import { fileURLToPath } from "url";
import path from "path";
export default defineConfig(({ command, mode }) => {
  const config = loadEnv(mode, "./");
  console.log(config); // 打印环境变量
  return {
    // 部署生产环境和开发环境下的URL。
    // 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
    // 例如 https://www.xxx/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.xxx/admin/,则设置 baseUrl 为 /admin/。
    base: config.VITE_APP_ENV === "production" ? "/" : "/",
    // 运行服务的配置这里就涉及到代理服务器。解决跨域问题
    server: {
      host: "localhost", // 启动后浏览器窗口输入地址就可以进行访问
      port: 8080, // 端口号
      open: true, //是否自动打开浏览器
      cors: true, //为开发服务器配置 CORS , 默认启用并允许任何源
      https: false, //是否支持http2 如果配置成true 会打开https://localhost:8080;
      strictPort: true, //严格的端口号,如果true,端口号被占用时会直接退出
      hmr: true, // 开启热更新
      proxy: {
        // 反向代理配置
        "/api": {
          // 配置接口调用目标地址
          target: config.VITE_APP_API_URL,
          // 当进行代理时,在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
          changeOrigin: true,
          // 替换target中的请求地址,请求时以 /api 开头
          rewrite: (path) => path.replace(/^\/api/, ""),
        },
      },
    },
  };
});

vite.config.ts 中最后的配置

js
import { defineConfig, loadEnv } from "vite";
import react from "@vitejs/plugin-react";
import { fileURLToPath } from "url";
import path from "path";
// https://vite.dev/config/
export default defineConfig(({ command, mode }) => {
  const config = loadEnv(mode, "./");
  console.log(config);
  return {
    plugins: [react()],
    resolve: {
      alias: {
        // 定义项目路径别名,这样可以在引入文件时,以属性值为起点
        "@": fileURLToPath(new URL("./src", import.meta.url)),
      },
      // import 导入时想要省略的扩展名列表
      extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json"],
    },
    // 部署生产环境和开发环境下的URL。
    // 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
    // 例如 https://www.xxx/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.xxx/admin/,则设置 baseUrl 为 /admin/。
    base: config.VITE_APP_ENV === "production" ? "/" : "/",
    // 运行服务的配置这里就涉及到代理服务器。解决跨域问题
    server: {
      host: "localhost", // 启动后浏览器窗口输入地址就可以进行访问
      port: 8080, // 端口号
      open: true, //是否自动打开浏览器
      cors: true, //为开发服务器配置 CORS , 默认启用并允许任何源
      https: false, //是否支持http2 如果配置成true 会打开https://localhost:8080;
      strictPort: true, //严格的端口号,如果true,端口号被占用时会直接退出
      hmr: true, // 开启热更新
      proxy: {
        // 反向代理配置
        "/api": {
          // 配置接口调用目标地址
          target: config.VITE_APP_API_URL,
          // 当进行代理时,在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
          changeOrigin: true,
          // 替换target中的请求地址,请求时以 /api 开头
          rewrite: (path) => path.replace(/^\/api/, ""),
        },
      },
    },
    build: {
      // 最终构建的浏览器兼容目标,类型:string | string[]
      target: "",
      //指定输出路径
      outDir: "dist",
      //生成静态资源的存放的路径
      assetsDir: "assets",
      // 设置资源阈值,小于该值将内联为 base64 编码,避免额外的 http 请求
      assetsInlineLimit: 4096,
      //启用/禁用 CSS 代码拆分,如果有设置build.lib,build.cssCodeSplit 会默认为 false,
      //false 的话会将项目中的所以 css 提取到一个 css 文件中
      cssCodeSplit: true,
      // 构建后是否生成 source map 文件, boolean | 'inline' | 'hidden'
      sourcemap: false,
      //自定义底层的 Rollup 打包配置
      rollupOptions: {
        // 可以配置多个,表示多入口
        input: {
          index: path.resolve(__dirname, "index.html"),
        },
        output: {
          chunkFileNames: "static/js/[name]-[hash].js",
          entryFileNames: "static/js/[name]-[hash].js",
          assetFileNames: "static/[ext]/name-[hash].[ext]",
        },
      },
      // 禁用将构建后的文件写入磁盘
      write: true,
      //默认情况下,若 outDir 在 root 目录下,则 Vite 会在构建时清空该目录。
      emptyOutDir: true,
      //chunk 大小警告的限制
      chunkSizeWarningLimit: 500,
    },
  };
});