-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathindex.js
executable file
·162 lines (150 loc) · 4.67 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/env node
const path = require('path')
const fs = require('fs')
const yargs = require('yargs/yargs')
const cp = require('child_process')
const scripts = require('./template/package.json').scripts
const { hideBin } = require('yargs/helpers')
const platform = process.env.__TESTING_FAKE_PLATFORM__ || process.platform
const isWindows = platform === 'win32'
const argv = yargs(hideBin(process.argv))
.usage('Usage: unilaunch <path> --cmd <cmd>')
.command('$0', 'which project dir to run in', (yargs) => {
yargs
.positional('path', {
describe: '*inux 风格项目路径, 绝对路径或者相对运行时的路径, 默认 `.`',
defaultDescription:
'*inux 风格项目路径, 绝对路径或者相对运行时的路径, 默认`.`',
type: 'string',
default: '.'
})
.option('cmd', {
alias: 'c',
defaultDescription: '启动script,同由vue-cli建立的项目中scripts字段',
describe: '启动script,同vue-cli建立的项目scripts字段',
type: 'string',
demandOption: true
})
})
.command('ls', 'list all avalible scripts')
.demandCommand(1)
.example('unilaunch ./ --cmd dev:mp-weixin', '开发环境运行当前目录下项目')
// 最后补充说明部分
.epilogue(
"cmd 可选项同vuecli项目下scripts中字段, 如 ['dev:mp-weixin', 'build:mp-weixin', 'dev:mp-alipay', 'build:mp-alipay']\n" +
'path 不区分windows使用, 统一为/root/path/to/project, or ./project'
).argv
// project 目录参数
const cmdDir = argv._[0]
if (cmdDir === 'ls') {
console.log('All avalible scripts:')
console.log(Object.keys(scripts).join(', '))
return
}
const { error } = require('@vue/cli-shared-utils')
const script = scripts[argv.cmd]
const parsedDir = path.posix.parse(cmdDir)
// 目标 wd
const cwd = process.cwd()
const projectDir = path.resolve(cwd, path.format(parsedDir))
// 切换上下文到本包 wd
process.chdir(path.resolve(__dirname))
if (!script) {
error(`--cmd ${argv.cmd} not found`)
process.exit()
}
// serve: npm run dev:h5
// dev:h5: cross-env NODE_ENV=production vue-cli-serve uniapp-serve
// npm run serve => npm run dev:h5 => cross-env NODE_ENV=production vue-cli-server
const parseScript = function(script) {
switch (true) {
case script.startsWith('npm'): {
script = script.split(' ').pop()
if (scripts[script]) {
return parseScript(scripts[script])
}
}
case script.startsWith('node'):
case script.startsWith('cross-env'): {
// 程序在 uni-project-cli 目录运行
// 指定 jest 目录
if (script.indexOf('jest') !== -1) {
script += ` --projects ${projectDir}`
}
return script
}
}
}
const finalScript = parseScript(script)
const scriptsArgs = yargs(finalScript).argv._
let nodeEnv = 'production'
let buildPlatform = 'h5'
scriptsArgs.forEach((env) => {
if (env.indexOf('NODE_ENV') !== -1) {
nodeEnv = env.split('=')[1]
}
if (env.indexOf('UNI_PLATFORM') !== -1) {
buildPlatform = env.split('=')[1]
}
})
const outPath = path.join(
'unpackage',
nodeEnv === 'production' ? 'build' : 'dev',
buildPlatform
)
process.env.UNI_OUTPUT_DIR = path.join(projectDir, outPath)
process.env.UNI_INPUT_DIR = path.resolve(projectDir)
process.env.UNI_CLI_CONTEXT = process.env.UNI_INPUT_DIR
if (process.env.UNI_SCRIPT) {
const { initCustomScript } = require('@dcloudio/uni-cli-shared/lib/package')
initCustomScript(
process.env.UNI_SCRIPT,
path.resolve(process.env.UNI_INPUT_DIR, 'package.json')
)
}
const vueConfigJsPath = path.resolve(process.env.UNI_INPUT_DIR, 'vue.config.js')
if (fs.existsSync(vueConfigJsPath)) {
process.env.VUE_CLI_SERVICE_CONFIG_PATH = vueConfigJsPath
}
// spawn 参数
const getSpawnArgs = (cmd) => {
let sh = 'sh'
let shFlag = '-c'
const binPath = [
path.join(__dirname, 'node_modules', '.bin'),
path.join(projectDir, 'node_modules', '.bin'),
process.env.PATH
].join(isWindows ? ';' : ':')
const conf = {
env: {
...process.env,
PATH: binPath
},
cwd: process.cwd(),
stdio: [0, 1, 2]
}
if (isWindows || process.env.__TESTING_FAKE_PLATFORM__) {
sh = process.env.comspec || 'cmd'
// '/d /s /c' is used only for cmd.exe.
if (/^(?:.*\\)?cmd(?:\.exe)?$/i.test(sh)) {
shFlag = '/d /s /c'
conf.windowsVerbatimArguments = true
}
}
return [sh, [shFlag, cmd], conf]
}
// 执行到 cmd
console.log(finalScript)
const [sh, env, conf] = getSpawnArgs(finalScript)
// do it
// 模仿 `npm run`
const proc = cp.spawn(sh, env, conf)
process.once('SIGTERM', () => {
proc.kill()
})
process.once('SIGINT', () => {
proc.kill('SIGINT')
proc.on('exit', function() {
process.exit()
})
})