重要!
本指南是关于将 @quasar/app-vite v2 项目升级到 @quasar/app-vite v3。 对于更旧的版本,请参考 https://legacy-app.quasar.dev。
App Extensions 开发者注意事项
你可能需要发布新版本的 Quasar App Extensions 以支持新的 @quasar/app-vite。如果你没有修改 quasar.config 配置,那么只需要更改以下内容即可:
api.compatibleWith(
'@quasar/app-vite',
'^2.0.0' // [!code --]
'^3.0.0-rc.1' // [!code ++]
)WARNING
App Extensions 背后的引擎变更今后只兼容 @quasar/app-vite v3+。你需要放弃对 @quasar/app-vite v2 和 @quasar/app-webpack(任何版本)的支持。
移除了 api.engine、api.hasVite、api.hasWebpack 和 api.hasLint。
所有 api.extendX(fn, api) 方法现在可以是异步的,并且可以选择性地返回一个(Rolldown 等)配置对象,该对象将与默认配置合并。
api.extendSSRWebserverConf((rolldownConf, api) => {
// 添加/移除/修改 Quasar CLI 生成的 Rolldown 配置对象
// 新功能!现在可以选择性地返回一个配置对象,
// 它将被合并到默认配置中
return {
output: {
banner: '/**! My Banner */'
}
}
})许多新的 Index API 方法:
/**
* Add/remove/change properties of SSR production generated package.json
*
* Can be async. Can directly modify the "pkgJson" parameter or
* return a new one that will be merged with the default one.
*/
api.extendSSRPackageJson: (
pkgJson: { [index in string]: any },
api: IndexAPI
) =>
| void
| { [index in string]: any }
| Promise<void | { [index in string]: any }>;
/**
* Extend/configure the Workbox GenerateSW options
* Specify Workbox options which will be applied on top of
* `pwa > extendPWAGenerateSWOptions()`.
*
* https://developer.chrome.com/docs/workbox/the-ways-of-workbox/
*
* Can be async. Can directly modify the "config" parameter or
* return a new one that will be merged with the default one.
*/
api.extendSSRGenerateSWOptions: (
config: GenerateSWOptions,
api: IndexAPI
) => void | GenerateSWOptions | Promise<void | GenerateSWOptions>;
/**
* Extend/configure the Workbox InjectManifest options
* Specify Workbox options which will be applied on top of
* `pwa > extendPWAInjectManifestOptions()`.
*
* https://developer.chrome.com/docs/workbox/the-ways-of-workbox/
*
* Can be async. Can directly modify the "config" parameter or
* return a new one that will be merged with the default one.
*/
api.extendSSRInjectManifestOptions: (
config: InjectManifestOptions,
api: IndexAPI
) => void | InjectManifestOptions | Promise<void | InjectManifestOptions>;新增了 api.logger(在所有四个脚本中可用:Index、Install、Uninstall、Prompts),它以 Quasar CLI 自己的输出风格打印日志,并在每行前标注你的扩展 ID。参见 api.logger。
@quasar/app-vite 现在还为 Index/Prompts/Install/Uninstall 脚本提供了新的类型包装器。IDE 自动补全,我们来了。
通过 App Extension 提供的 CLI 命令的简写形式已被移除:
# 仍然有效;推荐的方式!
quasar run <ext-id> <cmd> [...args]
# 以下方式将不再有效:
quasar <ext-id> <cmd> [...args]并且 api.registerCommand() 的参数也发生了变化。
我们还大幅升级了 AE 的开发体验。你可能想从头到尾重新阅读一遍 AE 文档,从 AE 开发指南 开始,并创建一个新的 AE 项目目录来体验所有新功能。包含 TS 版本!
鸟瞰新特性
⚡ 极速编译:我们用 Rolldown 替代了 esbuild 来处理 /src-* 目录,并彻底重新设计了构建架构。所有 Quasar 模式的构建步骤现在都是并行化的,带来了显著更快的速度和更小的生产包体积。
⚙️ 新一代环境变量管理:我们从零开始重新设计了 env 文件管理。修改这些文件后不再需要重启开发服务器,而且你现在可以直接在 quasar.config 文件中使用它们!
🔒 增强安全性与现代标准:我们从
process.env迁移到了现代的import.meta.env(与 Vite 原生模型对齐),并提供完整的 TypeScript 支持。新的安全层确保客户端文件只能使用可配置前缀的环境变量定义,防止敏感数据泄露。📦 更智能的依赖隔离:我们现在对每个 Quasar 模式的依赖有了清晰的分离。你可以直接在各自的 /src-* 目录中安装模式特定的包。例如,默认的 Electron 应用不再需要在其 dist 目录中安装依赖——只有你在 /src-electron 中显式安装的才会被包含。
🌍 重新设计的 SSR 架构:SSR 模式现在对自定义 Web 服务器和 TypeScript 集成有了更好的支持。添加 SSR 时,CLI 会提示你使用 Hono、Fastify、Express 或 Koa 来生成预配置的 /src-ssr 目录(欢迎告诉我们你还想要哪些开箱即用的服务器支持!)。
📂 SSR 新增服务器资源目录:我们引入了 /src-ssr/server-assets 目录以及实用的工具函数。这使得在开发和生产运行时中引用资源(如 HTTPS 证书)变得非常简单,消除了对 Apache/Nginx 包装器的严格需求。我们还让 serverless 支持变得轻而易举。
🚀 为 SSG 铺路:这个新的 SSR 架构为我们未来正式发布静态站点生成(SSG)模式奠定了必要的基础。
🖥️ 全新的 Electron 模式:我们添加了大量新功能使桌面开发更加顺畅。类似于 SSR,我们引入了 /src-electron/electron-assets 目录。通过 /src-electron 和 /src 中可用的新工具方法,从这里(或从 /public 目录)引用文件现在变得更加容易。
🛣️ Vue Router:对基于文件名的路由提供一流支持。
🚀 更智能的重载(仅在绝对必要时):你会发现开发体验有了显著提升,在修改 quasar.config 文件或 dotenv 文件时有更智能的启发式策略。
🛠️ 现代化核心:代码库已更新以充分利用 Node.js v22+ 的特性,以及所有 Quasar 模式中无数其他小而重要的改进来提升你的生产力。CLI 使用的依赖大幅减少。
开始升级
TIP
如果你不确定是否会遗漏某些推荐的更改,你可以随时使用 @quasar/app-vite v3 创建一个新的项目目录,然后从那里轻松地移植你的应用。
pnpm create quasar@latestPNPM 相关
如果你使用的是 PNPM v11,编辑你的 /pnpm-workspace.yaml 文件。不再需要 shamefullyHoist 配置。
# https://pnpm.io/settings
allowBuilds:
'@parcel/watcher': true
core-js: true
electron-winstaller: true
esbuild: true
lightningcss: true
rolldown: true
unrs-resolver: true同时,在 /src-<bex|pwa|electron|ssr> 中创建 pnpm-workspace.yaml 文件,内容如下:
# 此文件用于强制 pnpm 在此处安装依赖,不受上层 workspace 影响
# https://pnpm.io/settings/package.json
编辑你的 /package.json,更新 @quasar/app-vite 条目:
"devDependencies": {
"@quasar/app-vite": "^2.0.0", // [!code --]
"@quasar/app-vite": "^3.0.0-rc.1" // [!code ++]
}同时确保你的 Vue Router 版本为 v5+,这是现在的最低版本要求!
"dependencies": {
"vue-router": "^5.0.6"
}全局搜索替换
全局搜索 #q-app/wrappers 并替换为 #q-app。
为了更好地与 Vue 生态系统对齐,Quasar CLI 现在只注入一个别名:@/。请在你的代码中对 import 语句进行全局搜索替换,如下表所示。或者,你也可以自行注入旧的别名(查看表格下方了解如何操作)。
| 别名 | 状态 | 说明 |
|---|---|---|
@/ | 新增! | 指向 /src,替代旧的 src 别名。 |
app/ | 已移除 | 将导入替换为 @/../ |
src/ | 已移除 | 将导入替换为 @/ |
components/ | 已移除 | 将导入替换为 @/components/ |
layouts/ | 已移除 | 将导入替换为 @/layouts/ |
pages/ | 已移除 | 将导入替换为 @/pages/ |
assets/ | 已移除 | 将导入替换为 @/assets/。同时将 .vue 文件 <template> 中的 ~assets/... 替换为 ~@/assets/...! |
boot/ | 已移除 | 将代码中的引用替换为 @/boot/ |
stores/ | 已移除 | 将代码中的引用替换为 @/stores/ |
别名变更的替代方案
如果你愿意,可以自行注入旧的别名来避免上述变更:
import { defineConfig } from '#q-app'
export default defineConfig(ctx => ({
build: {
alias: {
src: ctx.appPaths.srcDir,
app: ctx.appPaths.appDir,
components: ctx.appPaths.resolve.src('components'),
layouts: ctx.appPaths.resolve.src('layouts'),
pages: ctx.appPaths.resolve.src('pages'),
assets: ctx.appPaths.resolve.src('assets'),
boot: ctx.appPaths.resolve.src('boot'),
stores: ctx.appPaths.resolve.src('stores')
}
}
}))全局搜索 process.env 并替换为 import.meta.env。对于 Quasar 提供的常量,你还需要加上 QUASAR_ 前缀。以下是完整列表:
// 新增的布尔值常量!
import.meta.env.QUASAR_SPA_MODE
import.meta.env.QUASAR_PWA_MODE
import.meta.env.QUASAR_SSR_MODE
import.meta.env.QUASAR_ELECTRON_MODE
import.meta.env.QUASAR_BEX_MODE
import.meta.env.QUASAR_CAPACITOR_MODE
import.meta.env.QUASAR_CORDOVA_MODE
process.env.DEV // [!code --]
process.env.PROD // [!code --]
import.meta.env.QUASAR_DEV // [!code ++]
import.meta.env.QUASAR_PROD // [!code ++]
// 注意 DEBUGGING -> DEBUG 的变化!
process.env.DEBUGGING // [!code --]
import.meta.env.QUASAR_DEBUG // [!code ++]
process.env.MODE // [!code --]
process.env.TARGET // [!code --]
import.meta.env.QUASAR_MODE // [!code ++]
import.meta.env.QUASAR_TARGET // [!code ++]
process.env.CLIENT // [!code --]
process.env.SERVER // [!code --]
import.meta.env.QUASAR_CLIENT // [!code ++]
import.meta.env.QUASAR_SERVER // [!code ++]
process.env.SERVICE_WORKER_FILE // [!code --]
process.env.PWA_FALLBACK_HTML // [!code --]
process.env.PWA_SERVICE_WORKER_REGEX // [!code --]
import.meta.env.QUASAR_SERVICE_WORKER_FILE // [!code ++]
import.meta.env.QUASAR_PWA_FALLBACK_HTML // [!code ++]
import.meta.env.QUASAR_PWA_SERVICE_WORKER_REGEX // [!code ++]
process.env.QUASAR_ELECTRON_PRELOAD_FOLDER // [!code --]
process.env.APP_URL // [!code --]
import.meta.env.QUASAR_ELECTRON_PRELOAD_FOLDER // [!code ++]
import.meta.env.QUASAR_APP_URL // [!code ++]
// 已移除;请使用 ".cjs" 代替: // [!code --]
process.env.QUASAR_ELECTRON_PRELOAD_EXTENSION // [!code --]对于 /index.html 文件,不再使用之前的 “process.env.X”,现在可以使用:
<!-- 旧方式,请替换! -->
<%= process.env.MY_ENV_VAR_OR_DEFINE %> // [!code --]
<!-- 新方式: -->
<%= importMetaEnv.MY_ENV_VAR_OR_DEFINE %> // [!code ++]
<!-- 或者简写方式: -->
%MY_ENV_VAR_OR_DEFINE% // [!code ++]
<% if (importMetaEnv.MY_ENV_VAR_OR_DEFINE) { %>Wow!<% } %>Quasar 模式的 package.json
编辑你的 /package.json 文件,移除 Quasar 模式特定的依赖,并将它们迁移到新的 /src-<mode>/package.json(需要创建这些文件!):
// create /src-bex/package.json: // [!code ++]
{
"name": "quasar-bex-app",
"version": "1.0.0",
"description": "Quasar BEX Folder",
"private": true,
"type": "module",
"devDependencies": {
"@types/chrome": "^0.1.40" // for TS only
}
}/quasar.config 文件的重要变更
编辑你的 /quasar.config 文件。以下是你需要注意的重要变更:
build: {
rawDefine: {} // [!code --]
define: {} // 值需要经过 JSON.stringify() 处理 // [!code ++]
env: {}, // [!code --]
defineEnv: {} // 或使用长格式 "define",key 中带 'import.meta.env.' 前缀 // [!code ++]
vueOptionsAPI // 如果需要请改为 "true";现在默认为 "false"! // [!code ++]
polyfillModulePreload // 已移除,使用 Vite 的默认配置 // [!code --]
// 新增!Vue Router v5+ 基于文件名的路由 // [!code ++]
filenameBasedRouting: boolean | VueRouterVitePluginOptions // [!code ++]
// 非 async,但现在也可以返回一个新配置
// 将与默认配置合并
extendTsConfig: (tsConfig: TSConfig) => void | TSConfig,
// 已移除;请自行添加你偏好的分析器; // [!code --]
// 下方有示例 // [!code --]
analyze // [!code --]
},
sourceFiles: {
// 现在默认为:'src-pwa/register-sw'!
// 修改文件名或设置为你当前使用的:
pwaRegisterServiceWorker: 'src-pwa/register-service-worker', // [!code ++]
// 现在默认为 'src-pwa/custom-sw'!
// 修改文件名或设置为你当前使用的:
pwaServiceWorker: 'src-pwa/custom-service-worker', // [!code ++]
},
cordova: {
noIosLegacyBuildFlag: true, // 不再可用;仅使用现代构建系统 // [!code --]
},
ssr: {
extendPackageJson (pkgJson) {}, // [!code --]
// 现在可以是异步的,并且可以选择性地返回对象与默认配置合并 // [!code ++]
extendSSRPackageJson (pkgJson) {}, // [!code ++]
extendSSRWebserverConf (esbuildConf) {}, // [!code --]
// 现在可以是异步的,并且可以选择性地返回对象与默认配置合并 // [!code ++]
extendSSRWebserverConf (rolldownConf) {}, // [!code ++]
pwaExtendGenerateSWOptions (conf) {}, // [!code --]
pwaExtendInjectManifestOptions (conf) {}, // [!code --]
// 现在可以是异步的,并且可以选择性地返回对象与默认配置合并 // [!code ++]
extendSSRGenerateSWOptions (conf) {}, // [!code ++]
// 现在可以是异步的,并且可以选择性地返回对象与默认配置合并 // [!code ++]
extendSSRInjectManifestOptions (conf) {}, // [!code ++]
},
pwa: {
// 新增!非 async,但现在也可以返回一个新配置
// 将与默认配置合并
extendPWASwTsConfig: (tsConfig: TSConfig) => void | TSConfig,
extendManifestJson (json) {}, // [!code --]
// 现在可以是异步的,并且可以选择性地返回对象与默认配置合并 // [!code ++]
extendPWAManifestJson (json) {}, // [!code ++]
injectPwaMetaTags: boolean // [!code --]
injectPWAMetaTags: boolean // [!code ++]
extendGenerateSWOptions (conf) {}, // [!code --]
extendInjectManifestOptions (conf) {}, // [!code --]
// 现在可以是异步的,并且可以选择性地返回对象与默认配置合并 // [!code ++]
extendPWAGenerateSWOptions (conf) {}, // [!code ++]
// 现在可以是异步的,并且可以选择性地返回对象与默认配置合并 // [!code ++]
extendPWAInjectManifestOptions (conf) {}, // [!code ++]
extendPWACustomSWConf (esbuildConf) {}, // [!code --]
// 现在可以是异步的,并且可以选择性地返回对象与默认配置合并 // [!code ++]
extendPWACustomSWConf (rolldownConf) {}, // [!code ++]
},
electron: {
extendPackageJson (pkgJson) {}, // [!code --]
// 现在可以是异步的,并且可以选择性地返回对象与默认配置合并 // [!code ++]
extendElectronPackageJson (pkgJson) {}, // [!code ++]
extendElectronMainConf (esbuildConf) {}, // [!code --]
extendElectronPreloadConf (esbuildConf) {}, // [!code --]
// 现在可以是异步的,并且可以选择性地返回对象与默认配置合并 // [!code ++]
extendElectronMainConf (rolldownConf) {}, // [!code ++]
// 现在可以是异步的,并且可以选择性地返回对象与默认配置合并 // [!code ++]
extendElectronPreloadConf (rolldownConf) {}, // [!code ++]
},
bex: {
extendBexScriptsConf (esbuildConf) {}, // [!code --]
// 现在可以是异步的,并且可以选择性地返回对象与默认配置合并 // [!code ++]
extendBexScriptsConf (rolldownConf) {}, // [!code ++]
}由于 build.analyze 已被移除,以下是手动实现的方式:
// pnpm/yarn/npm/bun add -D rollup-plugin-visualizer
// ...rollup-* 插件与 Rolldown 兼容
import { defineConfig } from '#q-app'
export default defineConfig(ctx => {
return {
build: {
vitePlugins: [
ctx.prod
? [
"rollup-plugin-visualizer",
{
open: true,
filename: ctx.appPaths.resolve.cache("stats.html")
},
{ client: true }
]
: null
]
}
}
})ctx 对象现在包含一个以 Quasar CLI 自己的输出风格打印日志的 logger。参见 通过 ctx 记录日志。
TypeScript 变更
你唯一需要的 .d.ts 文件将位于项目根目录:
/**
* 为你的自定义变量添加类型(Quasar CLI 未自动添加的),
* 以避免 TypeScript 错误,例如动态的 process.env 变量
* 或仅为 /quasar.config 文件本身配置的 dotenv 文件中的定义。
*
* @example
* interface ImportMetaEnv {
* readonly MY_VAR: string;
* readonly MY_OTHER_VAR: string;
* }
*/
interface ImportMetaEnv {}你之前使用的以下内容需要从所有 .d.ts 文件中移除。建议只保留上面定义的 /env.d.ts 文件即可。
/**
* 移除这些!不再需要了。
* 删除整个代码块:
*/
declare namespace NodeJS {
interface ProcessEnv {
NODE_ENV: string
VUE_ROUTER_MODE: 'hash' | 'history' | 'abstract' | undefined
VUE_ROUTER_BASE: string | undefined
// ...以及其他之前 Quasar 需要的定义
}
}你可以阅读关于 import.meta.env 的文档。强烈推荐,其中展示了所有新特性。
安装新依赖
然后在根目录和每个 /src-<mode> 目录中运行 pnpm/yarn/npm/bun install,并在根目录运行 quasar prepare。重启你的 IDE 以确保新依赖被正确识别。
确保使用最新的规范更新你的 /quasar.config 文件以满足类型要求。请检查以下所有章节。
重要的破坏性变更
- 所有从
#q-app/wrappers的导入需要替换为#q-app。请进行全局搜索替换。 - 从
process.env切换到了现代的import.meta.env。链接 - /quasar.config > build > vueOptionsAPI 现在默认为
false - /quasar.config > build > polyfillModulePreload(已移除,现在使用 Vite 自身的配置)
- /index.html -> 新的 HTML 常量替换。
<% if (process.env.X) %>将不再有效。 - 新的 dotenv 文件支持,包括
/quasar.config文件本身。默认情况下,Quasar CLI 只会查找.env和.env.local,但你可以添加其他文件以支持带有 prod/dev/mode 后缀的文件。 - /quasar.config >
env现在被新的 dotenv 支持使用。同时移除了build > rawDefine。请使用新的 build >define和defineEnv代替。链接 - Boot 文件和 preFetch > redirect() 的用法已更改。调用后需要立即返回。不再支持通过抛出错误(或返回 Promise)配合
{ url }语法的方式。请直接使用redirect()代替。 - /quasar.config 文件只能使用
.js或.ts扩展名。已移除对.cjs、.mjs、.cts和.mts的支持。 - 所有 Quasar 模式现在都需要在其
/src-<mode>目录下直接安装特定依赖。 - 用
Rolldown替代了esbuild来处理所有特定 Quasar 模式文件(在其/src-<mode>目录下)。这也影响了所有 /quasar.config 中的extendX()方法,因为它们现在接收的是 Rolldown 配置对象。 - 所有 /quasar.config 中的
extendX()方法现在可以是异步的,并且可以选择性地返回一个(Rolldown 等)配置对象,该对象将与默认配置合并。 - 移除了对 Capacitor v4 及以下版本的支持
- 移除了对
@electron/packagerv18 及以下版本的支持 - Cordova 的 iOS 现在使用现代构建系统。
noIosLegacyBuildFlag已被移除。 - “quasar dev -m cordova” 命令现在会打开对应的 IDE(就像 Capacitor 模式一样)
- “quasar dev/build -m bex” 命令现在默认使用 “chrome” 目标,所以
-t|--target选项可以省略。
Electron 模式变更
我们引入了 quasarRuntime。更多信息。
将你的 /src-electron/icons 移动到 /src-electron/electron-assets/icons(创建新的 electron-assets 文件夹)。
Preload 脚本
/**
* Only one preload script should contain this
*/
import { contextBridge } from 'electron'
import { quasarRuntime } from '#q-app/electron/preload'
/**
* Can be used in the renderer process through `window.quasarRuntime`
*/
contextBridge.exposeInMainWorld('quasarRuntime', quasarRuntime)Main 脚本
你可能还需要更新 /src-electron/electron-main 脚本:
- import { fileURLToPath } from 'url'
- const currentDir = fileURLToPath(new URL('.', import.meta.url));
+ import {
+ registerQuasarRuntime,
+ resolveElectronAssetsPath
+ } from "#q-app/electron/main";
- let mainWindow: BrowserWindow | undefined;
- async function createWindow() {
- mainWindow = new BrowserWindow({
- icon: path.resolve(currentDir, 'icons/icon.png'), // tray icon
- webPreferences: {
- preload: path.resolve(
- currentDir,
- path.join(process.env.QUASAR_ELECTRON_PRELOAD_FOLDER, 'electron-preload' + process.env.QUASAR_ELECTRON_PRELOAD_EXTENSION)
- ),
- },
+ async function createWindow() {
+ const mainWindow = new BrowserWindow({
+ icon: resolveElectronAssetsPath("icons/icon.png"), // linux
+ webPreferences: {
+ preload: path.join(import.meta.dirname, "electron-preload.cjs")
+ },
- if (process.env.DEV) {
- await mainWindow.loadURL(process.env.APP_URL);
- }
+ if (import.meta.env.QUASAR_DEV) {
+ await mainWindow.loadURL(import.meta.env.QUASAR_APP_URL);
+ }
- mainWindow.on('closed', () => {
- mainWindow = undefined;
- });
}
- void app.whenReady().then(createWindow);
- app.on('window-all-closed', () => {
- if (platform !== 'darwin') {
- app.quit();
- }
- });
- app.on('activate', () => {
- if (mainWindow === undefined) {
- void createWindow();
- }
- });
+ void app.whenReady().then(async () => {
+ await registerQuasarRuntime();
+ void createWindow();
+ app.on("activate", () => {
+ if (BrowserWindow.getAllWindows().length === 0) {
+ void createWindow();
+ }
+ });
+ });
+ app.on("window-all-closed", () => {
+ if (platform !== "darwin") {
+ app.quit();
+ }
+ });其他 Electron 相关
- 别忘了查看 安装 Electron 依赖 页面。
- 你可能还想看看更新后的 无边框 Electron 窗口 页面。
SSR 模式变更
我们大幅改进了对非 Express.js Web 服务器的支持,并显著提升了类型定义。当项目添加 SSR 模式时,Quasar CLI 会询问你想使用哪个 Web 服务器框架,可以从 Hono/Express.js/Fastify/Koa 中选择。
这里不做逐行对比,建议你查看以下页面(即使你仍想继续使用 Express.js):
- 安装 SSR 依赖
- Web 服务器:查看 Hono/Express/Fastify/Koa 的示例:SSR Webserver;或者移除并重新添加 SSR 模式。
- 中间件:查看 Hono/Express/Fastify/Koa 的示例:SSR Middleware;或者移除并重新添加 SSR 模式。
- 查看 SSR 处理 404 和 500 错误 页面。
- 如果使用 serverless 架构,请查看 SSR Webserver 页面中新的 Serverless 章节。
- 你可能还想使用新的
/src-ssr/server-assets文件夹(需要创建)。它会原样复制到 dist,在开发时也可以通过resolve.serverAssets()或folders.serverAssets使用。 - 还有一点需要注意,对于 SSR 中间件:
serve.error()已更改为serve.devError()(参数也有变化)。
PWA 模式变更
/src-pwa/sw/ 子目录用于 Service Worker
Service Worker 和 PWA 专属的 tsconfig.json(TypeScript 项目)现在位于 /src-pwa/sw/ 内。主线程文件 register-sw.{js,ts} 保留在 /src-pwa/ 根目录。
背景:TypeScript 在从项目根目录运行 tsc/vue-tsc 时不会识别嵌套的 tsconfig.json 文件,因此之前的平铺布局(src-pwa/custom-sw.ts + 同级 tsconfig.json)会产生错误的类型报错,如 Property 'skipWaiting' does not exist on type 'ServiceWorkerGlobalScope'。另外,在 register service worker 脚本中也无法使用 DOM 类型(如 location.reload()),而它在运行时是完全正常的。Quasar 生成的 .quasar/tsconfig.json 现在会自动排除 /src-pwa/sw/,使根 tsc/vue-tsc 跳过它,通过独立检查,嵌套的 tsconfig 像以前一样在 IDE 中处理 SW 类型。
迁移步骤:
创建
/src-pwa/sw/。移动
/src-pwa/custom-sw.{js,ts}->/src-pwa/sw/custom-sw.{js,ts}。仅 TS:移动
/src-pwa/tsconfig.json->/src-pwa/sw/tsconfig.json,然后将内容替换为指向 Quasar 生成的 SW 配置的简洁引用:{ "extends": "../../.quasar/tsconfig.pwa-sw.json" }content_paste
生成的 `.quasar/tsconfig.pwa-sw.json` 处理了 WebWorker lib 替换和作用域 include/exclude。如果你在旧的 `src-pwa/tsconfig.json` 中有自定义设置,可以使用 `quasar.config file > pwa > extendPWASwTsConfig` 来自定义生成的配置。详情参见 [PWA 与 TypeScript](/quasar-cli-vite/developing-pwa/pwa-with-typescript)。更新你的 ESLint 配置 glob:
{ files: ['src-pwa/custom-service-worker.ts'], // [!code --] files: ['src-pwa/sw/**/*.ts'], // [!code ++] languageOptions: { globals: { ...globals.serviceworker } } }content_paste如果你在
quasar.config中显式设置了sourceFiles.pwaServiceWorker,请更新它:sourceFiles: { pwaServiceWorker: 'src-pwa/custom-service-worker', // [!code --] pwaServiceWorker: 'src-pwa/sw/custom-sw', // [!code ++] }content_paste
如果没有设置,新的默认值会自动生效。(可选)TypeScript + ESLint:要在 dev/build 时对 SW 进行类型检查,在
vite-plugin-checker选项中添加一个typescript条目(与vueTsc: true并列):
vitePlugins: [
[
'vite-plugin-checker',
{
vueTsc: true,
typescript: { // [!code ++]
tsconfigPath: './src-pwa/sw/tsconfig.json' // [!code ++]
} // [!code ++]
// ...
},
{ server: false }
]
](可选)TypeScript:添加一个
package.json脚本来检查根和 SW 的类型:"scripts": { "typecheck": "vue-tsc --noEmit && tsc --project src-pwa/sw/tsconfig.json --noEmit", // [!code ++] // ... }content_paste
Capacitor 模式变更
.js / .ts capacitor.config
@quasar/app-vite 新增了对 capacitor.config.js 和 capacitor.config.ts 文件的支持,并移除了对 capacitor.config.json 的支持。.js 和 .ts 变体更加灵活,没有 .json 版本的 git 噪音(.json 版本在每次 “quasar dev” / “quasar build” 时都会被重写相关字段)。升级前你必须迁移到 capacitor.config.ts(TypeScript 项目)或 capacitor.config.js(JS 项目),详情见下文。
“quasar mode add capacitor” 命令现在为 JS 项目生成 capacitor.config.js,为 TypeScript 项目生成 capacitor.config.ts。详情参见 配置 Capacitor。配置文件使用来自 “@quasar/app-vite/capacitor” 的新 defineCapacitorConfig 辅助函数:
import { defineCapacitorConfig } from '@quasar/app-vite/capacitor';
export default defineCapacitorConfig({
appId: 'org.example.app',
appName: 'My App'
});该辅助函数默认 webDir 为 'www',在开发模式下注入 server.url(Android 上还有 server.cleartext: true),并根据 “@capacitor/cli” 的 CapacitorConfig 对你的输入进行类型检查。你自己的值总是优先,源文件不会被修改。在配置中,import.meta.env.QUASAR_DEV、QUASAR_TARGET、QUASAR_APP_URL 以及你自己的 .env / build.env 值都可用。详情阅读 配置 Capacitor。
从 “.json” 迁移时,将文件替换为携带相同字段的 defineCapacitorConfig({...}) 调用。webDir 可以省略:
-{
- "appId": "org.example.app",
- "appName": "My App",
- "webDir": "www"
-}
+const { defineCapacitorConfig } = require('@quasar/app-vite/capacitor');
+
+module.exports = defineCapacitorConfig({
+ appId: 'org.example.app',
+ appName: 'My App'
+});移除:quasar.config > capacitor.{appName, version, description}
quasar.config > capacitor 下的三个字段已移除。它们都没有按预期工作。
version 和 description 从未被 Capacitor CLI 读取,无论是从 capacitor.config.* 还是从 src-capacitor/package.json。iOS 和 Android 从 android/app/build.gradle(versionName / versionCode)和 ios/App/App/Info.plist(CFBundleShortVersionString / CFBundleVersion)获取版本号。发布到商店时请直接编辑这些文件。参见 发布到商店。
appName 有一些效果,但很有限。Capacitor 会将它写入 Info.plist 的 “CFBundleDisplayName”(iOS)和 “strings.xml” > app_name(Android),但仅在 “cap add” 时。“cap sync” 和 “cap copy” 命令不会重新执行那一步,所以 quasar.config 文件中的字段暗示了一个实际上并不存在的实时设置。现在它通过 “quasar mode add capacitor” 时的提示捕获,写入脚手架生成的 capacitor.config.*,并在添加平台时应用到原生项目。后续重命名通过直接编辑 Info.plist 和 strings.xml,或者删除并重新添加平台来完成。
如果你设置了这些字段,请移除它们:
capacitor: {
appName: 'My App', // [!code --]
version: '1.2.0', // [!code --]
description: 'My great app' // [!code --]
// hideSplashscreen, capacitorCliPreparationParams 保留
}src-capacitor/package.json 不再被重写
Quasar 过去会在每次 “quasar dev/build” 命令时覆盖 src-capacitor/package.json 中的 “name”、“version”、“description” 和 “author”。Capacitor CLI 并不读取其中大部分内容,所以这些重写没有实际意义(且在 git 中产生噪音)。新项目会生成一个静态的 quasar-capacitor-app / 1.0.0 模板。现有项目可以更新为匹配,或保持不变。Quasar 不会再修改它。
其他注意事项
切换到 Oxlint 和 Oxfmt
你可能还想将代码检查和格式化切换到 oxlint 和 oxfmt。在我们看来,这是未来的趋势。在不久的将来,Quasar 的项目脚手架工具将只提供这个选项用于代码检查。
在撰写本文时,对 .vue 文件的支持还不完全,但你仍然可以从中受益良多。
基于文件名的路由(Vue Router v5+)
我们现在对 Vue Router 的基于文件名的路由提供了一流支持。你可能想要试试看。
升级到 @quasar/extras v2
可选(但强烈推荐)同时升级到新的 @quasar/extras v2:发布说明。
新 CLI 命令选项
所有命令:–no-color
默认情况下,所有 CLI 命令在终端中输出彩色文本(在非 CI 环境中运行时)。如果你希望禁用彩色输出,可以在运行任何 CLI 命令时使用 --no-color 选项。
build 命令:–no-summary
如果你希望构建时跳过打印构建摘要(从而稍微加快速度):
quasar build --no-summary运行 AE 命令
通过 App Extension 提供的 CLI 命令的简写形式已被移除:
# 仍然有效;推荐的方式!
quasar run <ext-id> <cmd> [...args]
# 以下方式将不再有效:
quasar <ext-id> <cmd> [...args]CSP(内容安全策略)
你可能想在 /index.html 中添加一个 CSP meta 标签。这对 Electron 模式特别有用(会显示缺少 CSP 的警告),但对所有 Quasar 模式来说也是一个好的安全措施:
<!doctype html>
<html>
<head>
<!-- 添加到 head 中 -->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';<% if (ctx.dev) { %> connect-src 'self' ws://localhost:*; worker-src 'self' blob:;<% } %>"
/>
</head>
</html>TIP
这与 Oxlint 和 Oxfmt 配合良好。但是,如果使用 ESLint 和 vite-plugin-checker,上述配置可能需要稍作调整。
最后
请考虑支持我们的工作!如果你在工作中使用 Quasar,请向你的管理层提一下在 https://donate.quasar.dev/ 赞助我们。我们依靠你的支持来实现这样的大规模更新!
享受你的全新现代化配置吧!就是这样!🚀