Skip to content

Commit 0835281

Browse files
author
Guillaume Chau
committed
feat: local service plugins, closes vuejs#1841
1 parent d212dcd commit 0835281

File tree

14 files changed

+58
-20
lines changed

14 files changed

+58
-20
lines changed

docs/guide/plugins-and-presets.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,22 @@ For example, if you have a `.config/package.json` file:
7575
```
7676
:::
7777

78+
### Project local plugin
79+
80+
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:
81+
82+
```json
83+
{
84+
"vuePlugins": {
85+
"service": ["my-commands.js"]
86+
}
87+
}
88+
```
89+
90+
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).
91+
92+
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).
93+
7894
## Presets
7995

8096
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.

packages/@vue/cli-service/lib/Service.js

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const Config = require('webpack-chain')
88
const PluginAPI = require('./PluginAPI')
99
const loadEnv = require('./util/loadEnv')
1010
const defaultsDeep = require('lodash.defaultsdeep')
11-
const { warn, error, isPlugin } = require('@vue/cli-shared-utils')
11+
const { warn, error, isPlugin, loadModule } = require('@vue/cli-shared-utils')
1212

1313
const { defaults, validate } = require('./options')
1414

@@ -22,6 +22,9 @@ module.exports = class Service {
2222
this.webpackRawConfigFns = []
2323
this.devServerConfigFns = []
2424
this.commands = {}
25+
// Folder containing the target package.json for plugins
26+
this.pkgContext = context
27+
// package.json containing the plugins
2528
this.pkg = this.resolvePkg(pkg)
2629
// If there are inline plugins, they will be used instead of those
2730
// found in package.json.
@@ -42,7 +45,8 @@ module.exports = class Service {
4245
} else if (fs.existsSync(path.join(context, 'package.json'))) {
4346
const pkg = readPkg.sync({ cwd: context })
4447
if (pkg.vuePlugins && pkg.vuePlugins.resolveFrom) {
45-
return this.resolvePkg(null, path.resolve(context, pkg.vuePlugins.resolveFrom))
48+
this.pkgContext = path.resolve(context, pkg.vuePlugins.resolveFrom)
49+
return this.resolvePkg(null, this.pkgContext)
4650
}
4751
return pkg
4852
} else {
@@ -132,6 +136,8 @@ module.exports = class Service {
132136
apply: require(id)
133137
})
134138

139+
let plugins
140+
135141
const builtInPlugins = [
136142
'./commands/serve',
137143
'./commands/build',
@@ -146,16 +152,30 @@ module.exports = class Service {
146152
].map(idToPlugin)
147153

148154
if (inlinePlugins) {
149-
return useBuiltIn !== false
155+
plugins = useBuiltIn !== false
150156
? builtInPlugins.concat(inlinePlugins)
151157
: inlinePlugins
152158
} else {
153159
const projectPlugins = Object.keys(this.pkg.devDependencies || {})
154160
.concat(Object.keys(this.pkg.dependencies || {}))
155161
.filter(isPlugin)
156162
.map(idToPlugin)
157-
return builtInPlugins.concat(projectPlugins)
163+
plugins = builtInPlugins.concat(projectPlugins)
158164
}
165+
166+
// Local plugins
167+
if (this.pkg.vuePlugins && this.pkg.vuePlugins.service) {
168+
const files = this.pkg.vuePlugins.service
169+
if (!Array.isArray(files)) {
170+
throw new Error(`Invalid type for option 'vuePlugins.service', expected 'array' but got ${typeof files}.`)
171+
}
172+
plugins = plugins.concat(files.map(file => ({
173+
id: `local:${file}`,
174+
apply: loadModule(file, this.pkgContext)
175+
})))
176+
}
177+
178+
return plugins
159179
}
160180

161181
async run (name, args = {}, rawArgv = []) {

packages/@vue/cli-shared-utils/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
'exit',
44
'ipc',
55
'logger',
6+
'module',
67
'object',
78
'openBrowser',
89
'pluginResolution',

packages/@vue/cli-shared-utils/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"ora": "^2.1.0",
2828
"request": "^2.87.0",
2929
"request-promise-native": "^1.0.5",
30+
"semver": "^5.5.0",
3031
"string.prototype.padstart": "^3.0.0"
3132
},
3233
"publishConfig": {

packages/@vue/cli-ui/apollo-server/connectors/configurations.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ const plugins = require('./plugins')
99
const folders = require('./folders')
1010
const prompts = require('./prompts')
1111
// Utils
12-
const { get, set, unset } = require('@vue/cli-shared-utils')
12+
const { get, set, unset, loadModule } = require('@vue/cli-shared-utils')
1313
const { log } = require('../util/logger')
14-
const { loadModule } = require('@vue/cli/lib/util/module')
1514
const extendJSConfig = require('@vue/cli/lib/util/extendJSConfig')
1615

1716
const fileTypes = ['js', 'json', 'yaml']

packages/@vue/cli-ui/apollo-server/connectors/dependencies.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ const logs = require('./logs')
1111
// Context
1212
const getContext = require('../context')
1313
// Utils
14-
const { isPlugin, hasYarn } = require('@vue/cli-shared-utils')
15-
const { resolveModule } = require('@vue/cli/lib/util/module')
14+
const { isPlugin, hasYarn, resolveModule } = require('@vue/cli-shared-utils')
1615
const getPackageVersion = require('@vue/cli/lib/util/getPackageVersion')
1716
const {
1817
progress: installProgress,

packages/@vue/cli-ui/apollo-server/connectors/plugins.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ const PluginApi = require('../api/PluginApi')
2424
const {
2525
isPlugin,
2626
isOfficialPlugin,
27-
getPluginLink
27+
getPluginLink,
28+
resolveModule,
29+
loadModule,
30+
clearModule
2831
} = require('@vue/cli-shared-utils')
29-
const { resolveModule, loadModule, clearModule } = require('@vue/cli/lib/util/module')
3032
const {
3133
progress: installProgress,
3234
installPackage,

packages/@vue/cli-ui/apollo-server/connectors/projects.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ const Creator = require('@vue/cli/lib/Creator')
55
const { getPromptModules } = require('@vue/cli/lib/util/createTools')
66
const { getFeatures } = require('@vue/cli/lib/util/features')
77
const { defaults } = require('@vue/cli/lib/options')
8-
const { toShortPluginId } = require('@vue/cli-shared-utils')
8+
const { toShortPluginId, clearModule } = require('@vue/cli-shared-utils')
99
const { progress: installProgress } = require('@vue/cli/lib/util/installDeps')
10-
const { clearModule } = require('@vue/cli/lib/util/module')
1110
const parseGitConfig = require('parse-git-config')
1211
// Connectors
1312
const progress = require('./progress')

packages/@vue/cli-ui/ui-defaults/suggestions.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { loadModule } = require('@vue/cli/lib/util/module')
1+
const { loadModule } = require('@vue/cli-shared-utils')
22
const invoke = require('@vue/cli/lib/invoke')
33

44
const ROUTER = 'org.vue.vue-router-add'

packages/@vue/cli/lib/Creator.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const inquirer = require('inquirer')
77
const Generator = require('./Generator')
88
const cloneDeep = require('lodash.clonedeep')
99
const sortObject = require('./util/sortObject')
10-
const { loadModule } = require('./util/module')
1110
const getVersions = require('./util/getVersions')
1211
const { installDeps } = require('./util/installDeps')
1312
const { clearConsole } = require('./util/clearConsole')
@@ -34,7 +33,8 @@ const {
3433
hasYarn,
3534
logWithSpinner,
3635
stopSpinner,
37-
exit
36+
exit,
37+
loadModule
3838
} = require('@vue/cli-shared-utils')
3939

4040
const isManualMode = answers => answers.preset === '__manual__'

packages/@vue/cli/lib/add.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ const chalk = require('chalk')
22
const invoke = require('./invoke')
33
const { loadOptions } = require('./options')
44
const { installPackage } = require('./util/installDeps')
5-
const { resolveModule, loadModule } = require('./util/module')
65
const {
76
log,
87
error,
98
hasProjectYarn,
109
stopSpinner,
11-
resolvePluginId
10+
resolvePluginId,
11+
resolveModule,
12+
loadModule
1213
} = require('@vue/cli-shared-utils')
1314

1415
async function add (pluginName, options = {}, context = process.cwd()) {

packages/@vue/cli/lib/invoke.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const inquirer = require('inquirer')
77
const isBinary = require('isbinaryfile')
88
const Generator = require('./Generator')
99
const { loadOptions } = require('./options')
10-
const { loadModule } = require('./util/module')
1110
const { installDeps } = require('./util/installDeps')
1211
const normalizeFilePaths = require('./util/normalizeFilePaths')
1312
const {
@@ -17,7 +16,8 @@ const {
1716
hasProjectGit,
1817
logWithSpinner,
1918
stopSpinner,
20-
resolvePluginId
19+
resolvePluginId,
20+
loadModule
2121
} = require('@vue/cli-shared-utils')
2222

2323
async function readFiles (context) {

packages/@vue/cli/lib/util/configTransforms.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const extendJSConfig = require('./extendJSConfig')
22
const stringifyJS = require('./stringifyJS')
3-
const { loadModule } = require('./module')
3+
const { loadModule } = require('@vue/cli-shared-utils')
44
const merge = require('deepmerge')
55

66
const isObject = val => val && typeof val === 'object'

0 commit comments

Comments
 (0)