调用插件
对于第三方插件安装完成之后,先调用 invoke 方法,该方法实现如下:
async function invoke (pluginName, options = {}, context = process.cwd()) {
delete options._
const pkg = getPkg(context) // 解析 package.json
// attempt to locate the plugin in package.json
const findPlugin = deps => {
if (!deps) return
let name
// official
if (deps[(name = `@vue/cli-plugin-${pluginName}`)]) {
return name
}
// full id, scoped short, or default short
if (deps[(name = resolvePluginId(pluginName))]) {
return name
}
}
const id = findPlugin(pkg.devDependencies) || findPlugin(pkg.dependencies)
if (!id) {
throw new Error(
`Cannot resolve plugin ${chalk.yellow(pluginName)} from package.json. ` +
`Did you forget to install it?`
)
}
const pluginGenerator = loadModule(`${id}/generator`, context)
if (!pluginGenerator) {
throw new Error(`Plugin ${id} does not have a generator.`)
}
// resolve options if no command line options (other than --registry) are passed,
// and the plugin contains a prompt module.
// eslint-disable-next-line prefer-const
let { registry, ...pluginOptions } = options
if (!Object.keys(pluginOptions).length) {
let pluginPrompts = loadModule(`${id}/prompts`, context)
if (pluginPrompts) {
if (typeof pluginPrompts === 'function') {
pluginPrompts = pluginPrompts(pkg)
}
if (typeof pluginPrompts.getPrompts === 'function') {
pluginPrompts = pluginPrompts.getPrompts(pkg)
}
pluginOptions = await inquirer.prompt(pluginPrompts)
}
}
const plugin = {
id,
apply: pluginGenerator,
options: {
registry,
...pluginOptions
}
}
await runGenerator(context, plugin, pkg)
}
该方法先调用 findPlugin 判断插件是否安装,接着判断是否有 generator(pluginGenerator),然后就是判断插件是否含有 prompt。如果有则调用
inquirer.prompt 获取插件的 option,并传给其 generator,在完成这些以后,就是 runGenerator。
而对于 vue-cli 内部一些特殊的"插件",比如 router,vuex就直接调用 runGenerator。
如果你看了 vue create 分析部分的 Generator 的话,接下来就比较轻松了。runGenerator 的实质就是构造一个 Generator 实例,并调用其 generate 方法。
如果对 generate 方法还不熟悉的话,可查看下 vue create 部分。 在实例的 generator 方法调用完成之后执行以下命令:
git ls-files --exclude-standard --modified --others
因为插件的 generator 可以通过 GeneratorAPI 暴露的 render 和 extendPackage 方法修改项目的文件,因此通过执行该命令将变化的文件显示在
终端上,这对开发者十分地友好。