API 浏览器
应用扩展索引 API

本页引用 src/index.js 文件,该文件在 quasar devquasar build 上执行。这是你可以修改构建以满足应用扩展需求的主要流程。例如,注册启动文件、修改 webpack 进程、注册 CSS、注册 UI 组件、注册 Quasar CLI 命令等。

¥This page refers to src/index.js file, which is executed on quasar dev and quasar build. This is the main process where you can modify the build to suit the needs of your App Extension. For instance, registering a boot file, modifying the webpack process, registering CSS, registering a UI component, registering a Quasar CLI command, etc.

文件基本结构示例:

¥Example of basic structure of the file:

// can be async
export default function (api) {
  // props & methods for "api" Object described below
}

api.ctx(api.ctx)

/quasar.config 文件中的 ctx 相同。帮助你根据 quasar devquasar build 的运行环境做出决策。

¥Same as the ctx from the /quasar.config file. Helps you make decisions based on the context in which quasar dev or quasar build runs.

示例:如果仅在 Electron 模式下运行,你可能需要使用其中一种 api 方法。

¥Example: You might want to use one of the api methods if running for electron mode only.

if (api.ctx.dev === true && api.ctx.mode.electron === true) {
  api.beforeDev((api) => {
    // do something when running quasar dev and
    // with Electron mode
  })
}

api.engine(api.engine)

包含正在使用的 Quasar CLI 引擎(以字符串形式)。示例:@quasar/app-vite@quasar/app-webpack

¥Contains the Quasar CLI engine (as String) being used. Examples: @quasar/app-vite or @quasar/app-webpack.

api.hasVite(api.hasVite)

布尔值 - 是否在 @quasar/app-vite 上运行。

¥Boolean - is running on @quasar/app-vite or not.

api.hasWebpack(api.hasWebpack)

布尔值 - 是否在 @quasar/app-webpack 上运行。

¥Boolean - is running on @quasar/app-webpack or not.

api.extId(api.extId)

包含此应用扩展的 ext-id(字符串)。

¥Contains the ext-id (String) of this App Extension.

api.prompts(api.prompts)

是一个对象,其中包含此应用扩展安装时提示的答案。更多提示信息,请查看 提示 API

¥Is an Object which has the answers to the prompts when this App Extension got installed. For more info on prompts, check out Prompts API.

api.resolve(api.resolve)

解析此应用扩展程序正在运行的应用内的路径。无需导入 path 并自行解析路径。

¥Resolves paths within the app on which this App Extension is running. Eliminates the need to import path and resolve the paths yourself.

// resolves to root of app
api.resolve.app('src/my-file.js')

// resolves to root/src of app
api.resolve.src('my-file.js')

// resolves to root/public of app
// (@quasar/app-webpack v3.4+ or @quasar/app-vite v1+)
api.resolve.public('my-image.png')

// resolves to root/src-pwa of app
api.resolve.pwa('some-file.js')

// resolves to root/src-ssr of app
api.resolve.ssr('some-file.js')

// resolves to root/src-cordova of app
api.resolve.cordova('config.xml')

// resolves to root/src-electron of app
api.resolve.electron('some-file.js')

// resolves to root/src-electron of app
api.resolve.electron('some-file.js')

// resolves to root/src-bex of app
api.resolve.bex('some-file.js')

api.appDir(api.appDir)

包含运行此应用扩展程序的应用根目录的完整路径(字符串)。

¥Contains the full path (String) to the root of the app on which this App Extension is running.

api.hasTypescript
@quasar/app-vite 1.6+
@quasar/app-webpack 3.11+
(api.hasTypescript
@quasar/app-vite 1.6+
@quasar/app-webpack 3.11+
)

/**

 * @return {Promise<boolean>} host project has Typescript active or not
 */
await api.hasTypescript()

api.hasLint
@quasar/app-vite 1.6+
@quasar/app-webpack 3.11+
(api.hasLint
@quasar/app-vite 1.6+
@quasar/app-webpack 3.11+
)

/**

 * @return {Promise<boolean>} host project has ESLint or not
 */
await api.hasLint()

api.getStorePackageName
@quasar/app-vite 1.6+
@quasar/app-webpack 3.11+
(api.getStorePackageName
@quasar/app-vite 1.6+
@quasar/app-webpack 3.11+
)

/**

 * @return {Promise<string|undefined>} 'pinia' | 'vuex' | undefined
 */
await api.getStorePackageName()

