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

一个 Quasar Capacitor 应用有两个配置层面,各有分工。原生 Capacitor 项目位于 /src-capacitor 目录下,通过 capacitor.config.{ts,js} 进行配置。Quasar 自身的构建/开发行为则由顶层的 /quasar.config 文件配置。下面分别介绍。

capacitor.config 文件

capacitor.config.{ts,js} 是 Capacitor 自身的配置文件。/src-capacitor 目录是一个 Capacitor 项目,关于配置模式和各字段的含义,请参阅 Capacitor 的 配置应用 文档。

关键心智模型:这个文件由 Capacitor CLI 进程加载,而不是由 Vite 打包。当 Quasar 代你运行 cap sync(或类似命令)时,cap CLI 是一个独立的 Node 进程,通过 require().js)或其 TypeScript 加载器(.ts)直接读取 capacitor.config.*。理解了这一点,本页剩余内容就是自然的推论。

文件格式

Quasar CLI 会依次查找 capacitor.config.ts,然后是 .js。当你运行 quasar mode add capacitor 时,脚手架的格式取决于你的项目是否使用 TypeScript:

  • TS 项目会生成 capacitor.config.ts
  • JS 项目会生成 CommonJS 形式的 capacitor.config.js

Capacitor 的 .js 配置加载器尚不能正确处理 ESM 导出,所以 JS 项目中我们必须使用 module.exports

defineCapacitorConfig 辅助函数

@quasar/app-vite/capacitor 导出了 defineCapacitorConfig,这是一个用于 .ts / .js 配置的轻量封装。它做三件事:

  1. webDir 默认为 'www'。Quasar 始终构建到 src-capacitor/www,这样你就不需要记住手动设置这个字段。如果有非常特殊的用例,可以覆盖它。
  2. 在开发模式下,注入 server.url(Android 上还会注入 server.cleartext: true),使运行中的原生应用从 Quasar 的开发服务器加载。如果有非常特殊的用例,可以覆盖它。
  3. 根据 @capacitor/cliCapacitorConfig 对你的输入进行类型检查,这样自动补全和类型错误来自真正的上游配置模式。

所有这些都发生在 cap CLI 进程内部的配置加载时。你的源文件不会被修改。

该辅助函数接受普通对象、同步函数或异步函数:

capacitor.config.ts

import { defineCapacitorConfig } from '@quasar/app-vite/capacitor';

export default defineCapacitorConfig({
  appId: 'org.example.app',
  appName: 'My App',
  plugins: {
    MyPlugin: { apiUrl: process.env.MY_API_URL }
  }
});

JS 形式的写法相同,只是用 CommonJS:

/src-capacitor/capacitor.config.js

const { defineCapacitorConfig } = require('@quasar/app-vite/capacitor')

module.exports = defineCapacitorConfig({
  appId: 'org.example.app',
  appName: 'My App'
})

读取环境变量

当 Quasar 调用 Capacitor CLI(通过 quasar dev -m capacitorquasar build -m capacitor)时,它会在生成的进程上设置一些 QUASAR_* 环境变量。你的 capacitor.config.ts / .js 可以通过 process.env 读取它们。这些名称与 UI 代码中可用的 import.meta.env.QUASAR_* Vite 定义对应:

变量
QUASAR_DEV开发模式下为 'true',构建模式下为 'false'
QUASAR_TARGET'android''ios'
QUASAR_APP_URL开发服务器 URL(仅在开发模式有意义)
QUASAR_MODE'capacitor'
QUASAR_*(其他)Quasar 通过 import.meta.env.QUASAR_* 暴露的其他任何值

你的 .env 文件和 quasar.config > build.env 值也以相同方式转发(受 Quasar 前缀配置约束,参见 处理 import.meta.env)。所以如果你的 .env 中有 SENTRY_DSN=https://...,配置文件可以直接读取:

/src-capacitor/capacitor.config.ts

import { defineCapacitorConfig } from '@quasar/app-vite/capacitor'

