@mpxjs/cli 3.1.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/mpx.js +91 -115
- package/lib/create.js +91 -0
- package/lib/info.js +19 -0
- package/lib/inspect.js +35 -0
- package/package.json +1 -2
- package/utils/index.js +27 -0
package/bin/mpx.js
CHANGED
|
@@ -1,127 +1,103 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
const program = require('commander')
|
|
3
|
+
const { doVueCli } = require('../utils')
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const vueCliBinPath = require.resolve('@vue/cli/bin/vue')
|
|
7
|
-
const builtInPreset = require('../lib/preset')
|
|
8
|
-
const inquirer = require('inquirer')
|
|
9
|
-
const prompts = require('../lib/prompts')
|
|
10
|
-
const plugins = require('../lib/plugins')
|
|
11
|
-
const loadRemotePreset = require('@vue/cli/lib/util/loadRemotePreset')
|
|
12
|
-
const loadLocalPreset = require('@vue/cli/lib/util/loadLocalPreset')
|
|
13
|
-
const {
|
|
14
|
-
chalk,
|
|
15
|
-
exit,
|
|
16
|
-
error,
|
|
17
|
-
log
|
|
18
|
-
} = require('@vue/cli-shared-utils')
|
|
19
|
-
const merge = require('lodash.merge')
|
|
5
|
+
program
|
|
6
|
+
.version(`@mpx/cli ${require('../package').version}`)
|
|
7
|
+
.usage('<command> [options]')
|
|
20
8
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
async function resolvePrompts(name, builtInPreset) {
|
|
56
|
-
return new Promise(function(resolve) {
|
|
57
|
-
inquirer.prompt(prompts).then(answers => {
|
|
58
|
-
if (answers.needTs) {
|
|
59
|
-
Object.assign(builtInPreset.plugins, plugins.tsSupport)
|
|
60
|
-
}
|
|
61
|
-
if (answers.cloudFunc) {
|
|
62
|
-
Object.assign(builtInPreset.plugins, plugins.cloudFunc)
|
|
63
|
-
}
|
|
64
|
-
if (answers.isPlugin) {
|
|
65
|
-
Object.assign(builtInPreset.plugins, plugins.isPlugin)
|
|
66
|
-
}
|
|
67
|
-
if (answers.transWeb) {
|
|
68
|
-
Object.assign(builtInPreset.plugins, plugins.transWeb)
|
|
69
|
-
}
|
|
70
|
-
// TODO: 添加其他 prompt 插件配置
|
|
9
|
+
program.command('create <app-name>')
|
|
10
|
+
.description('create a new project powered by mpx-cli-service')
|
|
11
|
+
.option(
|
|
12
|
+
'-p, --preset <presetName>',
|
|
13
|
+
'Skip prompts and use saved or remote preset'
|
|
14
|
+
)
|
|
15
|
+
.option('-d, --default', 'Skip prompts and use default preset')
|
|
16
|
+
.option(
|
|
17
|
+
'-i, --inlinePreset <json>',
|
|
18
|
+
'Skip prompts and use inline JSON string as preset'
|
|
19
|
+
)
|
|
20
|
+
.option(
|
|
21
|
+
'-m, --packageManager <command>',
|
|
22
|
+
'Use specified npm client when installing dependencies'
|
|
23
|
+
)
|
|
24
|
+
.option(
|
|
25
|
+
'-r, --registry <url>',
|
|
26
|
+
'Use specified npm registry when installing dependencies (only for npm)'
|
|
27
|
+
)
|
|
28
|
+
.option(
|
|
29
|
+
'-g, --git [message]',
|
|
30
|
+
'Force git initialization with initial commit message'
|
|
31
|
+
)
|
|
32
|
+
.option('-n, --no-git', 'Skip git initialization')
|
|
33
|
+
.option('-f, --force', 'Overwrite target directory if it exists')
|
|
34
|
+
.option('--merge', 'Merge target directory if it exists')
|
|
35
|
+
.option('-c, --clone', 'Use git clone when fetching remote preset')
|
|
36
|
+
.option('-x, --proxy <proxyUrl>', 'Use specified proxy when creating project')
|
|
37
|
+
.option('-b, --bare', 'Scaffold project without beginner instructions')
|
|
38
|
+
.option('--skipGetStarted', 'Skip displaying "Get started" instructions')
|
|
39
|
+
.action(async () => {
|
|
40
|
+
require('../lib/create')()
|
|
41
|
+
})
|
|
71
42
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
43
|
+
program
|
|
44
|
+
.command('add <plugin> [pluginOptions]')
|
|
45
|
+
.description('install a plugin and invoke its generator in an already created project')
|
|
46
|
+
.option('--registry <url>', 'Use specified npm registry when installing dependencies (only for npm)')
|
|
47
|
+
.allowUnknownOption()
|
|
48
|
+
.action((plugin) => {
|
|
49
|
+
doVueCli(process.argv.slice(2))
|
|
50
|
+
})
|
|
80
51
|
|
|
81
|
-
|
|
82
|
-
|
|
52
|
+
program
|
|
53
|
+
.command('invoke <plugin> [pluginOptions]')
|
|
54
|
+
.description('invoke the generator of a plugin in an already created project')
|
|
55
|
+
.option('--registry <url>', 'Use specified npm registry when installing dependencies (only for npm)')
|
|
56
|
+
.allowUnknownOption()
|
|
57
|
+
.action(() => {
|
|
58
|
+
doVueCli(process.argv.slice(2))
|
|
83
59
|
})
|
|
84
|
-
}
|
|
85
60
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
61
|
+
program
|
|
62
|
+
.command('inspect:mp [paths...]')
|
|
63
|
+
.description('inspect the webpack config in a project with mpx-cli-service')
|
|
64
|
+
.option('--mode <mode>')
|
|
65
|
+
.option('--targets <targets>')
|
|
66
|
+
.option('-v --verbose', 'Show full function definitions in output')
|
|
67
|
+
.action((paths, options) => {
|
|
68
|
+
require('../lib/inspect')(paths, options, 'mp')
|
|
94
69
|
})
|
|
95
|
-
return cmd
|
|
96
|
-
}
|
|
97
70
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
71
|
+
program
|
|
72
|
+
.command('inspect:web [paths...]')
|
|
73
|
+
.description('inspect the webpack config in a project with mpx-cli-service')
|
|
74
|
+
.option('--mode <mode>')
|
|
75
|
+
.option('--rule <ruleName>', 'inspect a specific module rule')
|
|
76
|
+
.option('--plugin <pluginName>', 'inspect a specific plugin')
|
|
77
|
+
.option('--rules', 'list all module rule names')
|
|
78
|
+
.option('--plugins', 'list all plugin names')
|
|
79
|
+
.option('-v --verbose', 'Show full function definitions in output')
|
|
80
|
+
.action((paths, options) => {
|
|
81
|
+
require('../lib/inspect')(paths, options, 'web')
|
|
82
|
+
})
|
|
104
83
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
84
|
+
program
|
|
85
|
+
.command('config [value]')
|
|
86
|
+
.description('inspect and modify the config')
|
|
87
|
+
.option('-g, --get <path>', 'get value from option')
|
|
88
|
+
.option('-s, --set <path> <value>', 'set option value')
|
|
89
|
+
.option('-d, --delete <path>', 'delete option from config')
|
|
90
|
+
.option('-e, --edit', 'open config with default editor')
|
|
91
|
+
.option('--json', 'outputs JSON result only')
|
|
92
|
+
.action((value, options) => {
|
|
93
|
+
doVueCli(process.argv.slice(2))
|
|
94
|
+
})
|
|
108
95
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
96
|
+
program
|
|
97
|
+
.command('info')
|
|
98
|
+
.description('print debugging information about your environment')
|
|
99
|
+
.action((cmd) => {
|
|
100
|
+
require('../lib/info')()
|
|
101
|
+
})
|
|
115
102
|
|
|
116
|
-
|
|
117
|
-
execa(
|
|
118
|
-
'node',
|
|
119
|
-
[
|
|
120
|
-
vueCliBinPath,
|
|
121
|
-
...args
|
|
122
|
-
],
|
|
123
|
-
{
|
|
124
|
-
stdio: 'inherit'
|
|
125
|
-
}
|
|
126
|
-
)
|
|
127
|
-
}
|
|
103
|
+
program.parse(process.argv)
|
package/lib/create.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const minimist = require('minimist')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const inquirer = require('inquirer')
|
|
4
|
+
const merge = require('lodash.merge')
|
|
5
|
+
const { chalk, exit, error, log } = require('@vue/cli-shared-utils')
|
|
6
|
+
const loadRemotePreset = require('@vue/cli/lib/util/loadRemotePreset')
|
|
7
|
+
const loadLocalPreset = require('@vue/cli/lib/util/loadLocalPreset')
|
|
8
|
+
|
|
9
|
+
const prompts = require('./prompts')
|
|
10
|
+
const plugins = require('./plugins')
|
|
11
|
+
const builtInPreset = require('./preset')
|
|
12
|
+
|
|
13
|
+
const { regenCmd, doVueCli } = require('../utils')
|
|
14
|
+
|
|
15
|
+
async function resolvePreset (args = {}) {
|
|
16
|
+
const { p, preset, i, inlinePreset, c, clone } = args
|
|
17
|
+
let res = {}
|
|
18
|
+
let cliPreset = {}
|
|
19
|
+
if (p || preset) {
|
|
20
|
+
// mpx create foo --preset bar
|
|
21
|
+
cliPreset = p || preset
|
|
22
|
+
if (
|
|
23
|
+
cliPreset.endsWith('.json') ||
|
|
24
|
+
/^\./.test(cliPreset) ||
|
|
25
|
+
path.isAbsolute(cliPreset)
|
|
26
|
+
) {
|
|
27
|
+
res = await loadLocalPreset(path.resolve(cliPreset))
|
|
28
|
+
} else if (cliPreset.includes('/')) {
|
|
29
|
+
try {
|
|
30
|
+
log(`Fetching remote preset ${chalk.cyan(cliPreset)}...`)
|
|
31
|
+
res = await loadRemotePreset(cliPreset, c || clone)
|
|
32
|
+
} catch (e) {
|
|
33
|
+
error(`Failed fetching remote preset ${chalk.cyan(cliPreset)}:`)
|
|
34
|
+
throw e
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
} else if (i || inlinePreset) {
|
|
38
|
+
// mpx create foo --inlinePreset {...}
|
|
39
|
+
cliPreset = i || inlinePreset
|
|
40
|
+
try {
|
|
41
|
+
res = JSON.parse(cliPreset)
|
|
42
|
+
} catch (e) {
|
|
43
|
+
error(`CLI inline preset is not valid JSON: ${cliPreset}`)
|
|
44
|
+
exit(1)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return res
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function resolvePrompts (name, builtInPreset) {
|
|
51
|
+
return new Promise(function (resolve) {
|
|
52
|
+
inquirer.prompt(prompts).then((answers) => {
|
|
53
|
+
if (answers.needTs) {
|
|
54
|
+
Object.assign(builtInPreset.plugins, plugins.tsSupport)
|
|
55
|
+
}
|
|
56
|
+
if (answers.cloudFunc) {
|
|
57
|
+
Object.assign(builtInPreset.plugins, plugins.cloudFunc)
|
|
58
|
+
}
|
|
59
|
+
if (answers.isPlugin) {
|
|
60
|
+
Object.assign(builtInPreset.plugins, plugins.isPlugin)
|
|
61
|
+
}
|
|
62
|
+
if (answers.transWeb) {
|
|
63
|
+
Object.assign(builtInPreset.plugins, plugins.transWeb)
|
|
64
|
+
}
|
|
65
|
+
// TODO: 添加其他 prompt 插件配置
|
|
66
|
+
|
|
67
|
+
// 各插件共享 answers 配置
|
|
68
|
+
Object.keys(builtInPreset.plugins).forEach(function (key) {
|
|
69
|
+
const plugin = builtInPreset.plugins[key]
|
|
70
|
+
Object.assign(plugin, {
|
|
71
|
+
...answers,
|
|
72
|
+
name
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
resolve(builtInPreset)
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = async function () {
|
|
82
|
+
const args = process.argv.slice(2)
|
|
83
|
+
const parsedArgs = minimist(args)
|
|
84
|
+
const name = args[1]
|
|
85
|
+
const cmd = regenCmd(parsedArgs)
|
|
86
|
+
const mpxBuiltInPreset = await resolvePrompts(name, builtInPreset)
|
|
87
|
+
const cliPreset = await resolvePreset(parsedArgs)
|
|
88
|
+
const mergedPreset = merge(mpxBuiltInPreset, cliPreset)
|
|
89
|
+
cmd.push('-i', JSON.stringify(mergedPreset))
|
|
90
|
+
doVueCli(cmd)
|
|
91
|
+
}
|
package/lib/info.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const chalk = require('chalk')
|
|
2
|
+
|
|
3
|
+
module.exports = function () {
|
|
4
|
+
console.log(chalk.bold('\nEnvironment Info:'))
|
|
5
|
+
require('envinfo').run(
|
|
6
|
+
{
|
|
7
|
+
System: ['OS', 'CPU'],
|
|
8
|
+
Binaries: ['Node', 'Yarn', 'npm'],
|
|
9
|
+
Browsers: ['Chrome', 'Edge', 'Firefox', 'Safari'],
|
|
10
|
+
npmPackages: '/**/{typescript,*vue*,@vue/*/,*mpx*,@mpxjs/*/}',
|
|
11
|
+
npmGlobalPackages: ['@vue/cli', '@mpxjs/cli']
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
showNotFound: true,
|
|
15
|
+
duplicates: true,
|
|
16
|
+
fullTree: true
|
|
17
|
+
}
|
|
18
|
+
).then(console.log)
|
|
19
|
+
}
|
package/lib/inspect.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const resolve = require('resolve')
|
|
4
|
+
const { execa } = require('@vue/cli-shared-utils')
|
|
5
|
+
|
|
6
|
+
module.exports = function inspect (paths, args, mode) {
|
|
7
|
+
const cwd = process.cwd()
|
|
8
|
+
let servicePath
|
|
9
|
+
try {
|
|
10
|
+
servicePath = resolve.sync('@mpxjs/mpx-cli-service', { basedir: cwd })
|
|
11
|
+
} catch (e) {
|
|
12
|
+
const { error } = require('@vue/cli-shared-utils')
|
|
13
|
+
error(
|
|
14
|
+
'Failed to locate @mpxjs/mpx-cli-service.\n' +
|
|
15
|
+
'Note that `mpx inspect` is an alias of `@mpxjs/mpx-cli-service inspect`\n' +
|
|
16
|
+
'and can only be used in a project where @mpxjs/mpx-cli-service is locally installed.'
|
|
17
|
+
)
|
|
18
|
+
process.exit(1)
|
|
19
|
+
}
|
|
20
|
+
const binPath = path.resolve(servicePath, '../../bin/mpx-cli-service.js')
|
|
21
|
+
if (fs.existsSync(binPath)) {
|
|
22
|
+
execa('node', [
|
|
23
|
+
binPath,
|
|
24
|
+
`inspect:${mode}`,
|
|
25
|
+
...(args.mode ? ['--mode', args.mode] : []),
|
|
26
|
+
...(args.targets ? ['--targets', args.targets] : []),
|
|
27
|
+
...(args.rule ? ['--rule', args.rule] : []),
|
|
28
|
+
...(args.plugin ? ['--plugin', args.plugin] : []),
|
|
29
|
+
...(args.rules ? ['--rules'] : []),
|
|
30
|
+
...(args.plugins ? ['--plugins'] : []),
|
|
31
|
+
...(args.verbose ? ['--verbose'] : []),
|
|
32
|
+
...paths
|
|
33
|
+
], { cwd, stdio: 'inherit' })
|
|
34
|
+
}
|
|
35
|
+
}
|
package/package.json
CHANGED
package/utils/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const execa = require('execa')
|
|
2
|
+
const vueCliBinPath = require.resolve('@vue/cli/bin/vue')
|
|
3
|
+
|
|
4
|
+
module.exports.regenCmd = function regenCmd (parsedArgs) {
|
|
5
|
+
const cmd = [...parsedArgs._, '--skipGetStarted']
|
|
6
|
+
const ignoreKey = ['_', 'p', 'preset', 'i', 'inlinePreset']
|
|
7
|
+
Object.keys(parsedArgs).forEach((key = '') => {
|
|
8
|
+
if (key && !ignoreKey.includes(key)) {
|
|
9
|
+
cmd.push(key.length > 1 ? `--${key}` : `-${key}`)
|
|
10
|
+
cmd.push(parsedArgs[key])
|
|
11
|
+
}
|
|
12
|
+
})
|
|
13
|
+
return cmd
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports.doVueCli = function doVueCli (args) {
|
|
17
|
+
return execa(
|
|
18
|
+
'node',
|
|
19
|
+
[
|
|
20
|
+
vueCliBinPath,
|
|
21
|
+
...args
|
|
22
|
+
],
|
|
23
|
+
{
|
|
24
|
+
stdio: 'inherit'
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
}
|