為何捐款
API 瀏覽器
升級指南
NEW!
quasar.config 檔案
轉換專案至搭配 Vite 的 CLI
瀏覽器相容性
支援 TypeScript
目錄結構
命令列表
CSS 預處理器
路由
懶加載 - 程式碼分割
處理資源
啟動檔案
預先載入功能
API 代理
處理 Vite
處理 process.env
使用 Pinia 的狀態管理
使用 Vuex 的狀態管理
Linter
測試 & 稽核
開發行動應用程式
Ajax 請求
對外開放開發伺服器
搭配 Vite 的 Quasar CLI - @quasar/app-vite
支援 TypeScript

預設情況下,您的專案未新增 Typescript 支援 (除非您在建立專案資料夾時選擇了 TS),但您可以依照此頁面上的指南輕鬆整合。

提示

只有在您建立全新的 Quasar 專案時**未**選擇 TypeScript 支援時,才需要執行以下步驟。如果您在專案建立時選擇了 TS 選項,則 TypeScript 支援已啟用。

安裝 TypeScript 支援

在您的專案根目錄中建立 /tsconfig.json 檔案,並包含以下內容

{
  "extends": "@quasar/app-vite/tsconfig-preset",
  "compilerOptions": {
    // `baseUrl` should be set to the current folder to allow Quasar TypeScript preset to manage paths on your behalf
    "baseUrl": "."
  },
  "exclude": [
    "./dist",
    "./.quasar",
    "./node_modules",
    "./src-capacitor",
    "./src-cordova",
    "./quasar.config.*.temporary.compiled*"
  ]
}

然後安裝 typescript 套件


$ yarn add --dev typescript

現在您可以開始在專案中使用 TypeScript。請注意,某些 IDE 可能需要重新啟動才能完全啟用新的設定。

提示

請記住,您必須將 JavaScript 檔案的副檔名變更為 .ts,才能在其中撰寫 TypeScript 程式碼。若要在您的元件中撰寫 TS 程式碼,請將 script 開啟標籤變更為 <script lang="ts">

警告

如果您未新增 tsconfig.json 檔案,應用程式將在編譯時中斷!

Linting 設定

提示

由於類型檢查的額外負擔,TypeScript Linting 速度非常慢,我們建議您在 /quasar.config 檔案中針對開發版本停用它。

首先新增所需的依賴項


$ yarn add --dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
# you might also want to install the `eslint-plugin-vue` package.

然後相應地更新您的 ESLint 設定,如下列範例所示

/.eslintrc.cjs

const { resolve } = require('node:path');

module.exports = {
  // https://eslint.dev.org.tw/docs/user-guide/configuring#configuration-cascading-and-hierarchy
  // This option interrupts the configuration hierarchy at this file
  // Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
  root: true,

  // https://eslint.vuejs.org/user-guide/#how-to-use-custom-parser
  // Must use parserOptions instead of "parser" to allow vue-eslint-parser to keep working
  // `parser: 'vue-eslint-parser'` is already included with any 'plugin:vue/**' config and should be omitted
  parserOptions: {
    // https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/parser#configuration
    // https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#eslint
    // Needed to make the parser take into account 'vue' files
    extraFileExtensions: ['.vue'],
    parser: '@typescript-eslint/parser',
    project: resolve(__dirname, './tsconfig.json'),
    tsconfigRootDir: __dirname,
    ecmaVersion: 2021, // Allows for the parsing of modern ECMAScript features
    sourceType: 'module', // Allows for the use of imports
  },

  // Rules order is important, please avoid shuffling them
  extends: [
    // Base ESLint recommended rules
    'eslint:recommended',

    // https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
    // ESLint typescript rules
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended',
    // consider disabling this class of rules if linting takes too long
    'plugin:@typescript-eslint/recommended-requiring-type-checking',

    // https://eslint.vuejs.org/rules/#priority-a-essential-error-prevention
    // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules
    'plugin:vue/essential',

    // --- ONLY WHEN USING PRETTIER ---
    // https://github.com/prettier/eslint-config-prettier#installation
    // usage with Prettier, provided by 'eslint-config-prettier'.
    'prettier',
    'prettier/@typescript-eslint',
    'prettier/vue',
  ],

  plugins: [
    // required to apply rules which need type information
    '@typescript-eslint',

    // https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-file
    // required to lint *.vue files
    'vue',
  ],

  // add your custom rules here
  rules: {
    // others rules...

    // TypeScript
    'quotes': ['warn', 'single'],
    // this rule, if on, would require explicit return type on the `render` function
    '@typescript-eslint/explicit-function-return-type': 'off',
    // in plain CommonJS modules, you can't use `import foo = require('foo')` to pass this rule, so it has to be disabled
    '@typescript-eslint/no-var-requires': 'off',
  }
}

如果有任何問題,請參閱 typescript-eslint 指南,此範例即以此為基礎。

最後,更新您的 yarn lint 命令,以同時 lint .ts 檔案。

最後,編輯您的 /quasar.config 檔案

/quasar.config 檔案

eslint: {
  // fix: true,
  // include: [],
  // exclude: [],
  // rawOptions: {},
  warnings: true,
  errors: true
},

TypeScript 宣告檔案

