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

注意,你的项目文件夹中包含一个 /quasar.config 文件。那么你可以通过它配置什么呢?基本上是 Quasar CLI 能为你做的所有事情:

  • 你的网站/应用将使用的 Quasar 组件、指令和插件
  • 默认 Quasar 语言包
  • 你希望使用的 图标库
  • Quasar 组件默认 图标集
  • 开发服务器端口、HTTPS 模式、主机名等
  • 你希望使用的 CSS 动画
  • Boot 文件 列表(决定执行顺序)——这些文件位于 /src/boot,用于在挂载根 Vue 组件前初始化你的应用
  • 要包含进构建包的全局 CSS/Sass/… 文件
  • SPA、PWA、Electron、Capacitor、Cordova、SSR、BEX(浏览器扩展)等模式的配置
  • 扩展底层工具,比如生成的 Vite 配置
  • 以及你在使用过程中会发现的更多功能

TIP

你会发现更改这些设置时,无需手动重载开发服务器。Quasar 会自动检测并重载相关进程。你不会丢失开发流程,因为 Quasar CLI 会快速重载变更代码,并保持当前状态。这能为你节省大量时间!

WARNING

/quasar.config 文件由 Quasar CLI 构建系统运行,因此这些代码直接在 Node.js 下执行,而不是在你的应用上下文中。这意味着你可以直接引入诸如 node:fsnode:path、Vite 插件等模块。

结构

基础用法

你会注意到 /quasar.config 文件导出一个接收 ctx(上下文)参数的函数,并返回一个对象。这样你可以根据上下文动态更改网站/应用配置:

/quasar.config file

import { defineConfig } from '#q-app'

export default defineConfig(ctx => {
  // 也可以是 async
  console.log(ctx)

  // 控制台示例输出:
  /*
  {
    dev: true,
    prod: false,
    mode: { spa: true },
    modeName: 'spa',
    target: {},
    targetName: undefined,
    arch: {},
    archName: undefined,
    debug: undefined
  }
  */

  // 上下文是根据运行 "quasar dev" 或 "quasar build" 时的参数生成的

  return {
    // ... 你的配置
  }
})

这意味着,例如你可以在构建某种模式(如 PWA)时加载某个字体,而在其他模式中选择另一个:

/quasar.config file

{
  extras: [
    ctx.mode.pwa // we're adding only if working on a PWA
      ? 'roboto-font'
      : null
  ]
}

或者你可以在 SPA 模式中使用一个全局 CSS 文件,在 Cordova 模式中使用另一个,而其他模式则不加载任何此类文件:

/quasar.config file

{
  css: [
    ctx.mode.spa ? 'app-spa.sass' : null, // looks for /src/css/app-spa.sass
    ctx.mode.cordova ? 'app-cordova.sass' : null // looks for /src/css/app-cordova.sass
  ]
}

或者你可以配置开发服务器在 SPA 模式使用 8000 端口,PWA 模式使用 9000 端口,其他模式使用 9090 端口:

/quasar.config file

{
  devServer: {
    port: ctx.mode.spa ? 8000 : ctx.mode.pwa ? 9000 : 9090
  }
}

你也可以在返回配置前执行异步操作:

/quasar.config file

import { defineConfig } from '#q-app'

export default defineConfig(async (ctx) => {
  const data = await someAsyncFunction()
  return {
    // ... use "data"
  }
})

// or:
export default defineConfig((ctx) => {
  return new Promise(resolve => {
    // some async work then:
    // resolve() with the quasar config
    resolve({
      //
    })
  })
})

玩法无限。

通过 ctx 输出日志

ctx 对象内置了一个日志工具,输出样式与 Quasar CLI 自身保持一致:

/quasar.config file

import { defineConfig } from '#q-app'

export default defineConfig(ctx => {
  ctx.logger.log('hello') // 绿色横幅行
  ctx.logger.warn('careful') // 黄色横幅警告
  ctx.logger.fatal('boom') // 红色横幅错误;以退出码 1 终止进程
  ctx.logger.tip('try foo') // TIP 标签提示行
  ctx.logger.info('synced') // INFO 标签行
  ctx.logger.info('synced', 'SYNC') // 自定义标签文字(替代默认的 INFO)
  ctx.logger.success('built')
  ctx.logger.error('oh no')
  ctx.logger.warning('hmm')

  const finish = ctx.logger.progress({
    tool: 'fetch',
    waitAction: 'reading',
    doneAction: 'read'
  })
  // ...稍后
  finish() // 打印 DONE 行并显示耗时

  ctx.logger.dot // 辅助函数打印时使用的圆点字符

  return {
    // ...
  }
})