api.getNodePackagerName
@quasar/app-vite 1.6+
@quasar/app-webpack 3.11+
(api.getNodePackagerName
@quasar/app-vite 1.6+
@quasar/app-webpack 3.11+
)

/**

 * @return {Promise<'npm' | 'yarn' | 'pnpm' | 'bun'>}
 */
await api.getNodePackagerName()

api.compatibleWith(api.compatibleWith)

通过语义版本条件确保应用扩展与主机应用中安装的软件包兼容。

¥Ensure the App Extension is compatible with a package installed in the host app through a semver condition.

如果不满足语义版本条件,@quasar/app 将报错并停止执行。

¥If the semver condition is not met, then @quasar/app errors out and halts execution.

语义版本条件示例:'1.x || >=2.5.0 || 5.0.0 - 7.2.3'

¥Example of semver condition: '1.x || >=2.5.0 || 5.0.0 - 7.2.3'.

/**

 * @param {string} packageName

 * @param {string} semverCondition
 */
api.compatibleWith('@quasar/app', '1.x')
A more complex example

if (api.hasVite === true) {
  api.compatibleWith('@quasar/app-vite', '^2.0.0')
}
else {
  api.compatbileWith('@quasar/app-webpack', '^4.0.0')
}

api.hasPackage(api.hasPackage)

通过语义版本条件确定主机应用中是否安装了某些软件包。

¥Determine if some package is installed in the host app through a semver condition.

语义版本条件示例:'1.x || >=2.5.0 || 5.0.0 - 7.2.3'

¥Example of semver condition: '1.x || >=2.5.0 || 5.0.0 - 7.2.3'.

/**

 * @param {string} packageName

 * @param {string} (optional) semverCondition

 * @return {boolean} package is installed and meets optional semver condition
 */
if (api.hasPackage('vuelidate')) {
  // hey, this app has it (any version of it)
}
if (api.hasPackage('quasar', '^2.0.0')) {
  // hey, this app has Quasar UI v2 installed
}

api.hasExtension(api.hasExtension)

检查是否已通过 npm 安装其他应用扩展,并且 Quasar CLI 是否已调用它。

¥Check if another app extension is npm installed and Quasar CLI has invoked it.

/**

 * Check if another app extension is installed

 *  * @param {string} extId

 * @return {boolean} has the extension installed & invoked
 */
if (api.hasExtension(extId)) {
  // hey, we have it
}

api.getPackageVersion(api.getPackageVersion)

获取宿主应用包的版本。

¥Get the version of a host app package.

/**

 * @param {string} packageName

 * @return {string|undefined} version of app's package
 */
console.log( api.getPackageVersion(packageName) )
// output examples:
//   1.1.3
//   undefined (when package not found)

api.extendQuasarConf(api.extendQuasarConf)

扩展 quasar.config 文件

¥Extends quasar.config file

/**

 * @param {function} fn

 *   (cfg: Object, ctx: Object) => undefined
 */
api.extendQuasarConf ((conf, api) => {
  // do something with quasar.config file:
  // add, change anything
})
A more complex example:

api.extendQuasarConf ((conf, api) => {
  if (api.hasVite === true) {
    // do something with quasar.config file that is specific
    // to @quasar/app-vite
  }
  else { // api.hasWebpack === true
    // do something with quasar.config file that is specific
    // to @quasar/app-webpack
  }
})

注册启动文件和 CSS 文件(Registering boot and css files)

¥Registering boot and css files

export default function (api, ctx) {
  api.extendQuasarConf((conf, api) => {
    // make sure my-ext boot file is registered
    conf.boot.push('~quasar-app-extension-my-ext/src/boot/my-ext-bootfile.js')

    if (api.hasVite !== true) {
      // make sure boot file transpiles
      conf.build.webpackTranspileDependencies.push(/quasar-app-extension-my-ext[\\/]src[\\/]boot/)
      // if boot file imports anything, make sure that
      // the regex above matches those files too!
    }

    // make sure my-ext css goes through webpack
    conf.css.push('~quasar-app-extension-my-ext/src/component/my-ext.sass')
  })
}

提示

注意路径前面的标题 (~)。这会告诉 Quasar CLI 该路径是来自 node_modules 的依赖,而不是应用扩展索引脚本文件的相对路径。

¥Notice the tidle (~) in front of the paths. This tells Quasar CLI that the path is a dependency from node_modules instead of a relative path to App Extension index script file.