如果您在搭建專案時選擇了 TypeScript 支援,這些宣告檔案會自動為您搭建。如果專案建立期間未啟用 TypeScript 支援,請建立下列檔案。

/src/shims-vue.d.ts

/* eslint-disable */

/// <reference types="vite/client" />

// Mocks all files ending in `.vue` showing them as plain Vue instances
declare module '*.vue' {
  import type { DefineComponent } from 'vue';
  const component: DefineComponent<{}, {}, any>;
  export default component;
}
/src/quasar.d.ts

/* eslint-disable */

// Forces TS to apply `@quasar/app-vite` augmentations of `quasar` package
// Removing this would break `quasar/wrappers` imports as those typings are declared
//  into `@quasar/app-vite`
// As a side effect, since `@quasar/app-vite` reference `quasar` to augment it,
//  this declaration also apply `quasar` own
//  augmentations (eg. adds `$q` into Vue component context)
/// <reference types="@quasar/app-vite" />
/src/env.d.ts

/* eslint-disable */

declare namespace NodeJS {
  interface ProcessEnv {
    NODE_ENV: string;
    VUE_ROUTER_MODE: 'hash' | 'history' | 'abstract' | undefined;
    VUE_ROUTER_BASE: string | undefined;
    // Define any custom env variables you have here, if you wish
  }
}

請參閱以下章節,具體取決於您使用的功能和建置模式。

Pinia

如果您使用 Pinia,請將以下章節新增至您的專案。Quasar CLI 提供 router 屬性,如果您有更多全域屬性,可能需要新增。

/src/stores/index.ts

import { Router } from 'vue-router';

/*
 * When adding new properties to stores, you should also
 * extend the `PiniaCustomProperties` interface.
 * @see https://pinia.vuejs.org/core-concepts/plugins.html#typing-new-store-properties
 */
declare module 'pinia' {
  export interface PiniaCustomProperties {
    readonly router: Router;
  }
}

Vuex

如果您使用 Vuex,請將以下章節新增至您的專案。Quasar CLI 提供 router 屬性,如果您有更多全域屬性,可能需要新增。調整狀態介面以符合您的應用程式。

/src/store/index.ts

import { InjectionKey } from 'vue'
import { Router } from 'vue-router'
import {
  createStore,
  Store as VuexStore,
  useStore as vuexUseStore,
} from 'vuex'

export interface StateInterface {
  // Define your own store structure, using submodules if needed
  // example: ExampleStateInterface;
  // Declared as unknown to avoid linting issue. Best to strongly type as per the line above.
  example: unknown
}

// provide typings for `this.$store`
declare module 'vue' {
  interface ComponentCustomProperties {
    $store: VuexStore<StateInterface>
  }
}

// Provide typings for `this.$router` inside Vuex stores
declare module "vuex" {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  export interface Store<S> {
    readonly $router: Router;
  }
}

// provide typings for `useStore` helper
export const storeKey: InjectionKey<VuexStore<StateInterface>> = Symbol('vuex-key')

export function useStore() {
  return vuexUseStore(storeKey)
}

// createStore<StateInterface>({ ... })

PWA 模式

如果您使用 PWA 模式,請對您的專案進行以下修改,並建立任何不存在的檔案

/src-pwa/pwa-env.d.ts

/* eslint-disable */

declare namespace NodeJS {
  interface ProcessEnv {
    SERVICE_WORKER_FILE: string;
    PWA_FALLBACK_HTML: string;
    PWA_SERVICE_WORKER_REGEX: string;
  }
}
/src-pwa/custom-service-worker.ts

// at the top of the file
declare const self: ServiceWorkerGlobalScope &
  typeof globalThis & { skipWaiting: () => void };
/src-pwa/tsconfig.json

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "lib": ["WebWorker", "ESNext"]
  },
  "include": ["*.ts", "*.d.ts"]
}
/src-pwa/.eslintrc.cjs

const { resolve } = require('node:path');

module.exports = {
  parserOptions: {
    project: resolve(__dirname, './tsconfig.json'),
  },

  overrides: [
    {
      files: ['custom-service-worker.ts'],

      env: {
        serviceworker: true,
      },
    },
  ],
};

Electron 模式

如果您使用 Electron 模式,請將以下章節新增至您的專案。

/src-electron/electron-env.d.ts

/* eslint-disable */

declare namespace NodeJS {
  interface ProcessEnv {
    QUASAR_PUBLIC_FOLDER: string;
    QUASAR_ELECTRON_PRELOAD_FOLDER: string;
    QUASAR_ELECTRON_PRELOAD_EXTENSION: string;
    APP_URL: string;
  }
}

BEX 模式

如果您使用 BEX 模式,請將以下章節新增至您的專案。您可能需要根據您使用的事件調整它。關鍵是事件名稱,值是一個元組,其中第一個元素是輸入,第二個元素是輸出類型。

/src-bex/background.ts

declare module '@quasar/app-vite' {
  interface BexEventMap {
    /* eslint-disable @typescript-eslint/no-explicit-any */
    log: [{ message: string; data?: any[] }, never];
    getTime: [never, number];

    'storage.get': [{ key: string | null }, any];
    'storage.set': [{ key: string; value: any }, any];
    'storage.remove': [{ key: string }, any];
    /* eslint-enable @typescript-eslint/no-explicit-any */
  }
}