IDE 自动补全

注意从 #q-app 导入的 defineConfig。它本质上是一个 no-op 函数,但它能帮助 IDE 获得更好的自动补全体验。你设置的每个选项都会进行类型检查,每个值都会获得补全提示,悬停在键上还能看到其 JSDoc 文档。

/quasar.config file

// @noErrors
import { defineConfig } from '#q-app'

export default defineConfig(ctx => ({
  boot: ['axios', 'i18n'],

  css: ['app.sass'],

  extras: ['material-symbols-outlined', 'roboto-font'],

  framework: {
    lang: 'en-US',
    plugins: ['Notify', 'Dialog'],
    iconSet: 'material-'
    //                 ^|
  },

  build: {
    vueRouterMode: 'history'
  }
}))

可配置项说明

css

/**
 * Global CSS/Stylus/SCSS/SASS/... files from `/src/css/`,
 * except for theme files, which are included by default.
 */
css?: string[];

示例:

/quasar.config file

{
  css: [
    'app.sass', // referring to /src/css/app.sass
    '~some-library/style.css' // referring to node_modules/some-library/style.css
  ]
}

boot

更多内容请参阅 Boot 文件

/** Boot files to load. Order is important. */
boot?: QuasarBootConfiguration;

interface BootConfigurationItem {
  path: string;
  server?: false;
  client?: false;
}

type QuasarBootConfiguration = (string | BootConfigurationItem)[];

preFetch

更多内容请参阅 PreFetch 特性 页面。

/** Enable the preFetch feature. */
preFetch?: boolean;

extras

/**
 * What to import from [@quasar/extras](https://github.com/quasarframework/quasar/tree/dev/extras) package.
 * @example ['material-icons', 'roboto-font', 'ionicons-v4']
 */
extras?: (QuasarIconSets | QuasarFonts)[];

framework

/**
 * What Quasar language pack to use, what Quasar icon
 * set to use for Quasar components, etc.
 */
framework?: {
  /**
   * @see - QuasarConfOptions tab in API cards throughout the docs
   */
  config?: SerializableConfiguration<QuasarUIConfiguration>;
  /**
   * One of the Quasar IconSets
   *
   * @see https://v2.quasar.dev/options/quasar-icon-sets
   *
   * @example 'material-icons'
   */
  iconSet?: QuasarIconSets;
  /**
   * One of the Quasar language packs
   *
   * @see https://v2.quasar.dev/options/quasar-language-packs
   *
   * @example 'en-US'
   * @example 'es'
   */
  lang?: QuasarLanguageCodes;
  /**
   * Quasar CSS addons have breakpoint aware versions of flex and spacing classes
   *
   * @see https://v2.quasar.dev/layout/grid/introduction-to-flexbox#flex-addons
   * @see https://v2.quasar.dev/style/spacing#flex-addons
   */
  cssAddon?: boolean;

  /**
   * Auto import - how to detect components in your vue files
   *   "kebab": q-carousel q-page
   *   "pascal": QCarousel QPage
   *   "combined": q-carousel QPage
   *
   * @default 'kebab'
   */
  autoImportComponentCase?: "kebab" | "pascal" | "combined";
  /**
   * Auto import - which file extensions should be interpreted as referring to Vue SFC?
   *
   * @default ['vue']
   */
  autoImportVueExtensions?: string[];
  /**
   * Auto import - which file extensions should be interpreted as referring to script files?
   *
   * @default ['js', 'jsx', 'ts', 'tsx']
   */
  autoImportScriptExtensions?: string[];
  /**
   * Treeshake Quasar's UI on dev too?
   * Recommended to leave this as false for performance reasons.
   *
   * @default false
   */
  devTreeshaking?: boolean;

  /**
   * Quasar will auto import components based on your usage.
   * But, in case you have a special case, you can manually specify Quasar components to be available everywhere.
   *
   * An example case would be having custom component definitions with plain string templates, inside .js or .ts files,
   * in which you are using Quasar components (e.g. q-avatar).
   *
   * Another example would be that dynamically rendering components depending on an API response or similar (e.g. in a CMS),
   * something like `<component :is="dynamicName">` where `dynamicName` is a string that matches a Quasar component name.
   *
   * @example ['QAvatar', 'QChip']
   */
  components?: (keyof QuasarComponents)[];
  /**
   * Quasar will auto import directives based on your usage.
   * But, in case you have a special case, you can manually specify Quasar directives to be available everywhere.
   *
   * An example case would be having custom component definitions with plain string templates, inside .js or .ts files,
   * in which you are using Quasar directives (e.g. v-intersection).
   *
   * @example ['Intersection', 'Mutation']
   */
  directives?: (keyof QuasarDirectives)[];
  /**
   * Quasar plugins to be installed. Specify the ones you are using in your app.
   *
   * @example ['Notify', 'Loading', 'Meta', 'AppFullscreen']
   */
  plugins?: (keyof QuasarPlugins)[];
}

