jh5_app_build 1.0.15 → 1.0.18

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/.eslintrc.js CHANGED
@@ -126,7 +126,7 @@ module.exports = {
126
126
  "no-iterator": "error",
127
127
  "no-label-var": "error",
128
128
  "no-labels": "error",
129
- "no-lone-blocks": "error",
129
+ "no-lone-blocks": "off",
130
130
  "no-lonely-if": "error",
131
131
  "no-loop-func": "off",
132
132
  "no-magic-numbers": "off",
@@ -9,6 +9,8 @@ var jlog = jutils.jlog(__filename);
9
9
 
10
10
  var AdmZip = require('adm-zip');
11
11
 
12
+ var inquirer = require('inquirer');
13
+
12
14
  // 关闭日志输出
13
15
  jlog.setEnable(false, "*");
14
16
 
@@ -71,6 +73,21 @@ function getBuildCfg(cmd) {
71
73
  return buildCfg;
72
74
  }
73
75
 
76
+ /**
77
+ * 检查项目
78
+ * @param {*} buildCfg 构建配置
79
+ * @returns {void}
80
+ */
81
+ function chkProj(buildCfg) {
82
+ // 判断是否为h5项目
83
+ if (!fs.existsSync(buildCfg.rootPath + "/public/index.html")) {
84
+ console.error("The directory is not valid");
85
+ process.exit(-1);
86
+ return null;
87
+ }
88
+ }
89
+
90
+
74
91
  // 命令
75
92
  program
76
93
  .command('build')
@@ -86,6 +103,36 @@ program
86
103
  // 获取配置
87
104
  var buildCfg = getBuildCfg(cmd);
88
105
 
106
+ // 检查项目
107
+ chkProj(buildCfg);
108
+
109
+ // 选择编译类型
110
+ var answers = await inquirer.prompt([
111
+ {
112
+ type: 'list',
113
+ name: 'platform',
114
+ message: 'Please select a compilation platform:',
115
+ choices: [
116
+ {
117
+ name: 'Weds device(*.jap file)',
118
+ value: "weds"
119
+ },
120
+ {
121
+ name: 'Std device(*.apk file)',
122
+ value: "std"
123
+ },
124
+ {
125
+ name: 'Std device lite(*.apk file,no web)',
126
+ value: "std,noweb"
127
+ }
128
+ ]
129
+ }
130
+ ]);
131
+ buildCfg.platform = answers.platform.split(",");
132
+
133
+ // 标准应用
134
+ buildCfg.isStdApp = buildCfg.platform.includes("std");
135
+
89
136
  // 缺省输出文件
90
137
  if (cmd.outpath) {
91
138
  buildCfg.outpath = cmd.outpath;
@@ -107,19 +154,27 @@ program
107
154
  buildCfg.dateStr = jutils.getNowDate().replace(/(-|:)/g, "").replace(/ /g, "_").substr(2, 11);
108
155
 
109
156
  // 处理文件名
110
- buildCfg.outpath = `${process.cwd()}/jh5_${buildCfg.appName}_${buildCfg.dateStr}.jap`;
157
+ buildCfg.outpath = `${process.cwd()}/jh5_${buildCfg.appName}_${buildCfg.dateStr}.${buildCfg.isStdApp ? "apk" : "jap"}`;
111
158
  }
112
159
  buildCfg.outpath = path.resolve(buildCfg.outpath);
113
160
  jfile_utils.createDirs(buildCfg.outpath, true); // 建立目录
114
161
  console.log("[Out path] " + buildCfg.outpath);
115
162
 
116
- // 执行编译
117
- await require('../lib/build_japp')(cmd, buildCfg);
163
+ // 标准应用
164
+ if (buildCfg.isStdApp) {
165
+ // 执行编译
166
+ await require('../lib/build_std')(cmd, buildCfg);
167
+ }
168
+ // weds 应用
169
+ else {
170
+ // 执行编译
171
+ await require('../lib/build_japp')(cmd, buildCfg);
172
+ }
118
173
 
119
174
  // 执行自定义脚本
120
175
  var scriptObj = await loadUpdateScript(buildCfg.rootPath);
121
176
  if (scriptObj.build) {
122
- console.log("run script...");
177
+ console.log("run build script...");
123
178
  try {
124
179
  await scriptObj.build(cmd, buildCfg);
125
180
  } catch (error) {
@@ -131,6 +186,82 @@ program
131
186
  });
132
187
 
133
188
 
189
+ /**
190
+ * 升级函数
191
+ * @param {*} cmd 命令行
192
+ * @returns {void}
193
+ */
194
+ async function cmdUpdate(cmd) {
195
+ // 获取配置
196
+ var buildCfg = getBuildCfg(cmd);
197
+
198
+ // 检查项目
199
+ chkProj(buildCfg);
200
+
201
+ // 使用开发版
202
+ if (!cmd.ver && cmd.insiders) cmd.ver = "insiders";
203
+
204
+ // 获取版本
205
+ try {
206
+ var verData = await jutils.jhttp_utils.postJson(`http://reg.weds.com.cn:6608/res/get_build_pkg`, {
207
+ ver: cmd.ver || ""
208
+ }, {
209
+ stdBody: true
210
+ });
211
+ if (!verData.url) {
212
+ console.log("no url!");
213
+ return;
214
+ }
215
+ console.log("pkg version:" + verData.version);
216
+ console.log("start download");
217
+ } catch (error) {
218
+ console.error(error.message);
219
+ return;
220
+ }
221
+ // 下载
222
+ var downFilePath = buildCfg.rootPath + "/temp.jzip";
223
+ var perTimer = null;
224
+ await jutils.jhttp_utils.downloadFile(`http://reg.weds.com.cn:6608/${verData.url}`, downFilePath, {
225
+ }, (res, dwObj) => {
226
+ // 进度
227
+ perTimer = setInterval(() => {
228
+ console.log(`download [${parseInt(dwObj.current * 100 / dwObj.total, 10)}%] ${dwObj.current}/${dwObj.total}`);
229
+ }, 1000);
230
+ });
231
+ if (perTimer) {
232
+ clearInterval(perTimer);
233
+ }
234
+
235
+ // 删除旧资源
236
+ console.log("delete jbuild_data...");
237
+ await jutils.jfile_utils.deleteFolder(buildCfg.rootPath + "/jbuild_data");
238
+
239
+ // 解压
240
+ console.log("unpack...");
241
+ var myZip = new AdmZip(downFilePath);
242
+ myZip.extractAllTo(buildCfg.rootPath, true);
243
+ await jutils.jfile_utils.unlink(downFilePath);
244
+ try {
245
+ fs.writeFileSync(buildCfg.rootPath + "/jbuild_data/info.txt", JSON.stringify({
246
+ version: verData.version
247
+ }, null, 4));
248
+ } catch (error) {
249
+ }
250
+
251
+ // 执行自定义脚本
252
+ var scriptObj = await loadUpdateScript(buildCfg.rootPath);
253
+ if (scriptObj.update) {
254
+ console.log("run update script...");
255
+ try {
256
+ await scriptObj.update(cmd, buildCfg);
257
+ } catch (error) {
258
+ console.error(error);
259
+ }
260
+ }
261
+
262
+ console.log("update finish,ver:" + verData.version);
263
+ }
264
+
134
265
  // 命令
135
266
  program
136
267
  .command('update')
@@ -139,16 +270,80 @@ program
139
270
  .option('-i, --insiders', 'use last insiders version')
140
271
  .option('-d, --details', 'show list files details')
141
272
  .option('-e, --exparam <param>', 'ext param')
273
+ .action(cmdUpdate);
274
+
275
+
276
+ // 命令
277
+ program
278
+ .command('clean')
279
+ .option('-c, --config <file>', 'Config file')
280
+ .option('-d, --details', 'show list files details')
142
281
  .action(async (cmd) => {
143
282
  // 获取配置
144
283
  var buildCfg = getBuildCfg(cmd);
145
284
 
285
+ // 检查项目
286
+ chkProj(buildCfg);
287
+
288
+ console.log("clean...");
289
+
290
+ // 删除下载包
291
+ console.log("delete dist...");
292
+ await jutils.jfile_utils.deleteFolder(buildCfg.rootPath + "/dist");
293
+ // console.log("delete jbuild_data...");
294
+ // await jutils.jfile_utils.deleteFolder(buildCfg.rootPath + "/jbuild_data");
295
+
296
+ // 删除生成的文件
297
+ var filelist = await jutils.jfile_utils.readdir(buildCfg.rootPath);
298
+ for (let index = 0; index < filelist.length; index++) {
299
+ const element = filelist[index];
300
+ if ([".jzip", ".tmp"].indexOf(path.extname(element)) >= 0) {
301
+ console.log("delete:" + element);
302
+ await jutils.jfile_utils.deleteFile(buildCfg.rootPath + "/" + element);
303
+ }
304
+ }
305
+ console.log("clean finish");
306
+ });
307
+
308
+
309
+ // 命令
310
+ program
311
+ .command('init')
312
+ .option('-n, --pname <pname>', 'use name')
313
+ .option('-v, --ver <ver>', 'use fixed version')
314
+ .option('-i, --insiders', 'use last insiders version')
315
+ .option('-d, --details', 'show list files details')
316
+ .action(async (cmd) => {
317
+ // 获取配置
318
+ var buildCfg = getBuildCfg(cmd);
319
+
320
+ // 判断是否已经存在软件包,防止应用被覆盖
321
+ if (fs.existsSync(path.resolve(buildCfg.rootPath + "/package.json"))
322
+ || fs.existsSync(path.resolve(buildCfg.rootPath + "/src"))) {
323
+ console.error("Project exists in current directory!");
324
+ return;
325
+ }
326
+
327
+ // 应用名
328
+ buildCfg.appName = cmd.pname || "";
329
+ if (!buildCfg.appName) {
330
+ try {
331
+ var appNameTmp = path.basename(buildCfg.rootPath) || "app";
332
+ for (let index = 0; index < appNameTmp.length; index++) {
333
+ if (buildCfg.appName.length < 15 && Math.abs(appNameTmp.charCodeAt(index)) < 255) {
334
+ buildCfg.appName += appNameTmp[index];
335
+ }
336
+ }
337
+ } catch (error) {
338
+ }
339
+ }
340
+
146
341
  // 使用开发版
147
342
  if (!cmd.ver && cmd.insiders) cmd.ver = "insiders";
148
343
 
149
344
  // 获取版本
150
345
  try {
151
- var verData = await jutils.jhttp_utils.postJson(`http://reg.weds.com.cn:6608/res/get_build_pkg`, {
346
+ var verData = await jutils.jhttp_utils.postJson(`http://reg.weds.com.cn:6608/res/get_init_pkg`, {
152
347
  ver: cmd.ver || ""
153
348
  }, {
154
349
  stdBody: true
@@ -157,7 +352,7 @@ program
157
352
  console.log("no url!");
158
353
  return;
159
354
  }
160
- console.log("pkg version:" + verData.version);
355
+ console.log("init version:" + verData.version);
161
356
  console.log("start download");
162
357
  } catch (error) {
163
358
  console.error(error.message);
@@ -177,66 +372,41 @@ program
177
372
  clearInterval(perTimer);
178
373
  }
179
374
 
180
- // 删除旧资源
181
- console.log("delete jbuild_data...");
182
- await jutils.jfile_utils.deleteFolder(buildCfg.rootPath + "/jbuild_data");
183
-
184
375
  // 解压
185
376
  console.log("unpack...");
186
377
  var myZip = new AdmZip(downFilePath);
187
378
  myZip.extractAllTo(buildCfg.rootPath, true);
188
379
  await jutils.jfile_utils.unlink(downFilePath);
380
+
381
+ // 修改package
189
382
  try {
190
- fs.writeFileSync(buildCfg.rootPath + "/jbuild_data/info.txt", JSON.stringify({
191
- version: verData.version
192
- }, null, 4));
383
+ var pkgObj = JSON.parse(fs.readFileSync(buildCfg.rootPath + "/package.json", "utf8"));
384
+ pkgObj.name = buildCfg.appName;
385
+ pkgObj.versionJh5 = verData.version;
386
+ fs.writeFileSync(buildCfg.rootPath + "/package.json", JSON.stringify(pkgObj, null, 4));
193
387
  } catch (error) {
194
388
  }
195
389
 
390
+ // 执行update
391
+ await cmdUpdate({});
392
+
196
393
  // 执行自定义脚本
197
394
  var scriptObj = await loadUpdateScript(buildCfg.rootPath);
198
- if (scriptObj.update) {
199
- console.log("run script...");
395
+ if (scriptObj.init) {
396
+ console.log("run init script...");
200
397
  try {
201
- await scriptObj.update(cmd, buildCfg);
398
+ await scriptObj.init(cmd, buildCfg);
202
399
  } catch (error) {
203
400
  console.error(error);
204
401
  }
205
402
  }
206
403
 
207
- console.log("update finish,ver:" + verData.version);
404
+ console.log("init finish,ver:" + verData.version);
405
+ console.warn("please run:[npm install] to install node_modules.");
208
406
  });
209
407
 
210
408
 
211
409
 
212
- // 命令
213
- program
214
- .command('clean')
215
- .option('-c, --config <file>', 'Config file')
216
- .option('-d, --details', 'show list files details')
217
- .action(async (cmd) => {
218
- // 获取配置
219
- var buildCfg = getBuildCfg(cmd);
220
- console.log("clean...");
221
-
222
- // 删除下载包
223
- console.log("delete dist...");
224
- await jutils.jfile_utils.deleteFolder(buildCfg.rootPath + "/dist");
225
- // console.log("delete jbuild_data...");
226
- // await jutils.jfile_utils.deleteFolder(buildCfg.rootPath + "/jbuild_data");
227
-
228
- // 删除生成的文件
229
- var filelist = await jutils.jfile_utils.readdir(buildCfg.rootPath);
230
- for (let index = 0; index < filelist.length; index++) {
231
- const element = filelist[index];
232
- if ([".jap", ".jzip", ".tmp"].indexOf(path.extname(element)) >= 0) {
233
- console.log("delete:" + element);
234
- await jutils.jfile_utils.deleteFile(buildCfg.rootPath + "/" + element);
235
- }
236
- }
237
- console.log("clean finish");
238
- });
239
-
240
410
  // 开始解析
241
411
  program.parse(process.argv);
242
412
 
@@ -0,0 +1,164 @@
1
+ let glob = require("glob")
2
+ let archiver = require('archiver');
3
+ let jutils = require('base_parts');
4
+
5
+ let fs = require('fs');
6
+ let os = require('os');
7
+ let AdmZip = require('adm-zip');
8
+
9
+ module.exports = async (cmd, buildCfg) => {
10
+ return new Promise((resolve, reject) => {
11
+ (async () => {
12
+
13
+ // 建立压缩文件
14
+ console.log(`build file to ${buildCfg.outpath}`);
15
+ let output = fs.createWriteStream(buildCfg.outpath);
16
+ let archive = archiver('zip', {
17
+ zlib: { level: 9 }
18
+ });
19
+ output.on('close', function () {
20
+ console.log(archive.pointer() + ' total bytes');
21
+ console.log(`build success:${buildCfg.outpath}`);
22
+ resolve();
23
+ });
24
+ output.on('end', function () {
25
+ });
26
+ archive.on('warning', function (err) {
27
+ if (err.code === 'ENOENT') {
28
+ } else {
29
+ reject(err);
30
+ }
31
+ });
32
+ archive.on('error', function (err) {
33
+ reject(err);
34
+ });
35
+ archive.pipe(output);
36
+
37
+ // 修改版本号
38
+ let platformVer = jutils.getUUID();
39
+ try {
40
+ console.log(`change dist ver ...`);
41
+ let repFile = `${buildCfg.rootPath}\\dist\\index.html`;
42
+ let indexStr = fs.readFileSync(repFile, "utf8");
43
+ indexStr = indexStr.replace(/#J_APPNAME#/g, buildCfg.appName);
44
+ indexStr = indexStr.replace(/#J_DATE#/g, buildCfg.dateStr);
45
+
46
+ // 读取H5版本
47
+ try {
48
+ let bInfoStr = fs.readFileSync(`${buildCfg.rootPath}/jbuild_data/info.txt`, "utf8");
49
+ let bInfoObj = JSON.parse(bInfoStr);
50
+ if (bInfoObj.version) {
51
+ platformVer = bInfoObj.version;
52
+ indexStr = indexStr.replace(/#J_H5_VER#/g, bInfoObj.version);
53
+ }
54
+ } catch (error) {
55
+ console.log(`no h5Ver!`);
56
+ }
57
+
58
+ // 保存
59
+ fs.writeFileSync(repFile, indexStr);
60
+ } catch (error) {
61
+ }
62
+
63
+ // 载入apk
64
+ {
65
+ console.log(`load files ...`);
66
+ let myZip = new AdmZip(`${buildCfg.rootPath}/jbuild_data/std_bins/app-release.apk`);
67
+
68
+ // 循环添加
69
+ let zipEntries = myZip.getEntries();
70
+ zipEntries.forEach(function (zipEntry) {
71
+ // 过滤签名
72
+ if (!["META-INF/CERT.RSA", "META-INF/CERT.SF", "META-INF/MANIFEST.MF"].includes(zipEntry.entryName.toUpperCase())) {
73
+ archive.append(zipEntry.getData(), { name: zipEntry.entryName });
74
+ }
75
+ else {
76
+ console.error(">>>>>>>>>" + zipEntry);
77
+ }
78
+ });
79
+ }
80
+
81
+ // 添加用户文件
82
+ {
83
+ let pathSub = "dist";
84
+ console.log(`scaning ${pathSub} ...`);
85
+ let fileList = glob(`${pathSub}/**/*`, {
86
+ dot: true,
87
+ sync: true,
88
+ nodir: true,
89
+ cwd: buildCfg.rootPath,
90
+ ignore: []
91
+ });
92
+ if (fileList.length === 0) {
93
+ console.error("no dist files!");
94
+ return;
95
+ }
96
+ console.log(`add [${fileList.length}] files ...`);
97
+ for (let index = 0; index < fileList.length; index++) {
98
+ let element = fileList[index].substr(pathSub.length + 1);
99
+
100
+ // 添加文件
101
+ archive.append(fs.readFileSync(`${buildCfg.rootPath}/${pathSub}/${element}`), { name: "assets/h5app/" + element });
102
+ }
103
+ }
104
+
105
+ // 需要web
106
+ if (!buildCfg.platform.includes("noweb")) {
107
+ // 添加框架二进制
108
+ {
109
+ let pathSub = "jbuild_data/jext";
110
+ console.log(`scaning ${pathSub} ...`);
111
+ let fileList = glob(`${pathSub}/**/*`, {
112
+ dot: true,
113
+ sync: true,
114
+ nodir: true,
115
+ cwd: buildCfg.rootPath,
116
+ ignore: []
117
+ });
118
+ console.log(`add [${fileList.length}] files ...`);
119
+ for (let index = 0; index < fileList.length; index++) {
120
+ let element = fileList[index].substr(pathSub.length + 1);
121
+
122
+ // 添加文件
123
+ archive.append(fs.readFileSync(`${buildCfg.rootPath}/${pathSub}/${element}`), { name: "assets/jext/" + element });
124
+ }
125
+ }
126
+
127
+ // 添加后台服务
128
+ {
129
+ console.log(`add device_webapi files ...`);
130
+ // 载入zip
131
+ let myZip = new AdmZip(`${buildCfg.rootPath}/jbuild_data/device_webapi.zip`);
132
+
133
+ // 循环添加
134
+ let zipEntries = myZip.getEntries();
135
+ zipEntries.forEach(function (zipEntry) {
136
+ archive.append(zipEntry.getData(), { name: "assets/device_webapi/" + zipEntry.entryName });
137
+ });
138
+
139
+ // 版本号
140
+ archive.append(Buffer.from(platformVer), { name: "assets/device_webapi/info.txt" });
141
+ }
142
+
143
+ }
144
+ // 添加设备信息
145
+ try {
146
+ let pkgInfo = os.networkInterfaces();
147
+ pkgInfo.buildTime = jutils.getNowDate();
148
+ archive.append(JSON.stringify(pkgInfo, null, 4), { name: "assets/build_info.txt" });
149
+ } catch (error) {
150
+ }
151
+
152
+ // 开始压缩
153
+ archive.finalize();
154
+ })().catch((err) => {
155
+ console.error("build error,please run [jh5 update] first.");
156
+ try {
157
+ jutils.jfile_utils.deleteFile(buildCfg.outpath);
158
+ } catch (error) {
159
+ }
160
+ });
161
+ });
162
+
163
+ }
164
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jh5_app_build",
3
- "version": "1.0.15",
3
+ "version": "1.0.18",
4
4
  "description": "jaskle jh5_app_build",
5
5
  "main": "./bin/jh5_app_build.js",
6
6
  "registry": true,
@@ -22,6 +22,7 @@
22
22
  "base_parts": "^2.*",
23
23
  "commander": "^2.*",
24
24
  "glob": "^7.*",
25
+ "inquirer": "^8.2.4",
25
26
  "request": "^2.*"
26
27
  },
27
28
  "devDependencies": {