一个 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 配置的轻量封装。它做三件事:
- 将
webDir默认为'www'。Quasar 始终构建到src-capacitor/www,这样你就不需要记住手动设置这个字段。如果有非常特殊的用例,可以覆盖它。 - 在开发模式下,注入
server.url(Android 上还会注入server.cleartext: true),使运行中的原生应用从 Quasar 的开发服务器加载。如果有非常特殊的用例,可以覆盖它。 - 根据
@capacitor/cli的CapacitorConfig对你的输入进行类型检查,这样自动补全和类型错误来自真正的上游配置模式。
所有这些都发生在 cap CLI 进程内部的配置加载时。你的源文件不会被修改。
该辅助函数接受普通对象、同步函数或异步函数:
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:
const { defineCapacitorConfig } = require('@quasar/app-vite/capacitor')
module.exports = defineCapacitorConfig({
appId: 'org.example.app',
appName: 'My App'
})读取环境变量
当 Quasar 调用 Capacitor CLI(通过 quasar dev -m capacitor 或 quasar 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://...,配置文件可以直接读取:
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 内联为实际的布尔值 true 或 false。而在 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_PROD、QUASAR_CLIENT、QUASAR_SERVER 和其他布尔形状的标志同理。纯字符串值如 QUASAR_TARGET 则按你预期的方式工作。
直接运行 cap
如果你从 /src-capacitor 目录直接运行 cap CLI(npx cap sync、cap 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 > CFBundleDisplayName 和 android/app/src/main/res/values/strings.xml > app_name。
cap sync 和 cap copy 不会重新执行那一步。因此,在平台已存在的情况下修改 capacitor.config.* 中的 appId 或 appName 不会传播到现有原生项目。要重命名已安装的应用,请直接编辑 Info.plist 和 strings.xml,或者删除并重新添加平台。这是 Capacitor 的通用行为,不是 Quasar 特有的问题。
quasar.config 文件
Quasar 特定的 Capacitor 选项位于顶层 /quasar.config 文件中。这些是关于 Quasar 构建/开发行为的配置,而不是 Capacitor 的原生配置(那属于 capacitor.config.*)。
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[];
}
}你还可以配置:
return {
framework: {
config: {
capacitor: {
iosStatusBarPadding: true / false // add the dynamic top padding on iOS mobile devices
}
}
}
}最后,你还可以禁用或配置返回按钮钩子(用于对话框):
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 配置:
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
}
}
}
}
})