更多信息请参考:

animations

更多内容请参阅 CSS 动画

/**
 * What Quasar CSS animations to import.
 * @example [ 'bounceInLeft', 'bounceOutRight' ]
 * */
animations?: QuasarAnimationsConfiguration | 'all';

devServer

更多信息:Vite server options

import { ServerOptions as ViteServerOptions } from "vite";
import { Options as OpenOptions } from "open";
type DevServerOptions = Omit<ViteServerOptions, "open" | "https"> & {
  open?: Omit<OpenOptions, "wait"> | boolean;
  https?: ViteServerOptions["https"] | boolean;
};

/**
 * Vite "server" options.
 * Some properties are overwritten based on the Quasar mode you're using in order
 * to ensure a correct config.
 * Note: if you're proxying the development server (i.e. using a cloud IDE),
 * set the `public` setting to your public application URL.
 */
devServer?: DevServerOptions;

除了这些选项外,Quasar CLI 还会修改其中一些配置,您使用时的体验会与普通 Vite 应用有所不同:

使用 open 属性可以指定用特定浏览器打开,而不是使用操作系统的默认浏览器(查看支持的值)。上述链接中描述的 options 参数就是您应该在 quasar.config file > devServer > open 中配置的内容。一些示例:

/quasar.config file

// opens Google Chrome
devServer: {
  open: {
    app: {
      name: 'google chrome'
    }
  }
}

// opens Firefox
devServer: {
  open: {
    app: {
      name: 'firefox'
    }
  }
}

// opens Google Chrome and automatically deals with cross-platform issues:
import open from 'open'

devServer: {
  open: {
    app: {
      name: open.apps.chrome
    }
  }
}

你也可以配置自动打开远程 Vue Devtools:

/quasar.config file

devServer: {
  vueDevtools: true
}

build

import { Plugin, UserConfig as ViteUserConfig } from 'vite'
import { Options as VuePluginOptions } from '@vitejs/plugin-vue'
import { CompilerOptions, TypeAcquisition } from 'typescript'
import { QuasarHookParams } from './conf'
import type { Options as VueRouterVitePluginOptions } from 'vue-router/dist/unplugin/options.d.mts'

interface HtmlMinifierOptions {
  caseSensitive?: boolean
  collapseBooleanAttributes?: boolean
  collapseInlineTagWhitespace?: boolean
  collapseWhitespace?: boolean
  conservativeCollapse?: boolean
  continueOnParseError?: boolean
  customAttrAssign?: RegExp[]
  customAttrCollapse?: RegExp
  customAttrSurround?: RegExp[]
  customEventAttributes?: RegExp[]
  decodeEntities?: boolean
  html5?: boolean
  ignoreCustomComments?: RegExp[]
  ignoreCustomFragments?: RegExp[]
  includeAutoGeneratedTags?: boolean
  keepClosingSlash?: boolean
  maxLineLength?: number
  minifyCSS?: boolean
  minifyJS?: boolean
  minifyURLs?: boolean
  preserveLineBreaks?: boolean
  preventAttributesEscaping?: boolean
  processConditionalComments?: boolean
  processScripts?: string[]
  quoteCharacter?: string
  removeAttributeQuotes?: boolean
  removeComments?: boolean
  removeEmptyAttributes?: boolean
  removeEmptyElements?: boolean
  removeOptionalTags?: boolean
  removeRedundantAttributes?: boolean
  removeScriptTypeAttributes?: boolean
  removeStyleLinkTypeAttributes?: boolean
  removeTagWhitespace?: boolean
  sortAttributes?: boolean
  sortClassName?: boolean
  trimCustomFragments?: boolean
  useShortDoctype?: boolean
}

