为什么捐赠
API 浏览器
升级指南
NEW!
quasar.config 配置文件
从 Webpack 项目转换
浏览器兼容性
TypeScript 支持
目录结构
命令列表
CSS 预处理器
使用 VueRouter 进行页面路由
懒加载 - 代码分割
资源处理
Boot 文件
预取特性
API 代理
配置 Vite
处理 import.meta.env
Dotenv 文件支持
使用 Pinia 管理状态
代码检查与格式化
测试与审计
开发移动应用
Ajax 请求
开放开发服务器到公网
联系站长
Quasar CLI with Vite - @quasar/app-vite
处理 import.meta.env

使用 import.meta.env 可以在很多方面帮助你:

  • 根据 Quasar 模式(SPA/PWA/Cordova/Electron)区分运行时流程
  • 根据是开发构建还是生产构建区分运行时流程
  • 在构建时基于终端环境变量添加标志

Quasar CLI 提供的值

import.meta.env.<name>类型含义
QUASAR_DEVBoolean代码运行在开发模式
QUASAR_PRODBoolean代码运行在生产模式
QUASAR_DEBUGBoolean代码运行在开发模式或生产模式设置了 --debug 标志
QUASAR_CLIENTBoolean代码运行在客户端(非服务端)
QUASAR_SERVERBoolean代码运行在服务端(非客户端)
QUASAR_MODEStringQuasar CLI 模式(spapwa 等)
QUASAR_<MODE>_MODEBoolean代码运行在 <MODE> Quasar 模式下。例如:QUASAR_ELECTRON_MODE
QUASAR_TARGETStringCordova/Capacitor 模式下为 iosandroid,BEX 模式下为 chromefirefox

示例

if (import.meta.env.QUASAR_DEV) {
  console.log(`I'm on a development build`)
}

// import.meta.env.MODE 是
// "quasar dev/build -m <mode>" 中的 <mode>
//(如果未指定 -m 参数则默认为 'spa')

if (import.meta.env.QUASAR_MODE === 'electron') {
  // ...
}

// 或者使用:
if (import.meta.env.QUASAR_ELECTRON_MODE) {
  // ...
}

代码剥离

编译你的网站/应用时,依赖 import.meta.env 的 if () 分支会被求值,如果表达式为 false,它们会从文件中被剥离。示例:

if (import.meta.env.QUASAR_DEV) {
  console.log('dev')
} else {
  console.log('build')
}

// 使用 "quasar dev" 运行将得到:
console.log('dev')
// 而使用 "quasar build" 运行将得到:
console.log('build')

注意上面的 if 在编译时被求值并完全剥离,从而产生更小的包。

基于 import.meta.env 的导入

你可以将上面学到的内容与动态导入结合使用:

if (import.meta.env.QUASAR_MODE === 'electron') {
  import('my-fancy-npm-package').then(package => {
    // 注意下面的 "default",这是你可以访问
    // npm 导入包导出内容的属性
    package.default.doSomething()
  })
}

// 或者:
if (import.meta.env.QUASAR_ELECTRON_MODE) {
  // ...
}

添加到 import.meta.env

你可以通过 /quasar.config 文件向 import.meta.env 添加自定义定义:

/quasar.config 文件

build: {
  /**
   * 定义全局常量替换。条目在开发时定义为全局变量,
   * 在构建时进行静态替换。
   *
   * 值表达式必须是包含 JSON 可序列化值的字符串
   *(null、boolean、number、string、array 或 object)或单个标识符。
   *
   * @example { __APP_VERSION__: JSON.stringify('v1.0.0') }
   * @example { __API_URL__: 'window.__backend_api_url' }
   */
  define?: Record<string, string>;

  /**
   * `define` 选项的语法糖。定义全局常量替换,
   * 会自动转换为带 `import.meta.env` 前缀的 "define" 条目,
   * 并自动进行 JSON 字符串化。
   *
   * @example { SOME_DEFINE: 'my-string' } 将转换为 { 'import.meta.env.SOME_DEFINE': '"my-string"' }
   * @example { VERSION: 22 } 将转换为 { 'import.meta.env.VERSION': '22' }
   */
  defineEnv?: Record<string, any>;
}
/quasar.config 示例

