Quasar CLI with Vite - @quasar/app-vite
配置quasar.config.js

注意你的脚手架项目文件夹包含一个/quasar.config.js文件。那么你可以通过它配置什么呢?基本上是Quasar CLI为你做的任何事情。

  • 您将在您的网站/应用程序中使用的Quasar组件、指令和插件
  • 默认的Quasar语言包
  • 你想使用的图标库
  • Quasar组件的默认的Quasar图标集
  • 开发服务器端口、HTTPS模式、主机名等
  • 你想使用的CSS动画
  • 启动文件 列表(也决定了执行顺序) - 这是/src/boot中的文件,告诉你在安装根Vue组件之前如何初始化应用程序
  • bundle中包含的全局CSS/Sass/…文件
  • SPA、PWA、Electron、Capacitor、Cordova、SSR、BEX(浏览器扩展)配置
  • 扩展引擎盖下的工具,如生成的Vite配置
  • …还有很多很多,你会在学习过程中发现。

TIP

您会注意到,更改任何这些设置不需要您手动重新加载开发服务器。 Quasar检测是否可以通过热模块更换 注入更改,如果不能,则会自动重新加载开发服务器。 您不会丢失开发流程,因为您只需坐等Quasar CLI快速重新加载更改的代码,甚至保持当前状态。 这节省了大量的时间!

WARNING

/quasar.config.js由Quasar CLI构建系统运行,因此这些配置代码直接在Node下运行,而不是在应用程序的上下文中运行。这意味着你可以导入像’fs’,‘path’,'webpack’等模块。确保您在此文件编写的ES6功能受安装的Node版本(应该>=14.19.0)支持。

结构

基础

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

module.exports = function (ctx) { // 也可以是异步的
  console.log(ctx)

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

  // 根据这些参数上下文将会被创建
  // 当你运行"quasar dev"或"quasar build"时
}

这意味着,作为一个例子,您可以在构建特定模式(如PWA)时加载字体,并为其他模式选择另一个:

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

或者,您可以使用一个全局CSS文件用于SPA模式,使用另一个用于Cordova模式,同时避免为其他模式加载任何此类文件。

module.exports = function (ctx) {
  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
  ]
}

或者,您可以将开发服务器配置为在端口8000上运行SPA模式,在端口9000上运行PWA模式或在端口9090上运行其他模式:

module.exports = function (ctx) {
  devServer: {
    port: ctx.mode.spa
      ? 8000
      : (ctx.mode.pwa ? 9000 : 9090)
  }
}

您也可以在返回Quasar配置之前执行异步工作:

module.exports = async function (ctx) {
  const data = await someAsyncFunction()
  return {
    // ... use "data"
  }
}

// or:
module.exports = function (ctx) {
  return new Promise(resolve => {
    // some async work then:
    // resolve() with the quasar config
    resolve({
      //
    })
  })
}

可能性是无止境的。

IDE autocompletion

可以用configure()助手包装返回的函数,以获得更好的IDE自动完成体验(通过Typescript):

const { configure } = require('quasar/wrappers')

module.exports = configure(function (ctx) {
  /* configuration options */
})

配置选项

让我们逐个采取每个选项:

css

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

例:

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

boot

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

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

type QuasarBootConfiguration = (string | BootConfigurationItem)[];

preFetch

更多信息在预取功能

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

eslint

你将需要已经安装的linting文件。如果你不知道那些文件是什么,可以建立一个新的Quasar项目文件夹(yarn create quasarnpm init quasar或实验性的pnpm create quasar),并在被问及时选择 “Linting”。

/** Options with which Quasar CLI will use ESLint */
eslint?: QuasarEslintConfiguration;

interface QuasarEslintConfiguration {
  /**
   * Should it report warnings?
   * @default true
   */
  warnings?: boolean;

  /**
   * Should it report errors?
   * @default true
   */
  errors?: boolean;

  /**
   * Fix on save
   */
  fix?: boolean;

  /**
   * Raw options to send to ESLint
   */
  rawOptions?: object;

  /**
   * Files to include (can be in glob format)
   */
  include?: string[];

  /**
   * Files to exclude (can be in glob format).
   * Recommending to use .eslintignore file instead.
   */
  exclude?: string[];
}

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.
 */
framework?: QuasarFrameworkConfiguration;

interface QuasarFrameworkConfiguration {
  config?: /* Quasar UI config -- you'll notice in docs when you need it */;

  /**
   * one of the Quasar IconSets (see specific docs page)
   * @example 'material-icons'
   */
  iconSet?: QuasarIconSets;

  /**
   * one of the Quasar language pack in String format (see specific docs page)
   * @example 'en-US' / 'es' / 'he' / ...
   */
  lang?: QuasarLanguageCodes;

  /* if you want the Quasar CSS Addons (see specific docs page) */
  cssAddon?: boolean;

  /**
   * Format in which you will write your Vue templates when
   * using Quasar components.
   *
   * @default 'kebab'
   */
  autoImportComponentCase?: "kebab" | "pascal" | "combined";

  /**
   * For special cases outside of where the auto-import strategy can have an impact
   * (like plain .js or .ts files),
   * you can manually specify Quasar components/directives to be available everywhere.
   * @example [ 'QAvatar', 'QChip' ]
   */
  components?: (keyof QuasarPluginOptions["components"])[];
  directives?: (keyof QuasarPluginOptions["directives"])[];

  /**
   * Quasar plugins.
   * @example [ 'Notify', 'Loading', 'Meta', 'AppFullscreen' ]
   */
  plugins?: (keyof QuasarPluginOptions["plugins"])[];
}