// TSConfig type is adapted from https://github.com/unjs/pkg-types/blob/0bec64641468c9560dea95da2cff502ea8118286/src/types/tsconfig.ts
type StripEnums<T extends Record<string, any>> = {
  [K in keyof T]: T[K] extends boolean
    ? T[K]
    : T[K] extends string
      ? T[K]
      : T[K] extends object
        ? T[K]
        : T[K] extends Array<any>
          ? T[K]
          : T[K] extends undefined
            ? undefined
            : any
}

interface PluginEntryRunOptions {
  readonly server?: boolean
  readonly client?: boolean
}

type PluginEntry =
  | [pluginName: string, options?: any, runOptions?: PluginEntryRunOptions]
  | [
      pluginFactory: (options?: any) => Plugin,
      options?: any,
      runOptions?: PluginEntryRunOptions
    ]
  | Plugin
  | null
  | undefined
  | false

interface QuasarStaticBuildConfiguration {
  /**
   * @default
   * {
   *   browser: 'baseline-widely-available',
   *   node: 'node22'
   * }
   * @example
   * {
   *   browser: ['es2022', 'firefox115', 'chrome115', 'safari14'],
   *   node: 'node24'
   * }
   */
  target?: {
    /**
     * @default 'baseline-widely-available'
     * @example ['es2022', 'firefox115', 'chrome115', 'safari14']
     */
    browser?: string | string[]
    /**
     * @example 'node22'
     */
    node?: string
  }

  /**
   * Public path of your app.
   * Use it when your public path is something else,
   * like _“<protocol>://<domain>/some/nested/folder”_ – in this case,
   * it means the distributables are in _“some/nested/folder”_ on your webserver.
   *
   * @default '/'
   */
  publicPath?: string

  /**
   * Sets [Vue Router mode](https://router.vuejs.org/guide/essentials/history-mode.html).
   * History mode requires configuration on your deployment web server too.
   * For Capacitor and Electron, it's always 'hash' for [compatibility reasons](https://github.com/quasarframework/quasar/issues/17322#issuecomment-2191987962).
   *
   * @default 'hash'
   */
  vueRouterMode?: 'hash' | 'history'

  /**
   * Sets Vue Router base.
   * Should not need to configure this, unless absolutely needed.
   */
  vueRouterBase?: string

  /**
   * Automatically open remote Vue Devtools when running in development mode.
   */
  vueDevtools?: boolean

  /**
   * Should the Vue Options API be available? If all your components only use Composition API
   * it would make sense performance-wise to disable Vue Options API for a compile speedup.
   *
   * @default false
   */
  vueOptionsAPI?: boolean

  /**
   * Folder where Quasar CLI should generate the distributables.
   * Relative path to project root directory.
   *
   * @default 'dist/{ctx.modeName}' For all modes except Cordova.
   * @default 'src-cordova/www' For Cordova mode.
   */
  distDir?: string

  /**
   * Extend the Vite config generated by Quasar CLI.
   *
   * Can directly modify the "config" parameter or
   * return a new one that will be merged with the default one.
   *
   * @example
   * // return overrides
   * extendViteConf: (config) => ({
   *   optimizeDeps: {
   *     include: ['some-package']
   *   }
   * })
   *
   * @example
   * // directly modify the config object
   * extendViteConf(config) {
   *   config.optimizeDeps ||= {}
   *   config.optimizeDeps.include ||= []
   *   config.optimizeDeps.include.push('some-package)
   * }
   */
  extendViteConf?: (
    config: ViteUserConfig,
    invokeParams: {
      readonly isClient: boolean
      readonly isServer: boolean
    }
  ) => ViteUserConfig | void | Promise<ViteUserConfig | void>

