diff --git a/docs/dev-guide/generator-api.md b/docs/dev-guide/generator-api.md index 889b44bba5..286128ee9d 100644 --- a/docs/dev-guide/generator-api.md +++ b/docs/dev-guide/generator-api.md @@ -1,5 +1,44 @@ # Generator API +## cliVersion + +Type: `string` + +The version string for the **global** `@vue/cli` version that is invoking the plugin. + + +## assertCliVersion + +- **Arguments** + - `{integer | string} range` - a semver range that `@vue/cli` needs to satisfy + +- **Usage** + + While api.version can be useful in general, it's sometimes nice to just declare your version. + This API exposes a simple way to do that. + + Nothing happens if the provided version is satified. Otherwise, an error will be thrown. + + +## cliServiceVersion + +Type: `string` + +The version string for the **project local** `@vue/cli-service` version that is invoking the plugin. + + +## assertCliServiceVersion + +- **Arguments** + - `{integer | string} range` - a semver range that `@vue/cli-service` needs to satisfy + +- **Usage** + + This API exposes a simple way to declare the required project local `@vue/cli-service` version. + + Nothing happens if the provided version is satified. Otherwise, an error will be thrown. + + ## resolve - **Arguments** diff --git a/docs/dev-guide/plugin-api.md b/docs/dev-guide/plugin-api.md index ab7ecf4c54..2e23920233 100644 --- a/docs/dev-guide/plugin-api.md +++ b/docs/dev-guide/plugin-api.md @@ -7,7 +7,7 @@ Type: `string` The version string for the `@vue/cli-service` version that is loading the plugin. -## assertVersion(range) +## assertVersion - **Arguments** - `{integer | string} range` - a semver range that `@vue/cli-service` needs to satisfy diff --git a/packages/@vue/cli/lib/GeneratorAPI.js b/packages/@vue/cli/lib/GeneratorAPI.js index b6ac7ee8f6..9aec3478e6 100644 --- a/packages/@vue/cli/lib/GeneratorAPI.js +++ b/packages/@vue/cli/lib/GeneratorAPI.js @@ -4,10 +4,11 @@ const path = require('path') const merge = require('deepmerge') const resolve = require('resolve') const { isBinaryFileSync } = require('isbinaryfile') +const semver = require('semver') const mergeDeps = require('./util/mergeDeps') const stringifyJS = require('./util/stringifyJS') const ConfigTransform = require('./ConfigTransform') -const { getPluginLink, toShortPluginId } = require('@vue/cli-shared-utils') +const { getPluginLink, toShortPluginId, loadModule } = require('@vue/cli-shared-utils') const isString = val => typeof val === 'string' const isFunction = val => typeof val === 'function' @@ -71,6 +72,55 @@ class GeneratorAPI { return path.resolve(this.generator.context, _path) } + get cliVersion () { + return require('../package.json').version + } + + assertCliVersion (range) { + if (typeof range === 'number') { + if (!Number.isInteger(range)) { + throw new Error('Expected string or integer value.') + } + range = `^${range}.0.0-0` + } + if (typeof range !== 'string') { + throw new Error('Expected string or integer value.') + } + + if (semver.satisfies(this.cliVersion, range)) return + + throw new Error( + `Require global @vue/cli "${range}", but was invoked by "${this.cliVersion}".` + ) + } + + get cliServiceVersion () { + const servicePkg = loadModule( + '@vue/cli-service/package.json', + this.generator.context + ) + + return servicePkg.version + } + + assertCliServiceVersion (range) { + if (typeof range === 'number') { + if (!Number.isInteger(range)) { + throw new Error('Expected string or integer value.') + } + range = `^${range}.0.0-0` + } + if (typeof range !== 'string') { + throw new Error('Expected string or integer value.') + } + + if (semver.satisfies(this.cliServiceVersion, range)) return + + throw new Error( + `Require @vue/cli-service "${range}", but was loaded with "${this.cliServiceVersion}".` + ) + } + /** * Check if the project has a given plugin. *