export default defineCapacitorConfig({
  appId: 'org.example.app',
  appName: 'My App',
  plugins: {
    Sentry: { dsn: process.env.SENTRY_DSN } // [!code highlight]
  }
})

由于加载模型的不同,有一个类型上的注意点需要理解。在 UI 代码中,import.meta.env.QUASAR_DEV 被 Vite 内联为实际的布尔值 truefalse。而在 capacitor.config.ts / .js 中你读取的是 process.env.X,它始终是字符串。因此同一个名称在两端携带不同的类型,且字符串 'true''false' 都是 truthy 的:

// UI 代码(Vite 打包)
if (import.meta.env.QUASAR_DEV) {
  /* 在开发模式下运行 */
} // [!code highlight]

// capacitor.config.ts(cap CLI 作为普通 Node 加载)
if (process.env.QUASAR_DEV) {
  /* 错误!总会执行! */
} // [!code error]
if (process.env.QUASAR_DEV === 'true') {
  /* 在开发模式下运行 */
} // [!code highlight]

QUASAR_PRODQUASAR_CLIENTQUASAR_SERVER 和其他布尔形状的标志同理。纯字符串值如 QUASAR_TARGET 则按你预期的方式工作。

直接运行 cap

如果你从 /src-capacitor 目录直接运行 cap CLI(npx cap synccap doctor、IDE 触发的同步),Quasar 不参与环境变量填充。文件仍然会加载,defineCapacitorConfig 仍然会默认 webDir,静态字段仍然有效。但任何读取 process.env.QUASAR_* 或你自己 .env 文件值的内容都会返回 undefined,因为没有东西去设置它们。如果某个配置分支在这种路径下很重要,请做好防御性编码。

appId 和 appName

appId 和应用显示名称在你运行 quasar mode add capacitor 时通过提示一次性捕获,并写入脚手架生成的 capacitor.config.* 中。Capacitor CLI 随后在添加平台时(cap add android / cap add ios)将它们写入原生项目,具体是 ios/App/App/Info.plist > CFBundleDisplayNameandroid/app/src/main/res/values/strings.xml > app_name

cap synccap copy 不会重新执行那一步。因此,在平台已存在的情况下修改 capacitor.config.* 中的 appIdappName 不会传播到现有原生项目。要重命名已安装的应用,请直接编辑 Info.plist 和 strings.xml,或者删除并重新添加平台。这是 Capacitor 的通用行为,不是 Quasar 特有的问题。

quasar.config 文件

Quasar 特定的 Capacitor 选项位于顶层 /quasar.config 文件中。这些是关于 Quasar 构建/开发行为的配置,而不是 Capacitor 的原生配置(那属于 capacitor.config.*)。

/quasar.config file

return {
  capacitor: {
    /**
     * Automatically hide the Capacitor Splashscreen when app is ready,
     * (is using the Splashscreen Capacitor plugin).
     *
     * @default true
     */
    hideSplashscreen?: boolean;

    /**
     * Preparation params with which the Capacitor CLI is called
     *
     * @default [ 'sync', ctx.targetName ]
     */
    capacitorCliPreparationParams?: string[];
  }
}

你还可以配置:

/quasar.config file

return {
  framework: {
    config: {
      capacitor: {
        iosStatusBarPadding: true / false // add the dynamic top padding on iOS mobile devices
      }
    }
  }
}

最后,你还可以禁用或配置返回按钮钩子(用于对话框):

/quasar.config file

return {
  framework: {
    config: {
      capacitor: {
        // Quasar handles app exit on mobile phone back button.
        backButtonExit: true / false / '*' / ['/login', '/home', '/my-page'],

        // On the other hand, the following completely
        // disables Quasar's back button management.
        backButton: true / false
      }
    }
  }
}

如果你想修改 /src 中 UI 的 Vite 配置:

/quasar.config file

export default defineConfig(ctx => {
  return {
    build: {
      extendViteConf(viteConf) {
        if (ctx.mode.capacitor) {
          // do something with viteConf
          // or return an object to deeply merge with current viteConf
        }
      }
    }
  }
})