export default defineConfig(ctx => {
  return {
    // ...

    build: {
      // 从 quasar.config 文件传递到 UI 代码
      define: {
        'import.meta.env.API': JSON.stringify(
          ctx.dev ? 'https://dev.api.com' : 'https://prod.api.com'
        ),
        'import.meta.env.VERSION': JSON.stringify(22)
      },

      // 或者使用 defineEnv 的语法糖:
      defineEnv: {
        API: ctx.dev ? 'https://dev.api.com' : 'https://prod.api.com',
        VERSION: 22
      }
    }
  }
})

然后在你的网站/应用中,你可以访问 import.meta.env.API,它会根据开发或生产构建类型指向上面两个链接之一。import.meta.env.VERSION 也同样可用。

TIP

build.definebuild.defineEnv 之间有一个根本区别。build.defineEnv 是 build.define 的语法糖:

  • 它自动转换为 build.define 语法,在 key 前添加 “import.meta.env.” 前缀并对值进行 JSON 字符串化。
  • build.define 还可以用于注入非 “import.meta.env” 的定义。例如:

build: {
  define: {
    __APP_VERSION__: JSON.stringify('v1.0.0')
  }
}

// 然后直接使用 __APP_VERSION__

你甚至可以将它与 quasar dev/build 的环境变量结合使用:

/.env

# 我们在终端设置一个环境变量
$ MY_API=api.com quasar build
/quasar.config 文件

// 然后在 /quasar.config 文件中获取它
build: {
  defineEnv: {
    API: ctx.dev
      ? 'https://dev.' + import.meta.env.MY_API
      : 'https://prod.' + import.meta.env.MY_API
  }
}

HTML 常量替换

import.meta.env 中的任何属性都可以在 HTML 文件(如你的 /index.html 文件)中使用特殊的 %CONST_NAME% 语法:

<!-- 以下将使用 import.meta.env.API -->
<div>The api is: %API%</div>

如果 env 在 import.meta.env 中不存在,例如 %NON_EXISTENT%,它会被忽略且不会被替换,这与 JS 中的 import.meta.env.NON_EXISTENT 不同(后者会被替换为 undefined)。

TypeScript 的 IntelliSense

你需要为你的定义提供类型声明。根据你使用它们的位置:

  • /src/env.d.ts
  • /src-ssr/ssr-env.d.ts
  • /src-pwa/pwa-env.d.ts
  • …以此类推,每个 Quasar CLI 模式都有对应的文件
/src/env.d.ts 示例

/// <reference types="@quasar/app-vite/client" />

/**
 * 为你的自定义环境变量添加类型,
 * 以避免通过 import.meta.env.VARIABLE_NAME 使用时的 TypeScript 错误
 */
interface ImportMetaEnv {
  readonly API: string
}

故障排除

如果你错误地访问变量或配置有误,可能会在浏览器控制台中看到 process is not defined 错误。

错误用法

/quasar.config 文件

build: {
  defineEnv: {
    FOO: 'hello',
  }
}
const { FOO } = import.meta.env // ❌ 不允许解构或类似操作
import.meta.env.FOO // ✅ 只能替换这样的直接使用

function getEnv(name) {
  return import.meta.env[name] // ❌ 无法分析动态使用
}

console.log(process) // ❌
console.log(import.meta.env) // ❌
// 如果你想查看可用的环境变量列表,
// 可以在 quasar.config 文件中打印传递给 `build > env` 的对象

console.log(import.meta.env.FOO) // ✅
console.log(import.meta.env.foo) // ❌ 区分大小写
console.log(import.meta.env.F0O) // ❌ 变量名拼写错误(中间的 o 是 0)

配置错误

手动定义

/quasar.config 文件

build: {
  defineEnv: {
    FOO: 'hello',
  }
}
console.log(import.meta.env.FOO) // ✅
console.log(import.meta.env.BAR) // ❌ 未在 `build > defineEnv` 中定义

其他有用链接

你可能还想查看 Dotenv 文件支持