本页引用 src/install.js
文件,该文件仅在安装应用扩展时执行。并非所有应用扩展都需要安装 - 这是一个可选步骤。
¥This page refers to src/install.js
file which is executed on the installation of the App Extension only. Not all App Extensions will need an install – this is an optional step.
文件基本结构示例:
¥Example of basic structure of the file:
// can be async
export default function (api) {
// props and methods for "api" Object
// are described below
}
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 gets 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-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 CLI 将报错并停止执行。
¥If the semver condition is not met, then Quasar CLI 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(packageName, '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.extendPackageJson(api.extendPackageJson)
辅助方法,用于使用新的 props 扩展 package.json。如果指定了现有的 props,它会覆盖它们。
¥Helper method to extend package.json with new props. If specifying existing props, it will override them.
/**
* @param {object|string} extPkg - Object to extend with or relative path to a JSON file
*/
api.extendPackageJson({
scripts: {
'electron': 'quasar dev -m electron'
}
})
以上示例将一个 npm 脚本添加到应用的 package.json 中,以便你可以执行 yarn electron
(或等效的 npm run electron
)。
¥The above example adds an npm script to the app’s package.json, so you can then execute yarn electron
(or the equivalent npm run electron
).
api.extendJsonFile(api.extendJsonFile)
使用新属性扩展 JSON 文件(深度合并)。如果指定了现有的 props,它会覆盖它们。
¥Extend a JSON file with new props (deep merge). If specifying existing props, it will override them.
/**
* @param {string} file (relative path to app root folder)
* @param {object} newData (Object to merge in)
*/
api.extendJsonFile('src/some.json', {
newProp: 'some-value'
})
api.render(api.render)
将应用扩展模板中的文件夹(你指定的任何文件夹)渲染(复制)到应用的根目录。保持与模板文件夹相同的文件夹结构。
¥Renders (copies) a folder from your App Extension templates (any folder you specify) into root of the app. Maintains the same folder structure that the template folder has.
如果某些文件已存在于应用中,它会询问用户是否应覆盖它们。
¥If some of the files already exist in the app then it will ask the user if they should be overwritten or not.
需要调用 render() 文件的文件夹的相对路径。
¥Needs a relative path to the folder of the file calling render().
/**
* Render a folder from extension templates into devland
* Needs a path (to a folder) relative to the path of the file where render() is called
* * @param {string} templatePath (relative path to folder to render in app)
* @param {object} scope (optional; rendering scope variables)
*/
api.render('./path/to/a/template/folder')
文件名边缘情况(Filename edge cases)
¥Filename edge cases
如果你要渲染一个以点开头的模板文件(例如 .env),则必须遵循特定的命名约定,因为在将插件发布到 npm 时会忽略点文件:
¥If you want to render a template file that either begins with a dot (i.e. .env) you will have to follow a specific naming convention, since dotfiles are ignored when publishing your plugin to npm:
# templates containing dotfiles must use an
# underscore instead of the dot in their names:
some-folder/_env
# When calling api.render('./some-folder'), this will be
# rendered in the project folder as:
/.env
如果你要渲染一个名称实际上以下划线开头的文件,则文件名必须以 __
开头(两个下划线字符,而不是一个):
¥If you want to render a file whose name actually begins with an underscore, then the filename must begin with __
(two underscore characters instead of only one):
some-folder/__my.css
# When calling api.render('./template'), this will be
# rendered in the project folder as:
/_my.css
使用 scope(Using scope)
¥Using scope
你还可以通过使用 lodash/template 语法进行插值,将一些决策代码注入到要渲染的文件中。
¥You can also inject some decision-making code into the files to be rendered by interpolating with lodash/template syntax.
示例:
¥Example:
// (my-folder is located in same folder as
// the file in which following call takes place)
api.render('./my-folder', {
prompts: api.prompts
})
假设我们也使用 提示 API 文件。它会询问用户是否需要 “功能 X”,并将答案存储在名为 “特性 X” 的变量中。
¥Let’s imagine we use a Prompts API file too. It asks the user if he/she wants “Feature X” and stores the answer in a variable called “featureX”.
我们可以在渲染文件的过程中,决定渲染文件的外观。这样就无需创建两个文件夹,也无需根据某些决定来决定渲染哪个文件夹。
¥We can take some decisions on what the files that we render look like, during rendering them. This removes the need of creating two folders and deciding which to render, based on some decision.
<% if (prompts.featureX) { %>
const message = 'This is content when "Feature X" exists'
<% } else { %>
const message = 'This is content when we don\'t have "Feature X"'
<% } %>
可能性仅受你的想象力限制。
¥Possibilities are limited only by your imagination.
api.renderFile(api.renderFile)
与 api.render() 类似,不同之处在于此方法渲染单个文件。
¥Similar with api.render() with the difference that this method renders a single file.
/**
* Render a file from extension template into devland
* Needs a path (to a file) relative to the path of the file where renderFile() is called
* * @param {string} relativeSourcePath (file path relative to the folder from which the install script is called)
* @param {string} relativeTargetPath (file path relative to the root of the app -- including filename!)
* @param {object} scope (optional; rendering scope variables)
*/
api.renderFile('./path/to/a/template/filename', 'path/relative/to/app/root/filename', {
prompts: api.prompts
})
api.renderFile('./my-file.json', 'src/my-file.json')
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.onExitLog(api.onExitLog)
在 App CLI 完成应用扩展安装并即将退出后,添加一条打印消息。可以多次调用以注册多个退出日志。
¥Adds a message to be printed after App CLI finishes up installing the App Extension and is about to exit. Can be called multiple times to register multiple exit logs.
/**
* @param {string} msg
*/
api.onExitLog('Thanks for installing my awesome extension')