更多关于cssAddon在这里

animations

更多关于css动画在这里

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

devServer

更多信息: Vite服务器选项

import { ServerOptions } from "vite";

/**
 * 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?: ServerOptions;

除了这些选项之外,Quasar CLI还对一些选项进行了修改,你的体验将与Vite应用程序不同。

使用open参数来打开一个特定的浏览器,而不是使用你的操作系统的默认浏览器(查看支持的值)。前面链接中描述的options参数是你应该配置的 quasar.config.js > devSever > open with. 一些例子:

// quasar.config.js

// 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:
const open = require('open')

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

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

// quasar.config.js

devServer: {
  vueDevtools: true
}

build

/** Build configuration options. */
build?: QuasarBuildConfiguration;

import { UserConfig as ViteUserConfig } from "vite";
import { Options as VuePluginOptions } from "@vitejs/plugin-vue"

interface BuildTargetOptions {
  /**
   * @default ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1']
   */
  browser?: string[];
  /**
   * @example 'node16'
   */
  node: string;
}

interface QuasarStaticBuildConfiguration {
  /**
   * @example
   *    {
   *      browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'],
   *      node: 'node16'
   *    }
   */
  target?: BuildTargetOptions;

  /**
   * Extend Vite config generated by Quasar CLI.
   */
  extendViteConf?: (
    config: ViteUserConfig,
    invokeParams: InvokeParams
  ) => void;

  /**
   * Options to supply to @vitejs/plugin-vue
   */
  viteVuePluginOptions?: VuePluginOptions;

  /**
   * Vite plugins
   *
   * @example
   *   [
   *     [ 'package-name', { ..options.. } ],
   *     [ require('some-plugin'), { ...options... } ]
   *   ]
   */
  vitePlugins?: object[];

  /**
   * @example setting an alias for a custom folder
   *    {
   *       locales: path.join(__dirname, 'src/locales')
   *    }
   */
  alias?: object[];

  /**
   * 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.
   *
   * @default 'hash'
   */
  vueRouterMode?: "hash" | "history";

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

  /**
   * 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 true
   */
  vueOptionsAPI?: boolean;

  /**
   * Should we invalidate the Vite and ESLint cache on startup?
   * @default false
   */
  rebuildCache?: boolean;

  /**
   * Do you want to analyze the production bundles?
   * Generates and opens an html report.
   * @default false
   */
  analyze?: 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;

  /**
   * Add properties to `process.env` that you can use in your website/app JS code.
   *
   * @example { SOMETHING: 'someValue' }
   */
  env?: { [index: string]: string };

  /**
   * Defines constants that get replaced in your app.
   *
   * @example { SOMETHING: JSON.stringify('someValue') } -> console.log(SOMETHING) // console.log('someValue')
   */
  rawDefine?: { [index: string]: string };

  /**
   * (requires @quasar/app-vite v1.1+)
   *
   * 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.rollupOptions.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 Rollup works through Vite).
   *
   * @default true
   */
  useFilenameHashes?: boolean;

  /**
   * whether to inject module preload polyfill.
   * @default false
   */
  polyfillModulePreload?: boolean;

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

  /**
   * Set to `false` to disable minification, or specify the minifier to use.
   * Available options are 'terser' or 'esbuild'.
   * If set to anything but boolean false then it also applies to CSS.
   * For production only.
   * @default 'esbuild'
   */
  minify?: boolean | 'terser' | 'esbuild';

  /**
   * 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';

  /**
   * (requires @quasar/app-vite v1.1.1+)
   *
   * Treeshake Quasar's UI on dev too?
   * Recommended to leave this as false for performance reasons.
   * @default false
   */
  devQuasarTreeshaking?: 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;
}

sourceFiles

sourceFiles?: QuasarSourceFilesConfiguration;

/**
 * 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', // for Pinia
 *  // store: 'src/store/index' // for Vuex
 *  pwaRegisterServiceWorker: 'src-pwa/register-service-worker',
 *  pwaServiceWorker: 'src-pwa/custom-service-worker',
 *  pwaManifestFile: 'src-pwa/manifest.json',
 *  electronMain: 'src-electron/electron-main',
 *  electronPreload: 'src-electron/electron-preload'
 * }
 */
interface QuasarSourceFilesConfiguration {
  rootComponent?: string;
  router?: string;
  store?: string;
  pwaRegisterServiceWorker?: string;
  pwaServiceWorker?: string;
  pwaManifestFile?: string;
  electronMain?: string;
  electronPreload?: string;
}

htmlVariables

/** Add variables that you can use in /index.html. */
htmlVariables?: { [index: string]: string };

你可以在/index.html中定义然后引用变量,像这样:

htmlVariables: {
  myVar: 'some-content'
}

// then in /index.html
<%= myVar %>
<% if (myVar) { %>something<% } %>

再举一个例子:

// quasar.config.js
module.exports = function (ctx) {
  return {
    htmlVariables: {
      title: 'test name',
      some: {
        prop: 'my-prop'
      }
    }

然后(只是一个例子,告诉你如何引用上面定义的变量,在这里是title):

<!-- /index.html -->
<%= title %>
<%= some.prop %>

具体的Quasar模式

属性类型描述
cordovaObjectCordova特定配置.
capacitorObjectQuasar CLI Capacitor特定配置.
pwaObjectPWA特定配置.
ssrObjectSSR特定配置.
electronObjectElectron特定配置.
bexObjectBEX特定配置.

例子

设置dev/build的环境

请参考我们文档中的添加到process.env中部分。

添加Vite插件

请参考处理Vite页面。