api.registerCommand(api.registerCommand)

注册一个将作为 quasar run <ext-id> <cmd> [args](或简称:quasar <ext-id> <cmd> [args])提供的命令。

¥Register a command that will become available as quasar run <ext-id> <cmd> [args] (or the short form: quasar <ext-id> <cmd> [args]).

/**

 * @param {string} commandName

 * @param {function} fn

 *   ({ args: [ string, ... ], params: {object} }) => ?Promise
 */
api.registerCommand('start', ({ args, params }) => {
  // do something here

  // this registers the "start" command
  // and this handler is executed when running
  // $ quasar run <ext-id> start
})

api.registerDescribeApi(api.registerDescribeApi)

注册 $ quasar describe 命令的 API 文件。

¥Register an API file for $ quasar describe command.

/**

 * @param {string} name

 * @param {string} relativePath

 *   (relative path starting from the file where you have this call)
 */
api.registerDescribeApi(
  'MyComponent',
  './relative/path/to/my/component/file.json'
)

然后,上述代码将响应 $ quasar describe MyComponent

¥The above will then respond to $ quasar describe MyComponent.

有关此类 JSON 文件的语法,请查看 /node_modules/quasar/dist/api(在你的项目文件夹中)。请注意,你的 JSON 必须包含 type 属性(“component”、“directive”、“plugin”)。例如:

¥For syntax of such a JSON file, look into /node_modules/quasar/dist/api (in your project folder). Be aware that your JSON must contain a type property (“component”, “directive”, “plugin”). For instance:

{
  "type": "component",
  "props": {
  },
  ...
}

提示

请务必使用 quasar describe 命令进行测试,以确保语法正确且没有错误。

¥Always test with the quasar describe command to ensure you got the syntax right and there are no errors.

api.getPersistentConf(api.getPersistentConf)

获取此扩展程序的内部持久化配置。如果没有对象,则返回空对象。

¥Get the internal persistent config of this extension. Returns empty object if it has none.

/**

 * @return {object} cfg
 */
api.getPersistentConf()

api.setPersistentConf(api.setPersistentConf)

设置此扩展程序的内部持久配置。如果已存在,则会被覆盖。

¥Set the internal persistent config of this extension. If it already exists, it is overwritten.

/**

 * @param {object} cfg
 */
api.setPersistentConf({
  // ....
})

api.mergePersistentConf(api.mergePersistentConf)

深度合并到此扩展的内部持久化配置中。如果扩展程序尚未设置任何配置,这基本上相当于首次设置。

¥Deep merge into the internal persistent config of this extension. If extension does not have any config already set, this is essentially equivalent to setting it for the first time.

/**

 * @param {object} cfg
 */
api.mergePersistentConf({
  // ....
})

api.beforeDev(api.beforeDev)

$ quasar dev 命令运行之前准备外部服务,例如启动某些后端或应用依赖的任何其他服务。

¥Prepare external services before $ quasar dev command runs, like starting some backend or any other service that the app relies on.

可以使用 async/await 或直接返回 Promise。

¥Can use async/await or directly return a Promise.

/**

 * @param {function} fn

 *   (api, { quasarConf }) => ?Promise
 */
api.beforeDev((api, { quasarConf }) => {
  // do something
})

api.afterDev(api.afterDev)

在 Quasar 开发服务器启动后运行钩子 ($ quasar build)。此时,开发服务器已启动,你可以随时使用它来执行操作。

¥Run hook after Quasar dev server is started ($ quasar build). At this point, the dev server has been started and is available should you wish to do something with it.

可以使用 async/await 或直接返回 Promise。

¥Can use async/await or directly return a Promise.

/**

 * @param {function} fn

 *   (api, { quasarConf }) => ?Promise
 */
api.afterDev((api, { quasarConf }) => {
  // do something
})

api.beforeBuild(api.beforeBuild)

在 Quasar 构建生产环境应用 ($ quasar build) 之前运行钩子。此时,distributables 文件夹尚未创建。

¥Run hook before Quasar builds app for production ($ quasar build). At this point, the distributables folder hasn’t been created yet.

可以使用 async/await 或直接返回 Promise。

¥Can use async/await or directly return a Promise.

/**

 * @param {function} fn

 *   (api, { quasarConf }) => ?Promise
 */
api.beforeBuild((api, { quasarConf }) => {
  // do something
})

api.afterBuild(api.afterBuild)

