当你的 App Extension 被安装时,如果你有一个 /index.js 文件(在 App Extension 的顶层目录中),那么它将被使用。
TIP
如果你使用 quasar create my-extension --kit app-extension 命令创建你的 App Extension,那么这个文件已经为你创建好了。
这个文件需要导出一个函数,该函数接收一个 API 对象参数:
/**
* Quasar App Extension index/runner script
* (在安装/删除过程中运行)
*
* Docs: https://quasar.dev/app-extensions/development-guide/index-api
* API: https://github.com/quasarframework/quasar/blob/master/app/lib/app-extension/IndexAPI.js
*/
module.exports = function (api) {
// 这里是你的 App Extension 代码
};Index API
api.ctx
与 /quasar.config 文件中的 ctx 相同。帮助您根据 quasar dev 或 quasar build 运行的上下文做出决策。
示例:如果仅在 electron 模式下运行,则可以使用其中一个 api 方法。
if (api.ctx.dev === true && api.ctx.mode.electron === true) {
api.beforeDev((api) => {
// 在运行 quasar dev 且处于 Electron 模式时执行某些操作
});
}api.engine
包含正在使用的 Quasar CLI 引擎名(字符串)。示例:@quasar/app-vite 或 @quasar/app-webpack。
api.hasVite
布尔值 - 是否在 @quasar/app-vite 上运行。
api.hasWebpack
布尔值 - 是否在 @quasar/app-webpack 上运行。
api.compatibleWith
通过 semver 条件确保扩展与宿主应用程序中安装的程序包兼容。
如果不满足semver条件,则 Quasar CLI 会出错并停止执行。
/**
* @param {string} packageName - 'quasar' 或 '@quasar/app-vite' 或 '@quasar/app-webpack'
* @param {string} semverCondition - 例如:'1.x || >=2.5.0 || 5.0.0 - 7.2.3'
*/
api.compatibleWith(packageName, semverCondition);
// 示例
api.compatibleWith("@quasar/app-vite", "^1.0.0");
api.compatibleWith("quasar", "^2.0.0");// 更复杂的例子:
if (api.hasVite === true) {
api.compatibleWith("@quasar/app-vite", "^1.0.0-beta.0");
} else {
api.compatbileWith("@quasar/app-webpack", "^3.4.0");
}api.hasPackage
检查宿主应用是否安装了某个包,并且可以通过 semver 条件设置版本。
/**
* @param {string} packageName
* @param {string} (可选) semver 条件
* @return {boolean} 软件包已安装并满足可选的 semver 条件
*/
if (api.hasPackage("vuelidate")) {
// 应用安装了这个包(任何版本)
}
if (api.hasPackage("quasar", "^2.0.0")) {
// 应用安装了 quasar v2
}api.hasExtension
检查另一个应用扩展是否通过 npm 安装并由 Quasar CLI 调用。
/**
* 检查另一个应用扩展是否已安装
*
* @param {string} extId - 例如:'@quasar/qmediaplayer'
* @return {boolean} 扩展已安装并被调用
*/
if (api.hasExtension(extId)) {
// 是的,我们安装了它
}api.extId
包含 App Extension 的 ID。
console.log(api.extId);
// 例如:'my-ext'api.prompts
包含用户在安装 App Extension 时回答的提示问题的答案。
// 假设用户在安装时被问到了一个名为 "message" 的问题
console.log(api.prompts.message);api.resolve
解析相对于 App Extension 目录的路径:
/**
* @param {...string} paths
* @return {string} 解析后的路径
*/
// 解析 "src/components" 相对于 App Extension 的路径
console.log(api.resolve("src/components"));在运行此应用扩展的应用程序内解析路径。消除了导入 path 并自行解析路径的需求。
// 解析到应用程序的根目录
api.resolve.app("src/my-file.js");
// 解析到应用程序/src目录
api.resolve.src("my-file.js");
// 解析到应用程序/public目录
// (@quasar/app-webpack v3.4+ 或 @quasar/app-vite v1+)
api.resolve.public("my-image.png");
// 解析到应用程序/src-pwa目录
api.resolve.pwa("some-file.js");
// 解析到应用程序/src-ssr目录
api.resolve.ssr("some-file.js");
// 解析到应用程序/src-cordova目录
api.resolve.cordova("config.xml");
// 解析到应用程序/src-electron目录
api.resolve.electron("some-file.js");
// 解析到应用程序/src-bex目录
api.resolve.bex("some-file.js");api.appDir
包含 App 的根目录路径。
console.log(api.appDir);
// /path/to/appapi.hasTypescript @quasar/app-vite 1.6+ @quasar/app-webpack 3.11+
/**
* @return {Promise<boolean>} 宿主项目是否启用 TypeScript
*/
await api.hasTypescript();api.hasLint @quasar/app-vite 1.6+ @quasar/app-webpack 3.11+
/**
* @return {Promise<boolean>} 宿主项目是否启用 ESLint
*/
await api.hasLint();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+
/**
* @return {Promise<string|undefined>} 'npm' | 'yarn' | 'pnpm'
*/
await api.getNodePackagerName();api.getPackageVersion
获取宿主应用的版本号
/**
* @param {string} packageName
* @return {string|undefined} 应用程序包的版本
*/
console.log(api.getPackageVersion(packageName));
// 输出示例:
// 1.1.3
// undefined(未找到包时)api.extendQuasarConf
扩展 /quasar.config.js 文件:
/**
* @param {function} fn
* fn(conf)
* - conf 是 quasar.config.js 的配置对象
*/
api.extendQuasarConf((conf) => {
// 通过 "conf" 对象修改 /quasar.config.js
// 以下是一些示例:
// 添加 boot 文件
conf.boot.push("~quasar-app-extension-my-ext/src/boot/my-boot.js");
// 添加 Quasar CSS 动画
conf.animations.push("bounceInLeft");
// 添加 Quasar 语言包
conf.framework.lang.push("de");
// 修改 build 配置
if (conf.ctx.dev) {
conf.build.minify = false;
}
// 添加 webpack 配置
if (conf.build.webpack) {
conf.build.webpack((cfg) => {
// ...对 cfg 进行修改
});
}
});// 一个更复杂的列子:
api.extendQuasarConf((conf, api) => {
if (api.hasVite === true) {
// 只针对 @quasar/app-vite
} else {
// api.hasWebpack === true
// 只针对 @quasar/app-webpack
}
});注册启动文件和 css 文件
export default function (api, ctx) {
api.extendQuasarConf((conf, api) => {
// 确保 my-ext 启动文件已注册
conf.boot.push("~quasar-app-extension-my-ext/src/boot/my-ext-bootfile.js");
if (api.hasVite !== true) {
// 确保启动文件进行转译
conf.build.transpileDependencies.push(/quasar-app-extension-my-ext[\\/]src[\\/]boot/);
// 如果启动文件导入了任何内容,请确保上述正则表达式也匹配这些文件!
}
// 确保 my-ext 样式经过 webpack 处理
conf.css.push("~quasar-app-extension-my-ext/src/component/my-ext.sass");
});
}TIP
注意路径前的波浪符(~)。这告诉 Quasar CLI 该路径是来自 node_modules 的依赖项,而不是相对于 App Extension 索引脚本文件的相对路径。
api.registerCommand
注册一个命令,将作为 quasar run <ext-id> <cmd> [args](或简写形式:quasar <ext-id> <cmd> [args])可用。
/**
* @param {string} commandName
* @param {function} fn
* ({ args: [ string, ... ], params: {object} }) => ?Promise
*/
api.registerCommand("start", ({ args, params }) => {
// 在这里执行一些操作
// 这注册了 "start" 命令
// 当运行 $ quasar run <ext-id> start 时执行此处理程序
});然后用户可以通过以下方式运行你的命令:
# 运行 "start" 命令:
$ quasar run my-ext start
# 带参数运行:
$ quasar run my-ext start --param1 --param2=value2api.registerDescribeApi
为 $ quasar describe 命令注册一个 API 文件。
/**
* @param {string} name
* @param {string} relativePath
* (相对路径,相对于调用此函数的文件)
*/
api.registerDescribeApi("MyComponent", "./relative/path/to/my/component/file.json");然后可以响应 $ quasar describe MyComponent。
有关这样一个 JSON 文件的语法,请查看 /node_modules/quasar/dist/api(在项目文件夹中)。请注意,JSON 必须包含一个 type 属性(“component”、“directive”、“plugin”)。例如:
{
"type": "component",
"props": {
},
...
}TIP
始终使用 quasar describe 命令进行测试,以确保语法正确且没有错误。
api.getPersistentConf
获取此扩展的内部持久配置。如果没有配置,则返回空对象。
/**
* @return {object} cfg
*/
api.getPersistentConf();api.setPersistentConf
设置此扩展的内部持久配置。如果已存在,则会被覆盖。
/**
* @param {object} conf
*/
api.setPersistentConf({
// 你的配置数据
});
// 或者使用函数形式:
api.setPersistentConf((conf) => {
conf.property = "value";
return conf; // 必须返回配置对象
});api.mergePersistentConf
深度合并到此扩展的内部持久配置。如果扩展尚未设置任何配置,则这实质上等同于首次设置。
/**
* @param {object} cfg
*/
api.mergePersistentConf({
// ....
});api.onExitLog()
在安装/删除过程结束时打印一条消息:
/**
* @param {string} msg
*/
api.onExitLog("感谢使用我的 App Extension");api.beforeDev
在运行 $ quasar dev 命令之前被调用的钩子,例如,您可以在此时启动后端或应用依赖的任何其他服务。
可以使用 async/await 或直接返回 Promise。
/**
* @param {function} fn
* (api, { quasarConf }) => ?Promise
*/
api.beforeDev((api, { quasarConf }) => {
// 执行某些操作
});api.afterDev
在 Quasar 开发服务器启动后($ quasar dev)运行钩子。此时,开发服务器已启动,并且可用于执行其他操作。
可以使用 async/await 或直接返回 Promise。
/**
* @param {function} fn
* (api, { quasarConf }) => ?Promise
*/
api.afterDev((api, { quasarConf }) => {
// 执行某些操作
});api.beforeBuild
在 Quasar 为生产构建应用程序之前运行钩子($ quasar build)。此时,尚未创建分发文件夹。
可以使用 async/await 或直接返回 Promise。
/**
* @param {function} fn
* (api, { quasarConf }) => ?Promise
*/
api.beforeBuild((api, { quasarConf }) => {
// 执行某些操作
});api.afterBuild
在 Quasar 为生产构建应用程序后运行钩子($ quasar build)。此时,分发文件夹已创建并可供执行其他操作。
可以使用 async/await 或直接返回 Promise。
/**
* @param {function} fn
* (api, { quasarConf }) => ?Promise
*/
api.afterBuild((api, { quasarConf }) => {
// 执行某些操作
});api.onPublish
如果运行了发布命令($ quasar build -P),在 Quasar 为生产构建应用程序后以及执行了 afterBuild 钩子后运行的钩子。
可以使用 async/await 或直接返回 Promise。
/**
* @param {function} fn
* () => ?Promise
* @param {object} opts
* * arg - 提供给 "--publish" 或 "-P" 参数的参数
* * distDir - 构建分发文件的文件夹
*/
api.onPublish((api, opts) => {
// 执行某些操作
});仅适用于 @quasar/app-vite
api.extendViteConf
/**
* @param {function} fn
* (viteConf: Object, invoke: Object {isClient, isServer}, api) => undefined
*/
if (api.hasVite === true) {
api.extendViteConf((viteConf, { isClient, isServer }, api) => {
// 添加/删除/更改由 Quasar CLI 生成的 Vite 配置对象
});
}api.extendSSRWebserverConf
/**
* @param {function} fn
* (esbuildConf: Object, api) => undefined
*/
if (api.hasVite === true) {
api.extendSSRWebserverConf((esbuildConf, api) => {
// 添加/删除/更改由 Quasar CLI 生成的用于 SSR webserver 的 esbuild 配置对象(包括 SSR 中间件)
});
}api.extendElectronMainConf
/**
* @param {function} fn
* (esbuildConf: Object, api) => undefined
*/
if (api.hasVite === true) {
api.extendElectronMainConf((esbuildConf, api) => {
// 添加/删除/更改由 Quasar CLI 生成的用于 SSR webserver 的 esbuild 配置对象(包括 SSR 中间件)
});
}api.extendElectronPreloadConf
/**
* @param {function} fn
* (esbuildConf: Object, api) => undefined
*/
if (api.hasVite === true) {
api.extendElectronPreloadConf((esbuildConf, api) => {
// 添加/删除/更改由 Quasar CLI 生成的用于 SSR webserver 的 esbuild 配置对象(包括 SSR 中间件)
});
}api.extendPWACustomSWConf
/**
* @param {function} fn
* (esbuildConf: Object, api) => undefined
*/
if (api.hasVite === true) {
api.extendPWACustomSWConf((esbuildConf, api) => {
// 添加/删除/更改由 Quasar CLI 生成的用于 SSR webserver 的 esbuild 配置对象(包括 SSR 中间件)
});
}api.extendBexScriptsConf
/**
* @param {function} fn
* (esbuildConf: Object, api) => undefined
*/
if (api.hasVite === true) {
api.extendBexScriptsConf((esbuildConf, api) => {
// 添加/删除/更改由 Quasar CLI 生成的用于 SSR webserver 的 esbuild 配置对象(包括 SSR 中间件)
});
}仅适用于 @quasar/app-webpack
api.extendWebpack
扩展 Webpack 配置:
/**
* @param {function} fn
* (cfg, { isClient, isServer }, api)
* - cfg 是 Webpack 配置对象
* - isClient - 为客户端代码构建?
* - isServer - 为服务器代码构建?
* - api - 包含 extendWebpack() 的 API 对象
*/
if (api.hasWebpack === true) {
api.extendWebpack((cfg, { isClient, isServer }, api) => {
// 修改 Webpack 配置
// 通过 cfg 对象
});
}api.chainWebpack
链 webpack 配置
/**
* @param {function} fn
* (chain: ChainObject, invoke: Object {isClient, isServer}, api) => undefined
*/
if (api.hasWebpack === true) {
api.chainWebpack((chain, { isClient, isServer }, api) => {
// 添加/删除/更改链 (Webpack chain Object)
});
}配置是一个 Webpack chain Object。有关其 API 的信息,请参阅 webpack-chain 文档。
api.chainWebpackMainElectronProcess
electron 主进程的 webpack 链式配置
/**
* @param {function} fn
* (chain: ChainObject) => undefined
*/
if (api.hasWebpack === true) {
api.chainWebpackMainElectronProcess((chain, { isClient, isServer }, api) => {
// 添加/删除/更改链(Webpack chain Object)
});
}api.extendWebpackMainElectronProcess
扩展 electron 主进程的 webpack 配置对象
/**
* @param {function} fn
* (cfg: Object) => undefined
*/
if (api.hasWebpack === true) {
api.extendWebpackMainElectronProcess((cfg, { isClient, isServer }, api) => {
// 添加/删除/更改 cfg(Webpack 配置 Object)
});
}api.chainWebpackPreloadElectronProcess
electron 链预加载进程的 webpack 链式配置
/**
* @param {function} fn
* (chain: ChainObject) => undefined
*/
if (api.hasWebpack === true) {
api.chainWebpackPreloadElectronProcess((chain, { isClient, isServer }, api) => {
// 添加/删除/更改链(Webpack chain Object)
});
}api.extendWebpackPreloadElectronProcess
扩展 electron 预加载进程的 webpack 配置对象
/**
* @param {function} fn
* (cfg: Object) => undefined
*/
if (api.hasWebpack === true) {
api.extendWebpackPreloadElectronProcess((cfg, { isClient, isServer }, api) => {
// 添加/删除/更改 cfg(Webpack 配置 Object)
});
}api.chainWebpackWebserver
SSR webserver 的 webpack 链式配置(包括 /src-ssr/middlewares 中的 SSR 中间件)
/**
* @param {function} fn
* (chain: ChainObject) => undefined
*/
if (api.hasWebpack === true) {
api.chainWebpackWebserver((chain, { isClient, isServer }, api) => {
// 添加/删除/更改链(Webpack chain Object)
// isClient 总是 "false",isServer 总是 "true"
});
}api.extendWebpackWebserver
扩展 SSR webserver 的 webpack 配置对象(包括 /src-ssr/middlewares 中的 SSR 中间件)
/**
* @param {function} fn
* (cfg: Object) => undefined
*/
if (api.hasWebpack === true) {
api.extendWebpackWebserver((cfg, { isClient, isServer }, api) => {
// 添加/删除/更改 cfg(Webpack 配置 Object)
// isClient 总是 "false",isServer 总是 "true"
});
}api.chainWebpackCustomSW
使用 InjectManifest 时用于自定义服务工作器的 webpack 链式配置(/src-pwa/custom-service-worker.js 中的内容):
/**
* @param {function} fn
* (cfg: ChainObject) => undefined
*/
if (api.hasWebpack === true) {
api.chainWebpackCustomSW((cfg, { isClient, isServer }, api) => {
// 添加/删除/更改 cfg(Webpack chain Object)
});
}api.extendWebpackCustomSW
扩展使用 InjectManifest 时用于自定义服务工作器的 webpack 配置对象(/src-pwa/custom-service-worker.js 中的内容):
/**
* @param {function} fn
* (cfg: Object) => undefined
*/
if (api.hasWebpack === true) {
api.extendWebpackCustomSW((cfg, { isClient, isServer }, api) => {
// 添加/删除/更改 cfg(Webpack 配置对象)
});
}