mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-05-06 20:09:14 -05:00
feat: local service plugins, closes #1841
This commit is contained in:
@@ -75,6 +75,22 @@ For example, if you have a `.config/package.json` file:
|
||||
```
|
||||
:::
|
||||
|
||||
### Project local plugin
|
||||
|
||||
If you need access to the plugin API in your project and don't want to create a full plugin for it, you can use the `vuePlugins.service` option in your `package.json` file:
|
||||
|
||||
```json
|
||||
{
|
||||
"vuePlugins": {
|
||||
"service": ["my-commands.js"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Each file will need to export a function taking the plugin API as the first argument. For more information about the plugin API, check out the [Plugin Development Guide](../dev-guide/plugin-dev.md).
|
||||
|
||||
You can also create a `vue-cli-ui.js` file that will behave like a UI plugin. For more information, read the [UI Plugin API](../dev-guide/ui-api.md).
|
||||
|
||||
## Presets
|
||||
|
||||
A Vue CLI preset is a JSON object that contains pre-defined options and plugins for creating a new project so that the user don't have to go through the prompts to select them.
|
||||
|
||||
@@ -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, isPlugin } = require('@vue/cli-shared-utils')
|
||||
const { warn, error, isPlugin, loadModule } = require('@vue/cli-shared-utils')
|
||||
|
||||
const { defaults, validate } = require('./options')
|
||||
|
||||
@@ -22,6 +22,9 @@ module.exports = class Service {
|
||||
this.webpackRawConfigFns = []
|
||||
this.devServerConfigFns = []
|
||||
this.commands = {}
|
||||
// Folder containing the target package.json for plugins
|
||||
this.pkgContext = context
|
||||
// package.json containing the plugins
|
||||
this.pkg = this.resolvePkg(pkg)
|
||||
// If there are inline plugins, they will be used instead of those
|
||||
// found in package.json.
|
||||
@@ -42,7 +45,8 @@ module.exports = class Service {
|
||||
} else if (fs.existsSync(path.join(context, 'package.json'))) {
|
||||
const pkg = readPkg.sync({ cwd: context })
|
||||
if (pkg.vuePlugins && pkg.vuePlugins.resolveFrom) {
|
||||
return this.resolvePkg(null, path.resolve(context, pkg.vuePlugins.resolveFrom))
|
||||
this.pkgContext = path.resolve(context, pkg.vuePlugins.resolveFrom)
|
||||
return this.resolvePkg(null, this.pkgContext)
|
||||
}
|
||||
return pkg
|
||||
} else {
|
||||
@@ -132,6 +136,8 @@ module.exports = class Service {
|
||||
apply: require(id)
|
||||
})
|
||||
|
||||
let plugins
|
||||
|
||||
const builtInPlugins = [
|
||||
'./commands/serve',
|
||||
'./commands/build',
|
||||
@@ -146,7 +152,7 @@ module.exports = class Service {
|
||||
].map(idToPlugin)
|
||||
|
||||
if (inlinePlugins) {
|
||||
return useBuiltIn !== false
|
||||
plugins = useBuiltIn !== false
|
||||
? builtInPlugins.concat(inlinePlugins)
|
||||
: inlinePlugins
|
||||
} else {
|
||||
@@ -154,8 +160,22 @@ module.exports = class Service {
|
||||
.concat(Object.keys(this.pkg.dependencies || {}))
|
||||
.filter(isPlugin)
|
||||
.map(idToPlugin)
|
||||
return builtInPlugins.concat(projectPlugins)
|
||||
plugins = builtInPlugins.concat(projectPlugins)
|
||||
}
|
||||
|
||||
// Local plugins
|
||||
if (this.pkg.vuePlugins && this.pkg.vuePlugins.service) {
|
||||
const files = this.pkg.vuePlugins.service
|
||||
if (!Array.isArray(files)) {
|
||||
throw new Error(`Invalid type for option 'vuePlugins.service', expected 'array' but got ${typeof files}.`)
|
||||
}
|
||||
plugins = plugins.concat(files.map(file => ({
|
||||
id: `local:${file}`,
|
||||
apply: loadModule(file, this.pkgContext)
|
||||
})))
|
||||
}
|
||||
|
||||
return plugins
|
||||
}
|
||||
|
||||
async run (name, args = {}, rawArgv = []) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
'exit',
|
||||
'ipc',
|
||||
'logger',
|
||||
'module',
|
||||
'object',
|
||||
'openBrowser',
|
||||
'pluginResolution',
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
"ora": "^2.1.0",
|
||||
"request": "^2.87.0",
|
||||
"request-promise-native": "^1.0.5",
|
||||
"semver": "^5.5.0",
|
||||
"string.prototype.padstart": "^3.0.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
||||
@@ -9,9 +9,8 @@ const plugins = require('./plugins')
|
||||
const folders = require('./folders')
|
||||
const prompts = require('./prompts')
|
||||
// Utils
|
||||
const { get, set, unset } = require('@vue/cli-shared-utils')
|
||||
const { get, set, unset, loadModule } = require('@vue/cli-shared-utils')
|
||||
const { log } = require('../util/logger')
|
||||
const { loadModule } = require('@vue/cli/lib/util/module')
|
||||
const extendJSConfig = require('@vue/cli/lib/util/extendJSConfig')
|
||||
|
||||
const fileTypes = ['js', 'json', 'yaml']
|
||||
|
||||
@@ -11,8 +11,7 @@ const logs = require('./logs')
|
||||
// Context
|
||||
const getContext = require('../context')
|
||||
// Utils
|
||||
const { isPlugin, hasYarn } = require('@vue/cli-shared-utils')
|
||||
const { resolveModule } = require('@vue/cli/lib/util/module')
|
||||
const { isPlugin, hasYarn, resolveModule } = require('@vue/cli-shared-utils')
|
||||
const getPackageVersion = require('@vue/cli/lib/util/getPackageVersion')
|
||||
const {
|
||||
progress: installProgress,
|
||||
|
||||
@@ -24,9 +24,11 @@ const PluginApi = require('../api/PluginApi')
|
||||
const {
|
||||
isPlugin,
|
||||
isOfficialPlugin,
|
||||
getPluginLink
|
||||
getPluginLink,
|
||||
resolveModule,
|
||||
loadModule,
|
||||
clearModule
|
||||
} = require('@vue/cli-shared-utils')
|
||||
const { resolveModule, loadModule, clearModule } = require('@vue/cli/lib/util/module')
|
||||
const {
|
||||
progress: installProgress,
|
||||
installPackage,
|
||||
|
||||
@@ -5,9 +5,8 @@ const Creator = require('@vue/cli/lib/Creator')
|
||||
const { getPromptModules } = require('@vue/cli/lib/util/createTools')
|
||||
const { getFeatures } = require('@vue/cli/lib/util/features')
|
||||
const { defaults } = require('@vue/cli/lib/options')
|
||||
const { toShortPluginId } = require('@vue/cli-shared-utils')
|
||||
const { toShortPluginId, clearModule } = require('@vue/cli-shared-utils')
|
||||
const { progress: installProgress } = require('@vue/cli/lib/util/installDeps')
|
||||
const { clearModule } = require('@vue/cli/lib/util/module')
|
||||
const parseGitConfig = require('parse-git-config')
|
||||
// Connectors
|
||||
const progress = require('./progress')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { loadModule } = require('@vue/cli/lib/util/module')
|
||||
const { loadModule } = require('@vue/cli-shared-utils')
|
||||
const invoke = require('@vue/cli/lib/invoke')
|
||||
|
||||
const ROUTER = 'org.vue.vue-router-add'
|
||||
|
||||
@@ -7,7 +7,6 @@ const inquirer = require('inquirer')
|
||||
const Generator = require('./Generator')
|
||||
const cloneDeep = require('lodash.clonedeep')
|
||||
const sortObject = require('./util/sortObject')
|
||||
const { loadModule } = require('./util/module')
|
||||
const getVersions = require('./util/getVersions')
|
||||
const { installDeps } = require('./util/installDeps')
|
||||
const { clearConsole } = require('./util/clearConsole')
|
||||
@@ -34,7 +33,8 @@ const {
|
||||
hasYarn,
|
||||
logWithSpinner,
|
||||
stopSpinner,
|
||||
exit
|
||||
exit,
|
||||
loadModule
|
||||
} = require('@vue/cli-shared-utils')
|
||||
|
||||
const isManualMode = answers => answers.preset === '__manual__'
|
||||
|
||||
@@ -2,13 +2,14 @@ const chalk = require('chalk')
|
||||
const invoke = require('./invoke')
|
||||
const { loadOptions } = require('./options')
|
||||
const { installPackage } = require('./util/installDeps')
|
||||
const { resolveModule, loadModule } = require('./util/module')
|
||||
const {
|
||||
log,
|
||||
error,
|
||||
hasProjectYarn,
|
||||
stopSpinner,
|
||||
resolvePluginId
|
||||
resolvePluginId,
|
||||
resolveModule,
|
||||
loadModule
|
||||
} = require('@vue/cli-shared-utils')
|
||||
|
||||
async function add (pluginName, options = {}, context = process.cwd()) {
|
||||
|
||||
@@ -7,7 +7,6 @@ const inquirer = require('inquirer')
|
||||
const isBinary = require('isbinaryfile')
|
||||
const Generator = require('./Generator')
|
||||
const { loadOptions } = require('./options')
|
||||
const { loadModule } = require('./util/module')
|
||||
const { installDeps } = require('./util/installDeps')
|
||||
const normalizeFilePaths = require('./util/normalizeFilePaths')
|
||||
const {
|
||||
@@ -17,7 +16,8 @@ const {
|
||||
hasProjectGit,
|
||||
logWithSpinner,
|
||||
stopSpinner,
|
||||
resolvePluginId
|
||||
resolvePluginId,
|
||||
loadModule
|
||||
} = require('@vue/cli-shared-utils')
|
||||
|
||||
async function readFiles (context) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const extendJSConfig = require('./extendJSConfig')
|
||||
const stringifyJS = require('./stringifyJS')
|
||||
const { loadModule } = require('./module')
|
||||
const { loadModule } = require('@vue/cli-shared-utils')
|
||||
const merge = require('deepmerge')
|
||||
|
||||
const isObject = val => val && typeof val === 'object'
|
||||
|
||||
Reference in New Issue
Block a user