在 Quasar 构建生产环境应用后运行钩子 ($ quasar build)。此时,distributables 文件夹已创建,你可以随时使用它来执行操作。

¥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.

可以使用 async/await 或直接返回 Promise。

¥Can use async/await or directly return a Promise.

/**

 * @param {function} fn

 *   (api, { quasarConf }) => ?Promise
 */
api.afterBuild((api, { quasarConf }) => {
  // do something
})

api.onPublish(api.onPublish)

如果请求发布 ($ quasar build -P),在 Quasar 构建生产环境应用并执行 afterBuild 钩子(如果指定)之后,运行钩子。

¥Run hook if publishing was requested ($ quasar build -P), after Quasar built app for production and the afterBuild hook (if specified) was executed.

可以使用 async/await 或直接返回 Promise。

¥Can use async/await or directly return a Promise.

/**

 * @param {function} fn

 *   () => ?Promise

 * @param {object} opts

 *   * arg - argument supplied to "--publish"/"-P" parameter

 *   * distDir - folder where distributables were built
 */
api.onPublish((api, opts) => {
  // do something
})

@quasar/app-vite only(@quasar/app-vite only)

api.extendViteConf(api.extendViteConf)

/**

 * @param {function} fn

 *   (viteConf: Object, invoke: Object {isClient, isServer}, api) => undefined
 */
if (api.hasVite === true) {
  api.extendViteConf((viteConf, { isClient, isServer }, api) => {
    // add/remove/change Quasar CLI generated Vite config object
  })
}

api.extendSSRWebserverConf(api.extendSSRWebserverConf)

/**

 * @param {function} fn

 *   (esbuildConf: Object, api) => undefined
 */
if (api.hasVite === true) {
  api.extendSSRWebserverConf((esbuildConf, api) => {
    // add/remove/change Quasar CLI generated esbuild config object
    // that is used for the SSR webserver (includes SSR middlewares)
  })
}

api.extendElectronMainConf(api.extendElectronMainConf)

/**

 * @param {function} fn

 *   (esbuildConf: Object, api) => undefined
 */
if (api.hasVite === true) {
  api.extendElectronMainConf((esbuildConf, api) => {
    // add/remove/change Quasar CLI generated esbuild config object
    // that is used for the SSR webserver (includes SSR middlewares)
  })
}

api.extendElectronPreloadConf(api.extendElectronPreloadConf)

/**

 * @param {function} fn

 *   (esbuildConf: Object, api) => undefined
 */
if (api.hasVite === true) {
  api.extendElectronPreloadConf((esbuildConf, api) => {
    // add/remove/change Quasar CLI generated esbuild config object
    // that is used for the SSR webserver (includes SSR middlewares)
  })
}

api.extendPWACustomSWConf(api.extendPWACustomSWConf)

/**

 * @param {function} fn

 *   (esbuildConf: Object, api) => undefined
 */
if (api.hasVite === true) {
  api.extendPWACustomSWConf((esbuildConf, api) => {
    // add/remove/change Quasar CLI generated esbuild config object
    // that is used for the SSR webserver (includes SSR middlewares)
  })
}

api.extendBexScriptsConf(api.extendBexScriptsConf)

/**

 * @param {function} fn

 *   (esbuildConf: Object, api) => undefined
 */
if (api.hasVite === true) {
  api.extendBexScriptsConf((esbuildConf, api) => {
    // add/remove/change Quasar CLI generated esbuild config object
    // that is used for the SSR webserver (includes SSR middlewares)
  })
}

@quasar/app-webpack only(@quasar/app-webpack only)

api.chainWebpack(api.chainWebpack)

链接 webpack 配置

¥Chain webpack config

/**

 * @param {function} fn

 *   (chain: ChainObject, invoke: Object {isClient, isServer}, api) => undefined
 */
if (api.hasWebpack === true) {
  api.chainWebpack((chain, { isClient, isServer }, api) => {
    // add/remove/change chain (Webpack chain Object)
  })
}

该配置是一个 Webpack 链式对象。其 API 在 webpack-chain 文档中进行了描述。

¥The configuration is a Webpack chain Object. The API for it is described on webpack-chain docs.

api.extendWebpack(api.extendWebpack)

扩展 webpack 配置

¥Extend webpack config

/**

 * @param {function} fn

 *   (cfg: Object, invoke: Object {isClient, isServer}, api) => undefined
 */
if (api.hasWebpack === true) {
  api.extendWebpack((cfg, { isClient, isServer }, api) => {
    // add/remove/change cfg (Webpack configuration Object)
  })
}