  /**
   * Should you want to use Vue Router's filename-based routing feature.
   * Set to `true` or an options object for vue-router/vite plugin (to override
   * or add to the default options).
   *
   * Restart the dev server and your IDE when toggling this option,
   * or run "quasar prepare" command.
   *
   * https://v2.quasar.dev/quasar-cli-vite/page-routing-with-vue-router#filename-based-routing
   *
   * https://router.vuejs.org/file-based-routing/configuration.html
   *
   * Default options supplied to vue-router/vite plugin when enabled:
   * @example
   * {
   *   // where are paths relative to:
   *   root: <root_project_dir>,
   *   // where to generate the types (if on TypeScript projects):
   *   dts: './src/router/typed-router.d.ts',
   * }
   *
   * @default false
   */
  filenameBasedRouting?: boolean | VueRouterVitePluginOptions

  /**
   * Options to supply to @vitejs/plugin-vue
   *
   * @see https://v2.quasar.dev/quasar-cli-vite/handling-vite#vite-vue-plugin-options
   */
  viteVuePluginOptions?: VuePluginOptions

  /**
   * Vite plugins
   *
   * @see https://v2.quasar.dev/quasar-cli-vite/handling-vite#adding-vite-plugins
   *
   * @example
   * import { somePlugin } from 'some-plugin'
   * // ...
   * [
   *   [ 'some-plugin', { ...pluginOptions... } ],
   *
   *   // disable running on client or server threads (set server/client to false):
   *   [ 'some-plugin', { ...pluginOptions... }, { server: true, client: true } ],
   *
   *   [ somePlugin, { ...pluginOptions... } ],
   *
   *   // disable running on client or server threads (set server/client to false):
   *   [ somePlugin, { ...pluginOptions... }, { server: true, client: true } ],
   *
   *   somePlugin({ ...pluginOptions... })
   * ]
   */
  vitePlugins?: PluginEntry[]

  /**
   * @see https://v2.quasar.dev/quasar-cli-vite/handling-vite#folder-aliases
   *
   * Quasar CLI automatically injects the following aliases:
   *   - `#q-app` to the Quasar CLI itself
   *   - `@/` to the /src directory
   *
   * Use only absolute paths. You can use ctx.appPaths for it,
   * for example: `ctx.appPaths.srcDir` or `ctx.appPaths.resolve.app('src/locales')`.
   *
   * @example
   * {
   *   // import { ... } from 'locales/...'
   *   locales: ctx.appPaths.resolve.app('src/locales')
   * }
   *
   * @example
   * {
   *   // import { ... } from 'locales/...'
   *   locales: path.join(import.meta.dirname, 'src/locales')
   * }
   */
  alias?: { [key: string]: string }

  /**
   * Configuration for TypeScript integration.
   */
  typescript?: {
    /**
     * Once your codebase is fully using TypeScript and all team members are comfortable with it,
     * you can set this to `true` to enforce stricter type checking.
     * It is recommended to set this to `true` and use stricter typescript-eslint rules.
     *
     * It will set the following TypeScript options:
     * - "strict": true
     * - "allowUnreachableCode": false
     * - "allowUnusedLabels": false
     * - "noImplicitOverride": true
     * - "exactOptionalPropertyTypes": true
     * - "noUncheckedIndexedAccess": true
     *
     * @see https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html#getting-stricter-checks
     */
    strict?: boolean

    /**
     * Extend the generated `.quasar/tsconfig.json` file.
     *
     * If you don't have dynamic logic, you can directly modify your `tsconfig.json` file instead.
     */
    extendTsConfig?: (tsConfig: {
      compilerOptions?: StripEnums<CompilerOptions>
      exclude?: string[]
      compileOnSave?: boolean
      extends?: string | string[]
      files?: string[]
      include?: string[]
      typeAcquisition?: TypeAcquisition
    }) => void

    /**
     * Generate a shim file for `*.vue` files to process them as plain Vue component instances.
     *
     * Vue Language Tools VS Code extension can analyze `*.vue` files in a better way, without the shim file.
     * So, you can disable the shim file generation and let the extension handle the types.
     *
     * However, some tools like ESLint can't work with `*.vue` files without the shim file.
     * So, if your tooling is not properly working, enable this option.
     */
    vueShim?: boolean
  }

