aiot-toolkit 1.0.18-aspect-beta.22 → 1.0.18-aspect-beta.23
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/lib/commands/compile.js +388 -1
- package/lib/commands/debug.js +673 -1
- package/lib/commands/init.js +255 -1
- package/lib/commands/packages.js +86 -1
- package/lib/commands/preview.js +19 -1
- package/lib/commands/report.js +60 -1
- package/lib/commands/resign.js +88 -1
- package/lib/commands/transform.js +223 -1
- package/lib/commands/update.js +358 -1
- package/lib/commands/utils.js +523 -1
- package/lib/index.js +85 -1
- package/lib/plugins/manifest-watch-plugin.js +123 -1
- package/lib/utils.js +110 -1
- package/package.json +9 -9
package/lib/commands/compile.js
CHANGED
|
@@ -1,2 +1,389 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _ziputil = require("@aiot-toolkit/packager/lib/common/ziputil");
|
|
4
|
+
|
|
5
|
+
var _config = _interopRequireDefault(require("@aiot-toolkit/shared-utils/config"));
|
|
6
|
+
|
|
7
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
* Copyright (C) 2017, hapjs.org. All rights reserved.
|
|
11
|
+
*/
|
|
12
|
+
const webpack = require('webpack');
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
setCustomConfig,
|
|
16
|
+
colorconsole,
|
|
17
|
+
getProjectJson,
|
|
18
|
+
getManifest,
|
|
19
|
+
readJson
|
|
20
|
+
} = require('@aiot-toolkit/shared-utils');
|
|
21
|
+
|
|
22
|
+
const genWebpackConf = require('../../gen-webpack-conf');
|
|
23
|
+
|
|
24
|
+
const {
|
|
25
|
+
summaryErrors,
|
|
26
|
+
summaryWarnings,
|
|
27
|
+
getAspectEntries,
|
|
28
|
+
cleanOrCreateDir,
|
|
29
|
+
copyFiles,
|
|
30
|
+
getProductionTypes,
|
|
31
|
+
isMirtosDevice,
|
|
32
|
+
deleteCompressedFiles,
|
|
33
|
+
getAndCopyDeviceAspectResource
|
|
34
|
+
} = require('./utils');
|
|
35
|
+
|
|
36
|
+
const {
|
|
37
|
+
validateConfigJson
|
|
38
|
+
} = require('../../gen-webpack-conf/validate');
|
|
39
|
+
|
|
40
|
+
const path = require('path');
|
|
41
|
+
|
|
42
|
+
const fs = require('fs'); // webpack watch 模式返回的watching实例
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
let watching = null; // 打包多aspect项目的rpk名字
|
|
46
|
+
|
|
47
|
+
let appName;
|
|
48
|
+
|
|
49
|
+
function showVersion() {
|
|
50
|
+
const toolkitVer = require('../../package.json').version;
|
|
51
|
+
|
|
52
|
+
const babelVer = require('@babel/core/package.json').version;
|
|
53
|
+
|
|
54
|
+
const webpackVer = require('webpack/package.json').version;
|
|
55
|
+
|
|
56
|
+
colorconsole.info(`aiot-toolkit: ${toolkitVer}; babel: ${babelVer}; webpack: ${webpackVer};`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
showVersion();
|
|
60
|
+
/**
|
|
61
|
+
* 调用 webpack 进行编译
|
|
62
|
+
*
|
|
63
|
+
* @module compile
|
|
64
|
+
* @param {String} platform - 目标平台: native
|
|
65
|
+
* @param {dev|prod} mode - 编译模式: dev、prod
|
|
66
|
+
* @param {Boolean} watch - 是否监听
|
|
67
|
+
* @param {Object} [options={}] - 动态生成 webpack 配置项的参数对象
|
|
68
|
+
* @param {String} [options.cwd] - 工作目录
|
|
69
|
+
* @param {Writable} [options.log] - 日志输出流
|
|
70
|
+
* @param {String} [options.originType] - 打包来源,ide|cmd
|
|
71
|
+
* @param {Function} [options.onerror] - 错误回调函数
|
|
72
|
+
* @param {String} [options.setPreviewPkgPath] - 预览包保存路径,由IDE传入
|
|
73
|
+
* @returns {Promise} - 返回 项目 成功与否的信息
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
module.exports.compile = async function compile(platform, mode, watch, options = {}) {
|
|
77
|
+
var _getProjectJson;
|
|
78
|
+
|
|
79
|
+
// 检查.project.json文件,获取projectType
|
|
80
|
+
let projectType = (_getProjectJson = getProjectJson()) === null || _getProjectJson === void 0 ? void 0 : _getProjectJson.projectType;
|
|
81
|
+
let res; // 是否为aspect项目
|
|
82
|
+
|
|
83
|
+
if (projectType === 'distributed') {
|
|
84
|
+
_config.default.aspectTemplate.isAspect = true; // 对多aspect项目进行打包
|
|
85
|
+
|
|
86
|
+
res = await aspectProjectCompiler(platform, mode, watch, options);
|
|
87
|
+
} else {
|
|
88
|
+
res = await singleCompiler(platform, mode, watch, options);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return res;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
*
|
|
95
|
+
* @param {*} platform - 目标平台: native
|
|
96
|
+
* @param {*} mode - 编译模式: dev、prod
|
|
97
|
+
* @param {*} watch - 是否监听
|
|
98
|
+
* @param {*} options - 动态生成 webpack 配置项的参数对象
|
|
99
|
+
* @returns {Promise} - 返回 打包列表 成功与否的信息
|
|
100
|
+
*/
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
async function aspectProjectCompiler(platform, mode, watch, options = {}) {
|
|
104
|
+
// 检查app/manifest.json文件
|
|
105
|
+
let app_manifest = getManifest(); // 打包rpk时使用的package值
|
|
106
|
+
|
|
107
|
+
appName = app_manifest.package || 'demo'; // 获取 app/manifest.json下的项目入口
|
|
108
|
+
|
|
109
|
+
const {
|
|
110
|
+
entries,
|
|
111
|
+
deviceAspects,
|
|
112
|
+
routerObj
|
|
113
|
+
} = getAspectEntries(_config.default.aspectTemplate.projectPath, app_manifest); // 校验config.js的内容
|
|
114
|
+
|
|
115
|
+
validateConfigJson(entries); // 清空DIST、BUILD文件夹
|
|
116
|
+
|
|
117
|
+
const DIST = _config.default.aspectTemplate.distPath;
|
|
118
|
+
const BUILD = _config.default.aspectTemplate.outputPath;
|
|
119
|
+
cleanOrCreateDir(BUILD);
|
|
120
|
+
cleanOrCreateDir(DIST);
|
|
121
|
+
const APPBUILD = path.join(BUILD, appName);
|
|
122
|
+
const allEntries = [];
|
|
123
|
+
|
|
124
|
+
async function compilerApp(isAllPkg, velaProduction, appPath, app_devices) {
|
|
125
|
+
_config.default.aspectTemplate.outputPath = APPBUILD;
|
|
126
|
+
_config.default.sourceRoot = '';
|
|
127
|
+
_config.default.aspectTemplate.isApp = true;
|
|
128
|
+
options.cwd = appPath;
|
|
129
|
+
const appProductionTypes = getProductionTypes(app_devices);
|
|
130
|
+
|
|
131
|
+
if (isAllPkg) {
|
|
132
|
+
// 分产物类型打包
|
|
133
|
+
for (const key of Object.keys(appProductionTypes)) {
|
|
134
|
+
if (appProductionTypes[key]) {
|
|
135
|
+
_config.default.aspectTemplate.packToVela = key === 'enableMirtos';
|
|
136
|
+
const entryName = _config.default.aspectTemplate.packToVela ? 'app.lite' : 'app';
|
|
137
|
+
allEntries.push(entryName);
|
|
138
|
+
await singleCompiler(platform, mode, watch, options);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
_config.default.aspectTemplate.packToVela = velaProduction;
|
|
143
|
+
await singleCompiler(platform, mode, watch, options);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async function compilerAspect(entries, allEntries, isPkgToRpk) {
|
|
148
|
+
for (let entry of entries) {
|
|
149
|
+
_config.default.aspectTemplate.outputPath = isPkgToRpk ? BUILD : APPBUILD;
|
|
150
|
+
_config.default.sourceRoot = './src';
|
|
151
|
+
_config.default.aspectTemplate.isApp = false;
|
|
152
|
+
options.cwd = path.join(_config.default.aspectTemplate.projectPath, entry);
|
|
153
|
+
_config.default.aspectTemplate.packToVela = false; // 读取deviceTypeList
|
|
154
|
+
|
|
155
|
+
let aspect_manifestFile = path.resolve(options.cwd, _config.default.sourceRoot, 'manifest.json');
|
|
156
|
+
|
|
157
|
+
if (!fs.existsSync(aspect_manifestFile)) {
|
|
158
|
+
// 报错,文件不存在
|
|
159
|
+
throw new Error(`the file ${aspect_manifestFile} cannot be found.`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const aspect_manifest = readJson(aspect_manifestFile);
|
|
163
|
+
const {
|
|
164
|
+
deviceTypeList
|
|
165
|
+
} = aspect_manifest;
|
|
166
|
+
|
|
167
|
+
if (deviceTypeList && Array.isArray(deviceTypeList)) {
|
|
168
|
+
// 根据配置打包成多种产物
|
|
169
|
+
const productionTypes = getProductionTypes(deviceTypeList);
|
|
170
|
+
|
|
171
|
+
for (const key of Object.keys(productionTypes)) {
|
|
172
|
+
if (productionTypes[key]) {
|
|
173
|
+
_config.default.aspectTemplate.packToVela = key === 'enableMirtos';
|
|
174
|
+
const entryName = _config.default.aspectTemplate.packToVela ? entry + '.lite' : entry;
|
|
175
|
+
allEntries.push(entryName);
|
|
176
|
+
await singleCompiler(platform, mode, watch, options);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
allEntries.push(entry);
|
|
181
|
+
await singleCompiler(platform, mode, watch, options);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
// 记录是否打包为rpk后缀
|
|
188
|
+
const isPkgToRpk = options.output === 'rpk';
|
|
189
|
+
await compilerAspect(entries, allEntries, isPkgToRpk); // 按照当前理解的意思是,到目前为止,已完成打包
|
|
190
|
+
|
|
191
|
+
if (isPkgToRpk) {
|
|
192
|
+
// 1. 将build下的子aspc移到dist目录下
|
|
193
|
+
// 2. 修改aspc的后缀为rpk
|
|
194
|
+
deleteCompressedFiles(BUILD, true, DIST); // 3. deploy参数存在时,再打一个打的总包
|
|
195
|
+
|
|
196
|
+
if (options.deploy) {
|
|
197
|
+
await deployAll('', DIST, _config.default.aspectTemplate.projectPath);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return Promise.resolve();
|
|
201
|
+
} // 记录原始的manifest.json
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
routerObj['all'] = app_manifest.router.aspects;
|
|
205
|
+
deviceAspects['all'] = allEntries; // 分设备打包
|
|
206
|
+
|
|
207
|
+
const appPath = path.join(_config.default.aspectTemplate.projectPath, 'app');
|
|
208
|
+
const manifestPath = path.join(appPath, 'manifest.json');
|
|
209
|
+
let device_manifest = JSON.parse(JSON.stringify(app_manifest)); // 获取总包all中app文件夹的设备列表
|
|
210
|
+
|
|
211
|
+
const {
|
|
212
|
+
deviceTypeList: app_devices
|
|
213
|
+
} = app_manifest; // 复制一份临时文件.manifest.json
|
|
214
|
+
|
|
215
|
+
const tempManifestPath = path.join(appPath, '.manifest.json');
|
|
216
|
+
fs.writeFileSync(tempManifestPath, JSON.stringify(app_manifest));
|
|
217
|
+
|
|
218
|
+
for (let deviceName of Object.keys(deviceAspects)) {
|
|
219
|
+
// 判断设备包是否需要vela产物
|
|
220
|
+
const velaProduction = isMirtosDevice(deviceName); // 记录是否为总包
|
|
221
|
+
|
|
222
|
+
let isAllPkg = deviceName === 'all'; // 分设备打包 设备包名: packageName-设备名-rule(屏幕规则:圆形、方形)
|
|
223
|
+
|
|
224
|
+
let name = isAllPkg ? appName : appName + '.' + deviceName.trim().replace(' ', '.'); // 更新app/manifest.json中的路由
|
|
225
|
+
|
|
226
|
+
device_manifest.router.aspects = routerObj[deviceName]; // 更新app/manifest.json中的包名
|
|
227
|
+
// device_manifest.package = name
|
|
228
|
+
|
|
229
|
+
fs.writeFileSync(manifestPath, JSON.stringify(device_manifest, null, 2)); // 打包app.base
|
|
230
|
+
|
|
231
|
+
await compilerApp(isAllPkg, velaProduction, appPath, app_devices); // 打设备包
|
|
232
|
+
|
|
233
|
+
let deviceAspectsArr = [];
|
|
234
|
+
|
|
235
|
+
if (isAllPkg) {
|
|
236
|
+
for (const item of deviceAspects[deviceName]) {
|
|
237
|
+
const aspectName = item === 'app' || item === 'app.lite' ? item + '.base' : item + '.aspc';
|
|
238
|
+
deviceAspectsArr.push({
|
|
239
|
+
name: item,
|
|
240
|
+
targetFile: aspectName,
|
|
241
|
+
otherName: aspectName
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
} else {
|
|
245
|
+
!isPkgToRpk && deviceAspects[deviceName].unshift('app');
|
|
246
|
+
deviceAspectsArr = getAndCopyDeviceAspectResource(deviceAspects[deviceName], APPBUILD, name, velaProduction);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const suffixName = '.app';
|
|
250
|
+
const destPath = path.join(DIST, name + suffixName);
|
|
251
|
+
await (0, _ziputil.packFolderToApp)(destPath, deviceAspectsArr, APPBUILD);
|
|
252
|
+
} // 打包完成后 删除build下的子rpk
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
deleteCompressedFiles(APPBUILD); // 打包完成,删除临时文件.mainifest.json
|
|
256
|
+
|
|
257
|
+
fs.unlinkSync(tempManifestPath); // deploy参数存在时,再打一个打的总包
|
|
258
|
+
|
|
259
|
+
if (options.deploy) {
|
|
260
|
+
await deployAll(manifestPath, DIST, _config.default.aspectTemplate.projectPath);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return Promise.resolve();
|
|
264
|
+
} catch (error) {
|
|
265
|
+
console.log(`Distributed project compiler error ${error}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
*
|
|
270
|
+
* @param {*} platform - 目标平台: native
|
|
271
|
+
* @param {*} mode - 编译模式: dev、prod
|
|
272
|
+
* @param {*} watch - 是否监听
|
|
273
|
+
* @param {*} options - 动态生成 webpack 配置项的参数对象
|
|
274
|
+
* @returns {Promise} - 返回 打包 成功与否的信息
|
|
275
|
+
*/
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
function singleCompiler(platform, mode, watch, options = {}) {
|
|
279
|
+
const errCb = options.onerror;
|
|
280
|
+
return new Promise((resolve, reject) => {
|
|
281
|
+
colorconsole.attach(options.log);
|
|
282
|
+
setCustomConfig(options.cwd); // IMPORTANT: set env variables before generating webpack config
|
|
283
|
+
|
|
284
|
+
process.env.NODE_PLATFORM = platform;
|
|
285
|
+
process.env.NODE_PHASE = mode;
|
|
286
|
+
|
|
287
|
+
function compilationCallback(err, stats) {
|
|
288
|
+
if (err) {
|
|
289
|
+
errCb && errCb(err);
|
|
290
|
+
colorconsole.error(err);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (stats) {
|
|
294
|
+
if (stats.hasErrors() || stats.hasWarnings()) {
|
|
295
|
+
const message = summaryErrors(stats);
|
|
296
|
+
const warningMsg = summaryWarnings(stats);
|
|
297
|
+
errCb && errCb(message);
|
|
298
|
+
colorconsole.error(message);
|
|
299
|
+
colorconsole.warn(warningMsg);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (stats.hasErrors()) {
|
|
303
|
+
process.exitCode = 1;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const webpackMode = mode === 'prod' ? 'production' : 'development';
|
|
309
|
+
|
|
310
|
+
try {
|
|
311
|
+
const webpackConfig = genWebpackConf(options, webpackMode);
|
|
312
|
+
|
|
313
|
+
if (_config.default.aspectTemplate.isAspect && options.output === 'rpk') {
|
|
314
|
+
webpackConfig.output.filename = pathData => {
|
|
315
|
+
return pathData.chunk.name === 'aspect' ? 'app.js' : '[name].js';
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (watch) {
|
|
320
|
+
const compiler = webpack(webpackConfig);
|
|
321
|
+
watching = compiler.watch({
|
|
322
|
+
aggregateTimeout: 300
|
|
323
|
+
}, (err, stats) => {
|
|
324
|
+
compilationCallback(err, stats);
|
|
325
|
+
resolve({
|
|
326
|
+
compileError: err,
|
|
327
|
+
stats,
|
|
328
|
+
watching
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
} else {
|
|
332
|
+
webpack(webpackConfig, (err, stats) => {
|
|
333
|
+
compilationCallback(err, stats);
|
|
334
|
+
resolve({
|
|
335
|
+
compileError: err,
|
|
336
|
+
stats
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
} catch (err) {
|
|
341
|
+
console.log(`singleCompiler error ${err}`);
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
async function deployAll(manifestPath, DIST, projectPath) {
|
|
347
|
+
// 复制app/manifest.json到build文件夹下
|
|
348
|
+
if (manifestPath) {
|
|
349
|
+
fs.copyFileSync(manifestPath, path.join(DIST, 'manifest.json'));
|
|
350
|
+
} // 开始打包
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
const destPath = path.join(DIST, path.basename(projectPath) + '.zip');
|
|
354
|
+
const files = fs.readdirSync(DIST);
|
|
355
|
+
const fileArr = files.map(file => {
|
|
356
|
+
return {
|
|
357
|
+
name: file,
|
|
358
|
+
targetFile: file,
|
|
359
|
+
otherName: file
|
|
360
|
+
};
|
|
361
|
+
});
|
|
362
|
+
await (0, _ziputil.packFolderToApp)(destPath, fileArr, DIST);
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* 停止 webpack watch监听
|
|
366
|
+
*
|
|
367
|
+
* @module stopWatch
|
|
368
|
+
* @returns {Promise} - 返回成功与否的信息
|
|
369
|
+
*/
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
module.exports.stopWatch = function () {
|
|
373
|
+
return new Promise(resolve => {
|
|
374
|
+
if (watching) {
|
|
375
|
+
watching.close(() => {
|
|
376
|
+
watching = null;
|
|
377
|
+
resolve({
|
|
378
|
+
stopWatchError: null
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
resolve({
|
|
385
|
+
stopWatchError: 'no watching'
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
};
|
|
2
389
|
//# sourceMappingURL=compile.js.map
|