api.chainWebpackMainElectronProcess(api.chainWebpackMainElectronProcess)

主 Electron 进程的 Chain Webpack 配置

¥Chain webpack config of the main electron process

/**

 * @param {function} fn

 *   (chain: ChainObject) => undefined
 */
if (api.hasWebpack === true) {
  api.chainWebpackMainElectronProcess((chain, { isClient, isServer }, api) => {
    // add/remove/change chain (Webpack chain Object)
  })
}

api.extendWebpackMainElectronProcess(api.extendWebpackMainElectronProcess)

扩展 Electron 主进程的 webpack 配置对象

¥Extend webpack config Object of the main electron process

/**

 * @param {function} fn

 *   (cfg: Object) => undefined
 */
if (api.hasWebpack === true) {
  api.extendWebpackMainElectronProcess((cfg, { isClient, isServer }, api) => {
    // add/remove/change cfg (Webpack configuration Object)
  })
}

api.chainWebpackPreloadElectronProcess(api.chainWebpackPreloadElectronProcess)

预加载 Electron 进程的 Chain Webpack 配置

¥Chain webpack config of the preload electron process

/**

 * @param {function} fn

 *   (chain: ChainObject) => undefined
 */
if (api.hasWebpack === true) {
  api.chainWebpackPreloadElectronProcess((chain, { isClient, isServer }, api) => {
    // add/remove/change chain (Webpack chain Object)
  })
}

api.extendWebpackPreloadElectronProcess(api.extendWebpackPreloadElectronProcess)

扩展 Electron 预加载进程的 webpack 配置对象

¥Extend webpack config Object of the preload electron process

/**

 * @param {function} fn

 *   (cfg: Object) => undefined
 */
if (api.hasWebpack === true) {
  api.extendWebpackPreloadElectronProcess((cfg, { isClient, isServer }, api) => {
    // add/remove/change cfg (Webpack configuration Object)
  })
}

api.chainWebpackWebserver(api.chainWebpackWebserver)

SSR Web 服务器的 Chain Webpack 配置(包含 /src-ssr/middlewares 中的 SSR 中间件)

¥Chain webpack config of SSR webserver (includes the SSR middlewares from /src-ssr/middlewares)

/**

 * @param {function} fn

 *   (chain: ChainObject) => undefined
 */
if (api.hasWebpack === true) {
  api.chainWebpackWebserver ((chain, { isClient, isServer }, api) => {
    // add/remove/change chain (Webpack chain Object)
    // isClient is always "false" and isServer is always "true"
  })
}

api.extendWebpackWebserver(api.extendWebpackWebserver)

扩展 SSR Web 服务器的 webpack 配置对象(包含 /src-ssr/middlewares 中的 SSR 中间件)

¥Extend webpack config Object of SSR webserver (includes the SSR middlewares from /src-ssr/middlewares)

/**

 * @param {function} fn

 *   (cfg: Object) => undefined
 */
if (api.hasWebpack === true) {
  api.extendWebpackWebserver((cfg, { isClient, isServer }, api) => {
    // add/remove/change cfg (Webpack configuration Object)
    // isClient is always "false" and isServer is always "true"
  })
}

api.chainWebpackCustomSW(api.chainWebpackCustomSW)

使用 InjectManifest 时自定义 Service Worker 的 Chain Webpack 配置(/src-pwa/custom-service-worker.js 的内容):

¥Chain webpack config for the custom service worker when using InjectManifest (content of /src-pwa/custom-service-worker.js):

/**

 * @param {function} fn

 *   (cfg: ChainObject) => undefined
 */
if (api.hasWebpack === true) {
  api.chainWebpackCustomSW ((cfg, { isClient, isServer }, api) => {
    // add/remove/change cfg (Webpack chain Object)
  })
}

api.extendWebpackCustomSW(api.extendWebpackCustomSW)

使用 InjectManifest 时,扩展自定义 Service Worker 的 webpack 配置对象(/src-pwa/custom-service-worker.js 的内容):

¥Extend webpack config Object for the custom service worker when using InjectManifest (content of /src-pwa/custom-service-worker.js):

/**

 * @param {function} fn

 *   (chain: Object) => undefined
 */
if (api.hasWebpack === true) {
  api.extendWebpackCustomSW((chain, { isClient, isServer }, api) => {
    // add/remove/change chain (Webpack configuration Object)
  })
}