  /**
   * Define global constant replacements. Entries will be defined as globals
   * during dev and statically replaced during build.
   *
   * This gets supplied to Vite's & Rolldown's own "define" option,
   * which in turn uses Oxc's "define" feature to perform replacements.
   *
   * All non-string values are automatically JSON.stringified by Quasar CLI.
   * This ensures consistency between Vite & Rolldown builds and avoids Rolldown to fail.
   *
   * @example { __APP_VERSION__: JSON.stringify('v1.0.0') }
   * @example { __API_URL__: 'window.__backend_api_url' }
   */
  define?: Record<
    string,
    string | number | boolean | undefined | null | any[] | Record<string, any>
  >

  /**
   * Sugar for `define` option. Define global constant replacements that will
   * be automatically transformed into "define" entries with the `import.meta.env` prefix
   * and already JSON-stringified.
   *
   * @example { SOME_DEFINE: 'my-string' } will be transformed into { 'import.meta.env.SOME_DEFINE': '"my-string"' }
   * @example { VERSION: 22 } will be transformed into { 'import.meta.env.VERSION': '22' }
   */
  defineEnv?: Record<
    string,
    string | number | boolean | undefined | null | any[] | Record<string, any>
  >

  /**
   * Configuration related to the environment variables loaded from
   * .env* files and Node.js process.env injections.
   */
  env?: {
    /**
     * For security reasons, only variables with this prefix from the env files
     * and Node.js process.env will be exposed to the code shipped to the client.
     * The client app code includes Electron main & preload scripts, as they get
     * shipped to the client side as well.
     *
     * Such variables exposed to the client app code should not contain sensitive
     * information such as API keys.
     *
     * Avoid setting it to 'QUASAR_' so it won't conflict with
     * Quasar's own environment variables.
     *
     * Setting it to an empty string will default to
     * the default value (QCLI_).
     *
     * @default 'QCLI_'
     */
    clientPrefix?: string | string[]
    /**
     * Setting this prefix will filter out env files variables and Node.js process.env
     * variables that are exposed to the backend code (like the SSR server-side).
     *
     * Avoid setting it to 'QUASAR_' so it won't conflict with
     * Quasar's own environment variables.
     *
     * @default ''
     */
    backendPrefix?: string | string[]
    /**
     * Folder where Quasar CLI should look for .env* files.
     * Can be an absolute path or a relative path to project root directory.
     *
     * @default appPaths.appDir
     */
    folder?: string | string[]
    /**
     * Additional .env* files to be loaded.
     * Each entry can be an absolute path or a relative path to
     * quasar.config > build > env > folder.
     *
     * @example ['.env.somefile', '../.env.someotherfile']
     */
    file?: string | string[]
    /**
     * Filter the env files variables & Node.js process.env variables
     * that are exposed to the app code. This does not affects props
     * assigned directly to the quasar.config > build > define prop.
     */
    filter?: (
      env: Record<string, string>,
      type: 'client' | 'backend'
    ) => Record<string, string>
  }

  /**
   * Build production assets with or without the hash part in filenames.
   * Example: "454d87bd" in "@/assets/index.454d87bd.js"
   *
   * When used, please be careful how you configure your web server cache strategy as
   * files will not change name so your client might get 304 (Not Modified) even when
   * it's not the case.
   *
   * Will not change anything if your Vite config already touches the
   * build.rolldownOptions.output.entryFileNames/chunkFileNames/assetFileNames props.
   *
   * Gets applied to production builds only.
   *
   * Useful especially for (but not restricted to) PWA. If set to false then updating the
   * PWA will force to re-download all assets again, regardless if they were changed or
   * not (due to how Rolldown works through Vite).
   *
   * @default true
   */
  useFilenameHashes?: boolean

  /**
   * Ignores the public folder.
   * @default false
   */
  ignorePublicFolder?: boolean

