本页引用 src/index.js
文件,该文件在 quasar dev
和 quasar 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 dev
或 quasar 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')
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
})
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)
})
}