aiot-toolkit 1.0.18-aspect-beta.21 → 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/bin/index.js CHANGED
@@ -95,6 +95,7 @@ program
95
95
  '--deploy',
96
96
  'compress the device package and manifest.json file in the build into a zip package'
97
97
  )
98
+ .option('--output <value>', 'specify the aspect output format')
98
99
  .action(options => {
99
100
  // 必备参数:当开发者不传递该参数时,要解析为默认
100
101
  const signModeTmp = options.disableSign && compileOptionsMeta.signModeEnum.NULL
@@ -1,2 +1,389 @@
1
- "use strict";var _ziputil=require("@aiot-toolkit/packager/lib/common/ziputil"),_config=_interopRequireDefault(require("@aiot-toolkit/shared-utils/config"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const webpack=require("webpack"),{setCustomConfig:setCustomConfig,colorconsole:colorconsole,getProjectJson:getProjectJson,getManifest:getManifest,readJson:readJson}=require("@aiot-toolkit/shared-utils"),genWebpackConf=require("../../gen-webpack-conf"),{summaryErrors:summaryErrors,summaryWarnings:summaryWarnings,getAspectEntries:getAspectEntries,cleanOrCreateDir:cleanOrCreateDir,copyFiles:copyFiles,getProductionTypes:getProductionTypes,isMirtosDevice:isMirtosDevice,deleteCompressedFiles:deleteCompressedFiles,getAndCopyDeviceAspectResource:getAndCopyDeviceAspectResource}=require("./utils"),{validateConfigJson:validateConfigJson}=require("../../gen-webpack-conf/validate"),path=require("path"),fs=require("fs");let appName,watching=null;function showVersion(){const e=require("../../package.json").version,t=require("@babel/core/package.json").version,o=require("webpack/package.json").version;colorconsole.info(`aiot-toolkit: ${e}; babel: ${t}; webpack: ${o};`)}async function aspectProjectCompiler(e,t,o,a={}){let s=getManifest();appName=s.package||"demo";const{entries:i,deviceAspects:r,routerObj:c}=getAspectEntries(_config.default.aspectTemplate.projectPath,s);validateConfigJson(i);const n=_config.default.aspectTemplate.distPath,p=_config.default.aspectTemplate.outputPath;cleanOrCreateDir(p),cleanOrCreateDir(n),_config.default.aspectTemplate.outputPath=path.join(p,appName);const l=_config.default.aspectTemplate.outputPath,f=[];try{for(let s of i){_config.default.sourceRoot="./src",_config.default.aspectTemplate.isApp=!1,a.cwd=path.join(_config.default.aspectTemplate.projectPath,s),_config.default.aspectTemplate.packToVela=!1;let i=path.resolve(a.cwd,_config.default.sourceRoot,"manifest.json");if(!fs.existsSync(i))throw new Error(`the file ${i} cannot be found.`);const r=readJson(i),{deviceTypeList:c}=r;if(c&&Array.isArray(c)){const i=getProductionTypes(c);for(const r of Object.keys(i))if(i[r]){_config.default.aspectTemplate.packToVela="enableMirtos"===r;const i=_config.default.aspectTemplate.packToVela?s+".lite":s;f.push(i),await singleCompiler(e,t,o,a)}}else f.push(s),await singleCompiler(e,t,o,a)}c.all=s.router.aspects,r.all=f;const p=path.join(_config.default.aspectTemplate.projectPath,"app"),u=path.join(p,"manifest.json");let g=JSON.parse(JSON.stringify(s));const{deviceTypeList:m}=s,d=getProductionTypes(m),h=path.join(p,".manifest.json");fs.writeFileSync(h,JSON.stringify(s));for(let s of Object.keys(r)){const i=isMirtosDevice(s);let m="all"===s,h=m?appName:appName+"."+s.trim().replace(" ",".");if(g.router.aspects=c[s],fs.writeFileSync(u,JSON.stringify(g,null,2)),_config.default.sourceRoot="",_config.default.aspectTemplate.isApp=!0,a.cwd=p,m){for(const s of Object.keys(d))if(d[s]){_config.default.aspectTemplate.packToVela="enableMirtos"===s;const i=_config.default.aspectTemplate.packToVela?"app.lite":"app";f.push(i),await singleCompiler(e,t,o,a)}}else _config.default.aspectTemplate.packToVela=i,await singleCompiler(e,t,o,a);let w=[];if(m)for(const e of r[s]){const t="app"===e||"app.lite"===e?e+".base":e+".aspc";w.push({name:e,targetFile:t,otherName:t})}else r[s].unshift("app"),w=getAndCopyDeviceAspectResource(r[s],l,h,i);const y=path.join(n,h+".app");await(0,_ziputil.packFolderToApp)(y,w,l),m&&deleteCompressedFiles(l)}if(fs.unlinkSync(h),a.deploy){fs.copyFileSync(u,path.join(n,"manifest.json"));const e=path.join(n,path.basename(_config.default.aspectTemplate.projectPath)+".zip"),t=fs.readdirSync(n).map((e=>({name:e,targetFile:e,otherName:e})));await(0,_ziputil.packFolderToApp)(e,t,n)}return Promise.resolve()}catch(e){console.log(`Distributed project compiler error ${e}`)}}function singleCompiler(e,t,o,a={}){const s=a.onerror;return new Promise(((i,r)=>{function c(e,t){if(e&&(s&&s(e),colorconsole.error(e)),t){if(t.hasErrors()||t.hasWarnings()){const e=summaryErrors(t),o=summaryWarnings(t);s&&s(e),colorconsole.error(e),colorconsole.warn(o)}t.hasErrors()&&(process.exitCode=1)}}colorconsole.attach(a.log),setCustomConfig(a.cwd),process.env.NODE_PLATFORM=e,process.env.NODE_PHASE=t;const n="prod"===t?"production":"development";try{const e=genWebpackConf(a,n);if(o){const t=webpack(e);watching=t.watch({aggregateTimeout:300},((e,t)=>{c(e,t),i({compileError:e,stats:t,watching:watching})}))}else webpack(e,((e,t)=>{c(e,t),i({compileError:e,stats:t})}))}catch(e){console.log(`singleCompiler error ${e}`)}}))}showVersion(),module.exports.compile=async function(e,t,o,a={}){var s;let i;return"distributed"===(null===(s=getProjectJson())||void 0===s?void 0:s.projectType)?(_config.default.aspectTemplate.isAspect=!0,i=await aspectProjectCompiler(e,t,o,a)):i=await singleCompiler(e,t,o,a),i},module.exports.stopWatch=function(){return new Promise((e=>{watching?watching.close((()=>{watching=null,e({stopWatchError:null})})):e({stopWatchError:"no watching"})}))};
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