UNPKG

10.8 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3/*
4 * Copyright (C) 2017, hapjs.org. All rights reserved.
5 */
6
7const program = require('commander')
8const chalk = require('chalk')
9const semver = require('semver')
10const { colorconsole } = require('@hap-toolkit/shared-utils')
11const { compileOptionsMeta } = require('@hap-toolkit/shared-utils/compilation-config')
12
13// 最低支持的node版本
14const NODE_MINIMUM_VERSION = '8.0.0'
15
16function checkVersion() {
17 const currentVersion = process.versions.node
18
19 // 若当前版本小于支持版本
20 if (semver.lt(currentVersion, NODE_MINIMUM_VERSION)) {
21 colorconsole.warn(
22 `检测到当前 NodeJS 版本过低,请升级到 NodeJS 版本 ${NODE_MINIMUM_VERSION} 以上`
23 )
24 }
25}
26
27checkVersion()
28
29program.version(require('../package').version, '-v, --version').usage('<command> [options]')
30
31program
32 .command('init <app-name>')
33 .option('--dsl <name>', 'init project by specific dsl template, eg: vue')
34 .description('create a new project.')
35 .action((name, options) => {
36 const generate = require('../lib/commands/init')
37 generate(name, options)
38 })
39
40program
41 .command('build')
42 .description('build the project')
43 .option('--enable-e2e', 'inject test-suite for current project')
44 .option('--stats', 'analyse time and size of webpack output files')
45 .option('--devtool <value>', 'source map config')
46 .option('--disable-subpackages', 'disable subpackages')
47 .option('--disable-stream-pack', 'disable stream pack')
48 .option('--disable-sign', 'disable signature')
49 .option('--disable-script-v8-v65', 'disable compile script match with v8 version 6.5')
50 .option('--optimize-desc-meta', 'optimize desc meta')
51 .option('--optimize-css-attr', 'optimize css attr')
52 .option('--optimize-template-attr', 'optimize template attr')
53 .option('--optimize-style-page-level', 'optimize style in page')
54 .option('--optimize-style-app-level', 'optimize style in app ')
55 .option('--enable-lazy-component', 'lazy load component')
56 .option('--optimize-unused-resource', 'remove unused resource')
57 .option('--include-dsl-from-lib', 'bundle dsl to rpk')
58 .option('--match-sourcemap', 'match sourcemap')
59 .option('--enable-extract-css', 'extract css to json')
60 .option(
61 '--split-chunks-mode <value>',
62 'extract js module to single files',
63 validateSplitChunksMode
64 )
65 .option('--remove-ux-style', 'remove style object in js')
66 .option('--enable-istanbul', 'enable coverage for ux/js files')
67 .option('--enable-performance-check', 'inject performance log in code')
68 .option(
69 '--enable-diagnosis [value]',
70 'proxy console object, send log to server, write into project/logs'
71 )
72 .action(options => {
73 // 必备参数:当开发者不传递该参数时,要解析为默认
74 const signModeTmp = options.disableSign && compileOptionsMeta.signModeEnum.NULL
75 options.signMode = validateSignMode(signModeTmp, compileOptionsMeta.signModeEnum.BUILD)
76
77 const { compile } = require('../lib/commands/compile')
78 compile('native', 'dev', false, options)
79 })
80
81program
82 .command('debug', { noHelp: true })
83 .description('debug the project')
84 .option('--open-browser', 'open QR code page in default browser')
85 .action(options => {
86 const { launchServer } = require('@hap-toolkit/server')
87 const { openBrowser } = options
88 launchServer({
89 modules: ['debugger'],
90 port: 8081,
91 openBrowser
92 })
93 })
94
95program
96 .command('server')
97 .description('open server for project')
98 .option('--port <port>', 'specified port')
99 .option('--watch', 'recompile project while file changes')
100 .option('--clear-records', 'clear device records')
101 .option('--disable-adb', 'disable adb debug')
102 .option('--chrome-path <chrome-path>', 'support for a user specified chrome path')
103 .option('--open-browser', 'open QR code page in default browser')
104 .option('--include-dsl-from-lib', 'bundle dsl to rpk')
105 .option('--enable-performance-check', 'inject performance log in code')
106 .action(options => {
107 const { launchServer } = require('@hap-toolkit/server')
108 const { compile } = require('../lib/commands/compile')
109 const { port, watch, clearRecords, chromePath, disableAdb, openBrowser } = options
110 launchServer({
111 port,
112 watch,
113 clearRecords,
114 chromePath,
115 disableADB: disableAdb,
116 openBrowser
117 })
118 if (options.watch) {
119 compile('native', 'dev', true, options)
120 }
121 })
122
123program
124 .command('watch')
125 .description('recompile project while file changes')
126 .option('--enable-e2e', 'inject test-suite for current project')
127 .option('--devtool <value>', 'source map config')
128 .option('--disable-subpackages', 'disable subpackages')
129 .option('--disable-stream-pack', 'disable stream pack')
130 .option('--disable-script-v8-v65', 'disable compile script match with v8 version 6.5')
131 .option('--include-dsl-from-lib', 'bundle dsl to rpk')
132 .option('--match-sourcemap', 'match sourcemap')
133 .option('--enable-extract-css', 'extract css to json')
134 .option(
135 '--split-chunks-mode <value>',
136 'extract js module to single files',
137 validateSplitChunksMode
138 )
139 .option('--remove-ux-style', 'remove style object in js')
140 .option('--enable-istanbul', 'enable coverage for ux/js files')
141 .option('--enable-performance-check', 'inject performance log in code')
142 .option(
143 '--enable-diagnosis [value]',
144 'proxy console object, send log to server, write into project/logs'
145 )
146 .action(options => {
147 const { compile } = require('../lib/commands/compile')
148 compile('native', 'dev', true, options)
149 })
150
151program
152 .command('release')
153 .description('release the project')
154 .option('--enable-e2e', 'inject test-suite for current project')
155 .option('--stats', 'analyse time and size of webpack output files')
156 .option('--devtool <value>', 'source map config')
157 .option('--disable-subpackages', 'disable subpackages')
158 .option('--disable-stream-pack', 'disable stream pack')
159 .option('--disable-sign', 'disable signature')
160 .option('--disable-script-v8-v65', 'disable compile script match with v8 version 6.5')
161 .option('--optimize-desc-meta', 'optimize desc meta')
162 .option('--optimize-css-attr', 'optimize css attr')
163 .option('--optimize-template-attr', 'optimize template attr')
164 .option('--optimize-style-page-level', 'optimize style in page')
165 .option('--optimize-style-app-level', 'optimize style in app ')
166 .option('--enable-lazy-component', 'lazy load component')
167 .option('--optimize-unused-resource', 'remove unused resource')
168 .option('--include-dsl-from-lib', 'bundle dsl to rpk')
169 .option('--match-sourcemap', 'match sourcemap')
170 .option('--enable-extract-css', 'extract css to json')
171 .option(
172 '--split-chunks-mode <value>',
173 'extract js module to single files',
174 validateSplitChunksMode
175 )
176 .option('--remove-ux-style', 'remove style object in js')
177 .option('--enable-istanbul', 'enable coverage for ux/js files')
178 .option('--enable-performance-check', 'inject performance log in code')
179 .option(
180 '--enable-diagnosis [value]',
181 'proxy console object, send log to server, write into project/logs'
182 )
183 .action(options => {
184 // 必备参数:当开发者不传递该参数时,要解析为默认
185 const signModeTmp = options.disableSign && compileOptionsMeta.signModeEnum.NULL
186 options.signMode = validateSignMode(signModeTmp, compileOptionsMeta.signModeEnum.RELEASE)
187
188 const { compile } = require('../lib/commands/compile')
189 compile('native', 'prod', false, options)
190 })
191
192program
193 .command('preview <target>')
194 .description('preview app in your browser')
195 .option('--port <port>', 'specified port', 8989)
196 .action((target, options) => {
197 const preview = require('../lib/commands/preview')
198 preview(target, options)
199 })
200
201program
202 .command('postinstall', { noHelp: true })
203 .description('Transpiling async/await for nodejs<7.6.x, deprecated.')
204 .action(() => {
205 colorconsole.warn('Deprecated command!')
206 })
207
208// TODO
209// Since we properly have all dependencies included,
210// and if we make {babel, eslint}-configuration built-in,
211// we won't need this `update` command anymore.
212program
213 .command('update')
214 .description('update tools for project')
215 .option('--force', 'force update tools for project')
216 .option('--update-deps', 'update dependencies directly', { noHelp: true })
217 .action(options => {
218 const update = require('../lib/commands/update')
219 colorconsole.warn('hap-toolkit>=0.1.0 不再需要运行此命令\n')
220 update(options)
221 })
222
223program
224 .command('report', { noHelp: true })
225 .description('collect system information and create report.log')
226 .action(() => {
227 const report = require('../lib/commands/report')
228 report()
229 })
230
231program
232 .command('view <rpk-path>')
233 .description('run server to view rpk')
234 .option('--port <port>', 'specified port', 8000)
235 .option('--open-browser', 'open QR code page in default browser')
236 .action((rpkPath, options) => {
237 const { launchServer } = require('@hap-toolkit/server')
238 const { port, openBrowser } = options
239 launchServer({
240 port,
241 openBrowser,
242 rpkPath
243 })
244 })
245
246program
247 .command('resign')
248 .description('resign the rpk/rpks packages')
249 .option('--sign <dir>', 'folder where your signature stored', 'sign/release')
250 .option('--file <dir>', 'rpk that need to be re-signed')
251 .option('--origin <dir>', 'folder where unsigned rpk(s) stored', 'dist')
252 .option('--dest <dir>', 'folder where re-signed rpk(s) stored', 'dest')
253 .action(options => {
254 const { resign } = require('../lib/commands/resign')
255 resign(options)
256 })
257
258program.on('--help', () => {
259 console.log()
260 console.log(`Run ${chalk.cyan(`hap <command> --help`)} for detailed usage of given command.`)
261 console.log()
262})
263
264// 更改 NodeJS 10.1.0 上的 "fs.promise is Experiment" 日志输出位置
265require('fs-extra')
266setTimeout(() => {
267 program.parse(process.argv)
268
269 if (!process.argv.slice(2).length) {
270 program.outputHelp()
271 }
272}, 0)
273
274function validateSignMode(value, defaultValue) {
275 // 无值则为空串
276 if ([null, undefined].includes(value)) {
277 value = defaultValue
278 }
279
280 // 转成枚举常量比较
281 value = value.toUpperCase()
282
283 let ret = value
284
285 if (!compileOptionsMeta.signModeEnum[value]) {
286 ret = defaultValue
287 colorconsole.warn(`当前signMode参数不支持: ${value} ,改为默认值:${ret}`)
288 }
289 return ret
290}
291
292/**
293 * 校验SplitChunkMode参数的有效值
294 * @param value {string}
295 * @return {string}
296 */
297function validateSplitChunksMode(value) {
298 // 转成枚举常量比较
299 value = value.toUpperCase()
300
301 let ret = value
302
303 if (!compileOptionsMeta.splitChunksModeEnum[value]) {
304 ret = compileOptionsMeta.splitChunksModeEnum.REDUNDANCY
305 colorconsole.warn(`当前splitChunksMode参数不支持: ${value} ,改为默认值:${ret}`)
306 }
307 return ret
308}