构建系统使用 Vite 来创建网站/应用的 UI(/src 目录)。如果您不熟悉 Vite,也不需要担心,所有的一切都是开箱即用的,因为我们已经为您做了适配。
更新 Vite 配置
您可能已经注意到 Quasar CLI with Vite 项目中并不存在 vite.config.js / vite.config.ts 文件。这是因为 Quasar CLI 会自动为您生成 Vite 配置,无需您操心。
如果您需要调整这些配置,可以通过 quasar.config 文件中的 build > extendViteConf 来实现:
build: {
extendViteConf (viteConf, { isServer, isClient }) {
// 我们返回一个对象,它会被深度合并到配置中,
// 而不是直接修改 viteConf
return {
build: {
chunkSizeWarningLimit: 750
}
}
// 等价于以下 vite.config.js/vite.config.ts 配置:
// export default defineConfig({
// build: {
// chunkSizeWarningLimit: 750
// }
// })
}
}注意,您不需要在这个函数中返回任何内容。extendViteConf(viteConf) 中的 viteConf 参数就是 Quasar 为您生成的 Vite 配置对象。您可以对它进行添加/删除/替换几乎任何内容,但前提是您确实知道自己在做什么。不要修改输入和输出文件的配置,以及已经在 quasar.config file > build 中配置过的选项。
如果您想添加 Vite 插件,请参阅下方的添加 Vite 插件章节。
引入了 Quasar 的 npm 包
如果一个 npm 包(组件库、工具包或应用扩展)在自身代码中使用了 import { Notify } from "quasar",Vite 的依赖预构建优化器会将其打包为一份独立的 Quasar 副本。这样一来,您在应用中安装的 Quasar 插件对该包不可见,会出现类似 Notify.create is not a function 的错误。
解决方法是将这类包排除在预构建之外,使它们的 Quasar 导入解析到与应用代码相同的模块:
build: {
extendViteConf () {
// 会被深度合并到生成的 Vite 配置中
return {
optimizeDeps: {
exclude: ['my-quasar-helper-package']
}
}
}
}应用扩展可以(也应当)自行配置这一项,而不是依赖宿主应用来做。详见注入 Quasar 插件。
依赖预构建优化器仅在开发服务器运行时生效。生产构建改为依赖 Quasar 的导入映射机制,它处理 quasar.config file > framework > autoImportScriptExtensions 中列出的文件扩展名(默认:['js', 'jsx', 'ts', 'tsx'])。如果这类包以 .mjs 文件发布其 ESM 构建产物,需要将 'mjs' 添加到该列表中,否则生产包会包含第二份 Quasar 副本,出现同样的症状。
查看 Vite 配置
Quasar CLI 提供了一个非常有用的命令可以输出当前的 Vite 配置:
$ quasar inspect -h
Description
Inspect Quasar generated Vite config
Usage
$ quasar inspect
$ quasar inspect -c build
$ quasar inspect -m electron -p 'build.outDir'
Options
--cmd, -c Quasar 命令 [dev|build] (默认: dev)
--mode, -m 应用开发模式 [spa|ssr|ssg|pwa|bex|cordova|capacitor|electron] (默认: spa)
--depth, -d 深度 (默认: 2)
--path, -p 以点号分隔的配置路径
示例:
-p module.rules
-p plugins
--thread, -t 只展示某个特定的开发模式配置
--help, -h 显示帮助信息添加 Vite 插件
请先确保您使用 pnpm/yarn/npm/bun 安装了您想用的 Vite 插件包,然后编辑 /quasar.config 文件:
build: {
vitePlugins: [
// 以下两种写法完全等价:
['<plugin-name>', {/* 插件配置项 */}],
['<plugin-name>', {/* 插件配置项 */}, { server: true, client: true }]
]
}您可以在客户端或服务端禁用某个插件,这在开发 SSR/SSG 应用时特别有用:
build: {
vitePlugins: [
// 在服务端禁用:
['<plugin-name>', {/* 插件配置项 */}, { server: false }],
// 在客户端禁用:
['<plugin-name>', {/* 插件配置项 */}, { client: false }]
]
}支持多种语法格式:
vitePlugins: [
['<plugin1-name>', {/* 插件 1 的配置项 */}, { server: true, client: true }],
['<plugin2-name>', {/* 插件 2 的配置项 */}, { server: true, client: true }]
// ...
]
// 或:
import plugin1 from "plugin1";
import plugin2 from "plugin2";
vitePlugins: [
[plugin1, {/* 插件 1 的配置项 */}, { server: true, client: true }],
[plugin2, {/* 插件 2 的配置项 */}, { server: true, client: true }]
// ...
]
// 最后,您还可以使用下面这种格式,
// 但这种方式有一个缺点:Quasar CLI 无法检测到
// 配置项参数的变更,因此需要您手动重启开发服务器
import plugin1 from "plugin1";
import plugin2 from "plugin2";
vitePlugins: [
plugin1({/* 插件 1 的配置项 */}),
plugin2({/* 插件 2 的配置项 */})
// ...
]同时,您也可以在 /quasar.config 文件的 extendViteConf() 函数中添加 Vite 插件。这在 SSR/SSG 模式中特别有用(但不局限于 SSR/SSG),可以指定某些插件只在服务端或客户端使用:
import plugin1 from 'plugin1'
import plugin2 from 'plugin2'
build: {
extendViteConf (viteConf, { isClient, isServer }) {
viteConf.plugins.push(
plugin1({ /* 插件 1 的配置项 */ }),
plugin2({ /* 插件 2 的配置项 */ })
// ...
)
}
}此外,别忘了 /quasar.config 文件导出的函数接收一个 ctx 参数。您可以在整个配置文件中使用它来判断当前的 Quasar 开发模式,或者判断是开发环境还是生产环境:
export default defineConfig((ctx) => {
return {
build: {
extendViteConf(viteConf, { isClient, isServer }) {
if (ctx.mode.pwa) {
viteConf.plugins.push(/* ... */);
}
if (ctx.dev) {
viteConf.plugins.push(/* ... */);
}
},
},
};
});示例:rollup-plugin-copy
在构建生产环境时,您很可能需要将一些静态或外部文件复制到 Quasar 项目中,rollup-plugin-copy 可以在构建时帮您完成文件和文件夹的复制。
// ...
build: {
// ...
vitePlugins: [
[
"rollup-plugin-copy",
{
targets: [
{
// 语法参考:https://www.npmjs.com/package/rollup-plugin-copy
src: "[ORIGIN_PATH]",
dest: "[DEST_PATH]",
},
{
// 将 firebase-messaging-sw.js 复制到 SPA/PWA/SSR/SSG 的构建输出目录
src: "config/firebase/firebase-messaging-sw.js",
dest: "dest/spa", // 构建 SPA 时的示例
},
],
},
],
// 其他 vite/rollup 插件
];
}
// ...Vite Vue 插件选项
如果您需要调整 Vite Vue 插件(@vitejs/plugin-vue)的选项,可以通过 quasar.config file > build > viteVuePluginOptions 来实现:
build: {
viteVuePluginOptions: {
script: {
// 示例:启用实验性的 props 解构
propsDestructure: true
},
template: {
compilerOptions: {
// 示例:启用自定义元素/Web Component 标签检测
isCustomElement: (tag) => tag.startsWith('my-')
}
}
}
}JSX/TSX Quasar UI v2.26+ @quasar/app-vite v3.8+
启用 JSX/TSX
如果你想用 JSX/TSX 编写组件(替代或配合 Vue 模板),可通过 quasar.config 文件 > build > vueJsx 启用:
build: {
/**
* 如果你想用 JSX/TSX 编写组件(.jsx/.tsx 文件
* 或 .vue 文件中的 <script lang="jsx|tsx">)。
*
* Vite 自行编译它们,因此该选项只是将 Vite 指向 Vue 的 JSX
* 运行时(而非它默认假定的 React 运行时),并在生成的
* .quasar/tsconfig.json 中添加匹配的 "jsx"/"jsxImportSource"
*(TypeScript 项目)。
*
* 设为 `true`,或传入选项对象以覆盖下方默认值,
* 或设为 "preserve" 让 Vite 插件(如 @vitejs/plugin-vue-jsx,
* 它会添加 Vue 特有的 JSX 语法糖:v-model、v-show、v-slots)
* 来转换 JSX。
*
* 当为 `true` 时提供给 Vite (Oxc) 的默认选项:
* @example
* {
* runtime: 'automatic',
* importSource: 'vue'
* }
*
* @default false
*/
vueJsx?: boolean | NonNullable<OxcOptions["jsx"]>;
}这就是全部所需。Vite 自行编译 JSX/TSX,因此不需要额外的包。该选项的作用是告诉 Vite 使用 Vue 的 JSX 运行时(而非默认的 React 运行时),并且在 TypeScript 项目中将匹配的 jsx / jsxImportSource 添加到生成的 .quasar/tsconfig.json。
现在你可以使用 .jsx / .tsx 文件:
import { QBadge } from 'quasar'
export default function MyBadge({ text }) {
return <QBadge class="q-ma-sm" color="accent" label={text} />
}……以及 .vue 文件中的 <script> 块,通过声明语言:
<script setup lang="jsx">
import { QBadge } from 'quasar'
const MyBadge = () => <QBadge color="accent" label="Hello" />
</script>Quasar 组件在 JSX/TSX 中拥有完整的类型支持:它们的 props、事件(onClick、onUpdate:modelValue 等)以及 Vue 在任何组件上接受的 props(class、style、key、ref)。
如果你还需要 Vue 特有的 JSX 语法糖,请查看 Vite 的 vue jsx 插件。
配置 JSX 转换
除了 true,你可以提供选项对象,它会传递给 Vite (Oxc)。它覆盖默认值:
build: {
vueJsx: {
runtime: 'automatic',
importSource: 'vue'
}
}使用 @vitejs/plugin-vue-jsx
Vite 编译的是纯 JSX,不包含 Vue 特有的 JSX 语法糖(v-model、v-show、v-slots)。如果你需要它们,在应用根目录安装 @vitejs/plugin-vue-jsx,然后将转换交给它:
build: {
// Vite 保留 JSX 不动,交由插件转换
vueJsx: 'preserve',
vitePlugins: [
[ '@vitejs/plugin-vue-jsx', { /* 插件选项 */ } ]
]
}文件夹路径别名
Quasar 预设了一组常用的文件夹路径别名,您可以在项目的任何地方使用它们,Vite 将会正确解析路径。
| 别名 | 解析到 |
|---|---|
src | /src |
app | / |
components | /src/components |
layouts | /src/layouts |
pages | /src/pages |
assets | /src/assets |
boot | /src/boot |
stores | /src/stores (Pinia stores) |
添加文件夹路径别名
我们以 utils 为例,配置后可以像这样使用:import { formatTime } from 'utils/time.js'。添加别名有两种方式:
- 通过 /quasar.config file > build > “alias” 属性。这是最简单的添加方式,请使用绝对路径。示例:
export default defineConfig(ctx => {
return {
build: {
alias: {
// 将指向 /src/utils
utils: ctx.appPaths.resolve.src('utils')
}
}
}
})- 通过直接扩展 Vite 配置。不要直接赋值给
viteConf.resolve.alias,否则会覆盖内置别名,请使用Object.assign或返回一个包含额外别名的对象。始终使用绝对路径。
export default defineConfig(ctx => {
return {
build: {
extendViteConf(viteConf, { isServer, isClient }) {
viteConf.resolve.alias.utils = ctx.appPaths.resolve.src('utils')
}
}
}
})配合 TypeScript 使用
如果您使用 TypeScript,则不需要额外在 tsconfig.json 文件中添加别名配置(也不需要使用 vite-tsconfig-paths 等包)。Quasar CLI 已经默认帮您处理好了。
PostCSS
*.vue 文件中的样式(以及所有其他样式文件)默认通过 PostCSS 管道传输,因此您不需要为其使用特定的加载程序。
默认情况下,PostCSS 会使用 Autoprefixer。如果需要调整,可以在 /postcss.config.js 文件中进行修改。