  /**
   * Prepare external services before `$ quasar dev` command runs
   * like starting some backend or any other service that the app relies on.
   * Can use async/await or directly return a Promise.
   */
  beforeDev?: (params: QuasarHookParams) => void
  /**
   * Run hook after Quasar dev server is started (`$ quasar dev`).
   * At this point, the dev server has been started and is available should you wish to do something with it.
   * Can use async/await or directly return a Promise.
   */
  afterDev?: (params: QuasarHookParams) => void
  /**
   * Run hook before Quasar builds app for production (`$ quasar build`).
   * At this point, the distributables folder hasn’t been created yet.
   * Can use async/await or directly return a Promise.
   */
  beforeBuild?: (params: QuasarHookParams) => void
  /**
   * Run hook after Quasar built app for production (`$ quasar build`).
   * At this point, the distributables folder has been created and is available
   *  should you wish to do something with it.
   * Can use async/await or directly return a Promise.
   */
  afterBuild?: (params: QuasarHookParams) => void
  /**
   * Run hook if publishing was requested (`$ quasar build -P`),
   *  after Quasar built app for production and the afterBuild hook (if specified) was executed.
   * Can use async/await or directly return a Promise.
   * `opts` is Object of form `{arg, distDir}`,
   * where “arg” is the argument supplied (if any) to -P parameter.
   */
  onPublish?: (ops: { arg: string; distDir: string }) => void
}

/**
 * Following properties of `build` are automatically configured by Quasar CLI
 *  depending on dev/build commands and Quasar mode.
 * You can override some, but make sure you know what you are doing.
 */
interface QuasarDynamicBuildConfiguration {
  /**
   * Set to `false` to disable minification, or specify the minifier to use.
   * Available options are 'oxc' (recommended) or 'terser'.
   * If set to anything but boolean false then it also applies to CSS.
   * For production only.
   * @default 'oxc'
   */
  minify?: boolean | 'oxc' | 'terser'
  /**
   * Minification options for html-minifier-terser.
   *
   * @see https://github.com/terser/html-minifier-terser?tab=readme-ov-file#options-quick-reference for complete list of options
   *
   * @default
   *  {
   *    removeComments: true,
   *    collapseWhitespace: true,
   *    removeAttributeQuotes: true,
   *    collapseBooleanAttributes: true,
   *    removeScriptTypeAttributes: true
   *  }
   */
  htmlMinifyOptions?: HtmlMinifierOptions
  /**
   * If `true`, a separate sourcemap file will be created. If 'inline', the
   * sourcemap will be appended to the resulting output file as data URI.
   * 'hidden' works like `true` except that the corresponding sourcemap
   * comments in the bundled files are suppressed.
   * @default false
   */
  sourcemap?: boolean | 'inline' | 'hidden'
}

See these references for more info:

sourceFiles

/**
 * Use this property to change the default names of some files of your website/app if you have to.
 * All paths must be relative to the root folder of your project.
 *
 * @default
 * {
 *  rootComponent: 'src/App.vue',
 *  router: 'src/router/index',
 *  store: 'src/stores/index',
 *  pwaRegisterServiceWorker: 'src-pwa/register-sw',
 *  pwaServiceWorker: 'src-pwa/sw/custom-sw',
 *  pwaManifestFile: 'src-pwa/manifest.json',
 *  electronMain: 'src-electron/electron-main',
 *  bexManifestFile: 'src-bex/manifest.json'
 * }
 */
interface QuasarSourceFilesConfiguration {
  rootComponent?: string
  router?: string
  store?: string
  pwaRegisterServiceWorker?: string
  pwaServiceWorker?: string
  pwaManifestFile?: string
  electronMain?: string
  bexManifestFile?: string
}

htmlVariables

/** Add variables that you can use in /index.html. */
htmlVariables?: Record<string, any>;

你可以定义变量,然后在 /index.html 中引用它们,示例如下:

/quasar.config file

import { defineConfig } from '#q-app'

export default defineConfig(ctx => {
  return {
    htmlVariables: {
      myVar: 'some-content'
    }
  }
})

然后在模板中使用:

/index.html

<%= myVar %> <% if (myVar) { %>something<% } %>

再来一个例子:

/quasar.config file

htmlVariables: {
  title: 'test name',
  some: {
    prop: 'my-prop'
  }
}

然后在模板中使用:

/index.html

<%= title %> <%= some.prop %> <% if (some.prop) { %><%= title %><% } %>

Quasar Mode Specific

PropertyTypeDescription
cordovaObjectCordova specific config.
capacitorObjectQuasar CLI Capacitor specific config.
pwaObjectPWA specific config.
ssrObjectSSR specific config.
electronObjectElectron specific config.
bexObjectBEX specific config.

其他有用链接