diff --git a/packages/@vue/cli-service/lib/PluginAPI.js b/packages/@vue/cli-service/lib/PluginAPI.js index 2552da006a..77d7cdce42 100644 --- a/packages/@vue/cli-service/lib/PluginAPI.js +++ b/packages/@vue/cli-service/lib/PluginAPI.js @@ -23,7 +23,7 @@ class PluginAPI { /** * Check if the project has a given plugin. * - * @param {string} id - Plugin id, can omit the (@vue/|vue-)-cli-plugin- prefix + * @param {string} id - Plugin id, can omit the (@vue/|vue-|@scope/vue)-cli-plugin- prefix * @return {boolean} */ hasPlugin (id) { diff --git a/packages/@vue/cli-service/lib/Service.js b/packages/@vue/cli-service/lib/Service.js index 12a758d883..c903ff9aac 100644 --- a/packages/@vue/cli-service/lib/Service.js +++ b/packages/@vue/cli-service/lib/Service.js @@ -8,7 +8,7 @@ const Config = require('webpack-chain') const PluginAPI = require('./PluginAPI') const loadEnv = require('./util/loadEnv') const defaultsDeep = require('lodash.defaultsdeep') -const { warn, error } = require('@vue/cli-shared-utils') +const { warn, error, isPlugin } = require('@vue/cli-shared-utils') const { defaults, validate } = require('./options') @@ -104,10 +104,9 @@ module.exports = class Service { ? builtInPlugins.concat(inlinePlugins) : inlinePlugins } else { - const prefixRE = /^(@vue\/|vue-)cli-plugin-/ const projectPlugins = Object.keys(this.pkg.dependencies || {}) .concat(Object.keys(this.pkg.devDependencies || {})) - .filter(p => prefixRE.test(p)) + .filter(isPlugin) .map(idToPlugin) return builtInPlugins.concat(projectPlugins) } diff --git a/packages/@vue/cli-shared-utils/index.js b/packages/@vue/cli-shared-utils/index.js index 2dcd6607f0..700ee8a116 100644 --- a/packages/@vue/cli-shared-utils/index.js +++ b/packages/@vue/cli-shared-utils/index.js @@ -3,7 +3,8 @@ 'logger', 'spinner', 'validate', - 'openBrowser' + 'openBrowser', + 'pluginResolution' ].forEach(m => { Object.assign(exports, require(`./lib/${m}`)) }) diff --git a/packages/@vue/cli-shared-utils/lib/pluginResolution.js b/packages/@vue/cli-shared-utils/lib/pluginResolution.js new file mode 100644 index 0000000000..0183d0c363 --- /dev/null +++ b/packages/@vue/cli-shared-utils/lib/pluginResolution.js @@ -0,0 +1,7 @@ +const pluginRE = /^(@vue\/|vue-|@[\w-]+\/vue-)cli-plugin-/ + +exports.isPlugin = id => pluginRE.test(id) + +exports.isOfficial = id => /^@vue\//.test(id) + +exports.toShortId = id => id.replace(pluginRE, '') diff --git a/packages/@vue/cli/lib/Generator.js b/packages/@vue/cli/lib/Generator.js index c80b4bcb1f..c50c31b0f7 100644 --- a/packages/@vue/cli/lib/Generator.js +++ b/packages/@vue/cli/lib/Generator.js @@ -4,10 +4,10 @@ const debug = require('debug') const GeneratorAPI = require('./GeneratorAPI') const sortObject = require('./util/sortObject') const writeFileTree = require('./util/writeFileTree') +const { toShortId } = require('@vue/cli-shared-utils') const configTransforms = require('./util/configTransforms') -const logger = require('@vue/cli-shared-utils/lib/logger') -const { toShortId } = require('./util/pluginResolution') +const logger = require('@vue/cli-shared-utils/lib/logger') const logTypes = { log: logger.log, info: logger.info, diff --git a/packages/@vue/cli/lib/GeneratorAPI.js b/packages/@vue/cli/lib/GeneratorAPI.js index 4e4eab814e..847efa6361 100644 --- a/packages/@vue/cli/lib/GeneratorAPI.js +++ b/packages/@vue/cli/lib/GeneratorAPI.js @@ -5,6 +5,7 @@ const globby = require('globby') const isBinary = require('isbinaryfile') const yaml = require('yaml-front-matter') const mergeDeps = require('./util/mergeDeps') +const { isOfficial, toShortId } = require('@vue/cli-shared-utils') const isString = val => typeof val === 'string' const isFunction = val => typeof val === 'function' @@ -39,11 +40,10 @@ class GeneratorAPI { this.pluginsData = generator.plugins .filter(({ id }) => id !== `@vue/cli-service`) .map(({ id }) => { - const name = id.replace(/^(@vue|vue-)\/cli-plugin-/, '') - const isOfficial = /^@vue/.test(id) + const name = toShortId(id) return { name: name, - link: isOfficial + link: isOfficial(id) ? `https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-${name}` : getLink(id) } @@ -87,7 +87,7 @@ class GeneratorAPI { /** * Check if the project has a given plugin. * - * @param {string} id - Plugin id, can omit the (@vue/|vue-)-cli-plugin- prefix + * @param {string} id - Plugin id, can omit the (@vue/|vue-|@scope/vue)-cli-plugin- prefix * @return {boolean} */ hasPlugin (id) { diff --git a/packages/@vue/cli/lib/invoke.js b/packages/@vue/cli/lib/invoke.js index e4ba5374ad..17e8423ad9 100644 --- a/packages/@vue/cli/lib/invoke.js +++ b/packages/@vue/cli/lib/invoke.js @@ -40,7 +40,19 @@ async function invoke (pluginName, options = {}, context = process.cwd()) { // attempt to locate the plugin in package.json const findPlugin = deps => { if (!deps) return + + // custom scoped plugin let name + if (pluginName.charAt(0) === '@') { + const scopeRE = /^@[\w-]+\// + const scopeMatch = pluginName.match(scopeRE) + const shortId = pluginName.replace(scopeRE, '') + if (scopeMatch && deps[name = `${scopeMatch[0]}vue-cli-plugin-${shortId}`]) { + return name + } + } + + // official, non-scoped & full name if (deps[name = `@vue/cli-plugin-${pluginName}`] || deps[name = `vue-cli-plugin-${pluginName}`] || deps[name = pluginName]) { diff --git a/packages/@vue/cli/lib/util/pluginResolution.js b/packages/@vue/cli/lib/util/pluginResolution.js deleted file mode 100644 index 6896b02daa..0000000000 --- a/packages/@vue/cli/lib/util/pluginResolution.js +++ /dev/null @@ -1,7 +0,0 @@ -function toShortId (id) { - id.replace('@vue/cli-plugin-', '').replace('vue-cli-plugin-', '') -} - -module.exports = { - toShortId -}