UNPKG

37.2 kBJavaScriptView Raw
1let colors = require("colors");
2let util = require("./util");
3let File = require("./lib/file");
4let Path = require("path");
5let maker = require("./maker/maker");
6let hash = require("./lib/md5");
7let queue = require("./lib/queue");
8let isbinaryfile = require("isbinaryfile");
9let config = require("./config");
10let gzipSize = require('gzip-size');
11let ignore = require('ignore');
12let ora = require('ora');
13
14const THRIDPARTFOLDER = "node_modules";
15const IGNOREMODULES = ["fs", "path", "util", "http", "url", "zlib", "https", "events", "crypto", "adajs"];
16const MANIFESTKEYS = ["theme_color", "start_url", "short_name", "scope", "related_applications", "prefer_related_applications", "orientation", "name", "lang", "icons", "display", "dir", "description", "background_color"];
17
18class AdaBundler {
19 constructor() {
20 this.resultmap = [];
21 this.resultmapcode = {};
22 this.contentCache = {};
23 }
24
25 getFileCode(path) {
26 if (!this.contentCache[path]) {
27 return new Promise((resolve, reject) => {
28 let file = new File(path), suffix = file.suffix();
29 if (suffix === "html") {
30 resolve(`module.exports=${JSON.stringify(file.readSync().replace(/\n/g, '').replace(/\r/g, '').replace(/\n\r/g, ''))}`);
31 } else if (suffix === "less") {
32 maker.lessCode(file.readSync()).then(code => {
33 resolve(`module.exports={active:function(){var _a = document.createElement("style");_a.setAttribute("media", "screen");_a.setAttribute("type", "text/css");_a.appendChild(document.createTextNode(${JSON.stringify(code)}));document.head.appendChild(_a);}};`);
34 });
35 } else if (suffix === "icon") {
36 maker.minifyIcon(file.readSync()).then(({name, code}) => {
37 let result = `var active=function(){var c=document.getElementById("ada-icon-container");if(!c){var c=document.createElement("div");c.setAttribute("id","ada-icon-container");c.style.cssText="width:0;height:0;";document.body.appendChild(c);}if(!document.getElementById("${name}")){var a=document.createElement("div");a.innerHTML=${JSON.stringify(code)};c.appendChild(a.childNodes[0]);}};module.exports={active:function(){if(/complete|loaded|interactive/.test(window.document.readyState)){active();}else{window.addEventListener("DOMContentLoaded",function(){active();});}},getIconId:function(){return "${name}";}};`;
38 resolve(result);
39 });
40 } else {
41 let __code = file.readSync();
42 if (__code.trim().length === 0) {
43 resolve("module.exports={};");
44 } else {
45 if (path.indexOf("node_modules") === -1) {
46 resolve(__code);
47 } else {
48 maker.babelCode(config, __code).then(content => {
49 resolve(content);
50 });
51 }
52 }
53 }
54 }).then((content) => {
55 this.contentCache[path] = content;
56 return content;
57 });
58 } else {
59 return Promise.resolve(this.contentCache[path]);
60 }
61 }
62
63 getDependenceInfo(path, code) {
64 if (!this.resultmapcode[path]) {
65 let paths = [];
66 code = code.replace(/require\(.*?\)/g, (one) => {
67 if (one.indexOf("${") === -1 && one.indexOf("+") === -1 && one.indexOf(".concat(") === -1) {
68 let a = one.substring(8, one.length - 1).replace(/['|"|`]/g, "").trim();
69 let _path = base.getFilePath(config, Path.resolve(path, "./../"), a);
70 let index = this.resultmap.indexOf(_path);
71 if (index === -1) {
72 paths.push(_path);
73 this.resultmap.push(_path);
74 index = this.resultmap.length - 1;
75 }
76 return `require(${index})`;
77 } else {
78 return one;
79 }
80 });
81 this.resultmapcode[path] = code;
82 return paths;
83 } else {
84 return [];
85 }
86 }
87
88 getCodeMap(path) {
89 return this.getFileCode(path).then(code => {
90 let tasks = this.getDependenceInfo(path, code).map(path => () => {
91 return this.getCodeMap(path);
92 });
93 return queue(tasks);
94 });
95 }
96
97 bundle(path, output, develop) {
98 path = path.replace(/\\/g, "/");
99 console.log("");
100 if (!config.ada_autobundle) {
101 console.log(` [ada_autobundle:false] ALWAYS BUNDLE ADA CORE`.grey);
102 }
103 let spinner = ora({
104 color: "yellow",
105 text: `NOW BUNDLING ADA CORE [${develop ? "DEVELOP" : "PUBLIC"} MODE]`
106 }).start();
107 return new File(`${config.projectPath}/node_modules/adajs/index.d.ts`).copyTo(`${config.projectPath}/node_modules/@types/adajs/index.d.ts`).then(() => {
108 return this.getCodeMap(path).then(() => {
109 let veison = require(Path.resolve(path, "./../package.json")).version;
110 this.resultmap.push(path);
111 let result = this.resultmap.map(path => {
112 return `function(module,exports,require){${this.resultmapcode[path]}}`;
113 });
114 let commet = `/*! adajs[${develop ? "Develop" : "Publish"}] ${veison} https://github.com/topolr/ada | https://github.com/topolr/ada/blob/master/LICENSE */\n`;
115 let code = `${commet}(function (map,moduleName) {var Installed={};var requireModule = function (index) {if (Installed[index]) {return Installed[index].exports;}var module = Installed[index] = {exports: {}};map[index].call(module.exports, module, module.exports, requireModule);return module.exports;};var mod=requireModule(map.length-1);window&&window.Ada.installModule(moduleName,mod);})([${result.join(",")}],"adajs");`;
116 config.adaHash = hash.md5(code).substring(0, 10);
117 code = code.replace(/\/ada\/sse/, `${config.server.protocol}://${config.server.host}${(config.server.port != 80 ? ":" + config.server.port : '')}/ada/sse`);
118 return new File(output).write(code).then(() => {
119 spinner.stop();
120 process.stderr.clearLine();
121 process.stderr.cursorTo(0);
122 console.log(` BUNDLE ADA CORE DONE [${develop ? "DEVELOP" : "PUBLIC"} MODE GZIP:${util.getFileSizeAuto(gzipSize.sync(code))}]`.yellow);
123 });
124 });
125 });
126 }
127}
128
129let base = {
130 logs: {},
131 packageLogs: {},
132 cache: {},
133 doneMap: [],
134 getUnIgnorePath(paths) {
135 return paths.filter(path => {
136 return !config.ignore.ignores("./" + path.substring(config.source_path.length));
137 });
138 },
139 isBundleAda(develop) {
140 let result = true;
141 if (config.ada_autobundle) {
142 let veison = require(Path.resolve(config.nmodule_path, "./adajs/package.json")).version;
143 if (develop) {
144 let adaFile = new File(Path.resolve(config.dist_path, "./ada.js"));
145 if (adaFile.isExists()) {
146 let content = adaFile.readSync();
147 let r = content.match(/\*! adajs.*?\*/g);
148 if (r) {
149 let current_version = r[0].split(" ")[2];
150 if (current_version && current_version.trim() === veison) {
151 result = false;
152 }
153 }
154 }
155 } else {
156 let k = new File(Path.resolve(config.dist_path)).subscan().filter(path => {
157 let a = /ada\-[0-9a-z]+\.js/.test(path.replace(/\\/g, "/").split("/").pop());
158 if (a) {
159 let content = new File(path).readSync();
160 let r = content.match(/\*! adajs.*?\*/g);
161 if (r) {
162 let current_version = r[0].split("")[2];
163 return current_version && current_version.trim() === veison;
164 }
165 }
166 });
167 if (k.length > 0) {
168 result = false;
169 }
170 }
171 }
172 return result;
173 },
174 getAllFiles() {
175 return new File(config.source_path + "/").scan();
176 },
177 getAllSource() {
178 let files = [];
179 new File(config.source_path + "/").scan().forEach(path => {
180 let suffix = new File(path).suffix();
181 if (suffix === "js" || suffix === "ts") {
182 files.push(path);
183 }
184 });
185 return files;
186 },
187 getFilePath(config, filePath, path) {
188 let __path = "", _path = "";
189 if (path.substring(0, path.length - 3) === ".js") {
190 path = path.substring(0, path.length - 3);
191 }
192 if (path.startsWith("./") || path.startsWith("../") || path.startsWith("/")) {
193 __path = _path = Path.resolve(filePath, path).replace(/\\/g, "/");
194 let _file = new File(_path);
195 if (!_file.isExists() || _file.isFolder()) {
196 _path = __path + ".ts";
197 }
198 _file = new File(_path);
199 if (!_file.isExists() || _file.isFolder()) {
200 _path = __path + ".js";
201 }
202 } else {
203 __path = _path = Path.resolve(config.nmodule_path, path);
204 _path = __path + ".ts";
205 let file = new File(_path);
206 if (!file.isExists()) {
207 _path = __path + ".js";
208 }
209 file = new File(_path);
210 if (!file.isExists()) {
211 _path = __path;
212 }
213 file = new File(_path);
214 if (file.isExists()) {
215 if (!file.isFile()) {
216 let _packagePath = Path.resolve(_path, "./package.json");
217 let _packageFile = new File(_packagePath);
218 if (_packageFile.isExists()) {
219 _path = Path.resolve(_packagePath, "./../", JSON.parse(_packageFile.readSync()).main);
220 } else {
221 let __path = Path.resolve(_path, "./index.ts");
222 if (!new File(__path).isExists()) {
223 __path = Path.resolve(_path, "./index.js");
224 }
225 _path = __path;
226 }
227 }
228 } else {
229 _path = __path + ".ts";
230 file = new File(_path);
231 if (!file.isExists()) {
232 _path = __path + ".js";
233 }
234 }
235 }
236 return _path.replace(/\\/g, "/");
237 },
238 getFileContent(config, filePath, path) {
239 let _path = this.getFilePath(config, filePath, path);
240 let _file = new File(_path);
241 let hash = _file.hash();
242 if (this.cache[_path] && this.cache[_path].hash === hash) {
243 return Promise.resolve(Object.assign({}, this.cache[_path]));
244 } else {
245 return maker.parse(_file.suffix(), _path, _file.readSync(), config).then(content => {
246 this.logs[_path] = "done";
247 this.cache[_path] = {hash, content, path: _path, result: "done"};
248 return {path: _path, content, result: "done"};
249 }).catch(e => {
250 this.logs[_path] = {
251 name: e.name,
252 message: e.message,
253 stack: e.stack
254 };
255 if (_file.suffix() === "js" || _file.suffix() === "ts") {
256 return {path: _path, content: `console.error(${JSON.stringify(e.message)})`, result: e}
257 } else {
258 return {path: _path, content: `${JSON.stringify(e.message)}`, result: e}
259 }
260 });
261 }
262 },
263 getRequireInfo(config, filePath, path) {
264 let _path = this.getFilePath(config, filePath, path);
265 if(!config.ignore.ignores("./" + _path.substring(config.source_path.length))) {
266 return this.getFileContent(config, filePath, path).then(info => {
267 let currentPath = info.path;
268 let at = {}, tasks = [], parseTasks = [], infoTasks = [], importsTasks = [];
269 let entry = {};
270 let result = {};
271 let name = "";
272 this.doneMap.push(currentPath);
273 info.content = info.content.replace(/_adajs.view\)\(\{[\d\D]*?\)/g, str => {
274 let map = str.substring(13, str.length - 1);
275 let mapj = new Function(`return ${map};`)();
276 ["template", "style"].forEach(key => {
277 let value = mapj[key];
278 if (value) {
279 let path = Path.join(info.path, "./../", value).replace(/\\/g, "/");
280 if (path.indexOf("node_modules") === -1) {
281 value = path.substring(config.source_path.length);
282 parseTasks.push({
283 path: Path.resolve(config.dist_path, path.substring(config.source_path.length)),
284 current: path,
285 value
286 });
287 } else {
288 value = `${THRIDPARTFOLDER}/${path.substring(config.nmodule_path.length)}`;
289 parseTasks.push({
290 path: Path.resolve(config.dist_path, `./${THRIDPARTFOLDER}/${path.substring(config.nmodule_path.length)}`),
291 current: path,
292 value
293 });
294 }
295 mapj[key] = value;
296 }
297 });
298 let __path = info.path.replace(/\\/g, "/");
299 if (__path.indexOf("node_modules") === -1) {
300 mapj.module = __path.substring(config.source_path.length);
301 } else {
302 mapj.module = `${THRIDPARTFOLDER}/${__path.substring(config.nmodule_path.length)}`;
303 }
304 let result = Reflect.ownKeys(mapj).map(key => {
305 return `${key}:"${mapj[key]}"`;
306 });
307 return `_adajs.view)({${result.join(",")}})`;
308 });
309 info.content = info.content.replace(/require\(.*?\)/g, (str) => {
310 let a = str.substring(8, str.length - 1).replace(/['|"|`]/g, "").trim();
311 if (IGNOREMODULES.indexOf(a) === -1) {
312 let m = this.getFilePath(config, Path.resolve(info.path, "./../"), a);
313 if (this.doneMap.indexOf(m) === -1 && m !== currentPath) {
314 infoTasks.push({
315 filePath: Path.resolve(info.path, "./../"),
316 path: a
317 });
318 }
319 if (m.indexOf("node_modules") === -1) {
320 return `require("${m.substring(config.source_path.length)}")`;
321 } else {
322 let name = `${THRIDPARTFOLDER}/${m.substring(config.nmodule_path.length)}`;
323 return `require("${name}")`;
324 }
325 } else {
326 return str;
327 }
328 });
329 info.content = info.content.replace(/import\(.*?\)/g, (str) => {
330 let a = str.substring(7, str.length - 1);
331 if (a.startsWith("\"") || a.startsWith("'") || a.startsWith("`")) {
332 a = a.replace(/['|"|`]/g, "").trim();
333 if (IGNOREMODULES.indexOf(a) === -1) {
334 let m = this.getFilePath(config, Path.resolve(info.path, "./../"), a);
335 let name = "", value = "";
336 if (m.indexOf("node_modules") === -1) {
337 name = m.substring(config.source_path.length);
338 value = `imports("${name}")`;
339 } else {
340 let name = `${THRIDPARTFOLDER}/${m.substring(config.nmodule_path.length)}`;
341 value = `imports("${name}")`;
342 }
343 if (this.doneMap.indexOf(m) === -1 && m !== currentPath) {
344 importsTasks.push({
345 filePath: Path.resolve(info.path, "./../"),
346 path: a,
347 name
348 });
349 }
350 return value;
351 } else {
352 return `imports(${a})`;
353 }
354 } else {
355 return `imports(${a})`;
356 }
357 });
358 if (info.path.indexOf("node_modules") !== -1) {
359 name = `${THRIDPARTFOLDER}/${info.path.substring(config.nmodule_path.length)}`;
360 let __path = Path.resolve(config.dist_path, `./${name}`);
361 if (this.doneMap.indexOf(__path) === -1) {
362 tasks.push({
363 path: __path,
364 content: info.content
365 });
366 }
367 } else {
368 name = info.path.substring(config.source_path.length);
369 let __path = Path.resolve(config.dist_path, info.path.substring(config.source_path.length))
370 if (this.doneMap.indexOf(__path) === -1) {
371 tasks.push({
372 path: __path,
373 content: info.content
374 });
375 }
376 }
377 at[name] = info.content;
378 return Promise.all(parseTasks.map(({path, current, content, value}) => {
379 this.doneMap.push(path);
380 return this.getFileContent(config, current, "./").then(({content}) => {
381 at[value] = content;
382 return new File(path).write(content);
383 });
384 }).concat(tasks.map(({path, content}) => {
385 this.doneMap.push(path);
386 return new File(path).write(content);
387 })).concat(infoTasks.map(({filePath, path}) => {
388 return this.getRequireInfo(config, filePath, path).then(b => {
389 if(b) {
390 let name = b.__name__;
391 Object.keys(b[name]).forEach(key => {
392 at[key] = b[name][key];
393 });
394 Object.keys(b).forEach(key => {
395 if (key !== name) {
396 result[key] = b[key];
397 }
398 });
399 }
400 });
401 })).concat(importsTasks.map(({filePath, path, name}) => {
402 return this.getRequireInfo(config, filePath, path).then(b => {
403 if(b) {
404 let name = b.__name__;
405 result[name] = b[name];
406 Object.keys(b).forEach(key => {
407 if (key !== name) {
408 result[key] = b[key];
409 }
410 });
411 }
412 });
413 }))).then(() => {
414 util.setProp(result, "__name__", name);
415 result[name] = at;
416 return result;
417 });
418 }).catch(e => console.log(e));
419 }else{
420 return Promise.resolve(null);
421 }
422 },
423 bundleAda(develop = false) {
424 if (this.isBundleAda(develop)) {
425 return new AdaBundler().bundle(Path.resolve(config.nmodule_path, `./adajs/${develop ? "develop" : (config.super_ada ? "super" : "index")}.js`),
426 Path.resolve(config.dist_path, "./ada.js"), develop).then(a => {
427 return a;
428 });
429 } else {
430 return Promise.resolve();
431 }
432 },
433 getEntriesInfo(paths) {
434 paths = this.getUnIgnorePath(paths);
435 let info = {};
436 let main = Path.resolve(config.base_path, config.main);
437 return queue(paths.map(path => {
438 return "./" + path.substring(config.source_path.length);
439 }).map(entry => () => {
440 return this.getRequireInfo(config, config.source_path, entry).then(_info => {
441 if(_info) {
442 Object.keys(_info).forEach(key => {
443 info[key] = _info[key];
444 });
445 }
446 });
447 })
448 ).then(() => {
449 let mainEntry = null, otherEnteries = [];
450 let _mainEntry = main.substring(config.source_path.length);
451 Object.keys(info).forEach(key => {
452 let result = {};
453 Reflect.ownKeys(info[key]).forEach(path => {
454 result[util.getMappedPath(path)] = {
455 hash: hash.md5(info[key][path]).substring(0, 8),
456 code: info[key][path]
457 }
458 });
459 let _result = {
460 code: result,
461 key: util.getMappedPath("package-" + key.replace(/\//g, "-").replace(/\\/g, "-")),
462 name: key
463 };
464 if (key === _mainEntry) {
465 mainEntry = _result;
466 } else {
467 otherEnteries.push(_result);
468 }
469 });
470 return {mainEntry, otherEnteries};
471 });
472 },
473 getAppSourceInfo() {
474 let main = Path.resolve(config.base_path, config.main);
475 let info = {};
476 let entries = [];
477 if (config.entry_path) {
478 entries = new File(Path.resolve(config.base_path, config.entry_path) + "/").subscan().filter(path => {
479 let suffix = new File(path).suffix();
480 return suffix === "js" || suffix === "ts";
481 }).map(path => path.replace(/\\/g, "/").replace(/[\/]+/g, "/"));
482 }
483 return this.getEntriesInfo([main, ...entries]);
484 },
485 outputPWAFile(config) {
486 let manifest = {};
487 config = util.extend(true, {}, config);
488 Reflect.ownKeys(config).filter(key => MANIFESTKEYS.indexOf(key) !== -1).forEach(key => {
489 manifest[key] = config[key];
490 });
491
492 let worker = config.worker;
493 let registCode = worker.beforeregist.toString().trim();
494 let start = registCode.indexOf("{") + 1;
495 let a = registCode.substring(start, registCode.length - 1);
496 let c = a.substring(a.indexOf("."));
497 let workerRegistCode = `if ('serviceWorker' in navigator) {navigator.serviceWorker.register('/serviceworker.js', { scope: '${worker.scope}' })${c}}`;
498
499 let codes = Reflect.ownKeys(worker).filter(key => ["scope", "beforeregist"].indexOf(key) === -1).map(key => {
500 let code = worker[key].toString();
501 return `self.addEventListener('${key.substring(2)}', function${code.substring(code.indexOf("("))});`;
502 });
503
504 let page = config.page;
505 page.meta.theme_color = config.theme_color;
506 page.meta.description = config.description;
507 page.meta.keywords = config.keywords;
508 let metaContent = Reflect.ownKeys(page.meta).map(key => {
509 return `<meta name="${key.replace(/_/g, "-")}" content="${page.meta[key]}">`;
510 }).join("");
511 let iconsContent = config.icons.map(info => {
512 return `<link rel="apple-touch-icon-precomposed" sizes="${info.sizes}" href="${config.site_url + info.src}">`;
513 }).join("");
514 if (config.icons.length > 0) {
515 iconsContent += `<link rel="shortcut icon" href="${config.site_url + config.icons[0].src}">`;
516 }
517 let styleContent = page.style.map(path => {
518 return `<link rel="stylesheet" href="${path}">`;
519 }).join("");
520 let scriptContent = page.script.map(path => {
521 return `<script src="${path}"></script>`;
522 }).join("");
523 let content = `<!DOCTYPE html><html><head><link rel="manifest" href="manifest.json"><meta charset="${page.charset}"><title>${config.name}</title>${metaContent}${iconsContent}${styleContent}${scriptContent}<script src="${config._adaPath}"></script><script>${config.regist_service ? workerRegistCode : ""}</script><script>Ada.boot(${JSON.stringify(config.ada)});</script></head><body></body></html>`;
524 return Promise.all(config.icons.map(icon => {
525 return new File(Path.resolve(config.source_path, icon.src)).copyTo(Path.resolve(config.dist_path, icon.src));
526 })).then(() => {
527 if (manifest.icons) {
528 manifest.icons.forEach(icon => {
529 icon.src = config.site_url + icon.src;
530 });
531 }
532 Promise.all([
533 new File(Path.resolve(config.index_path, "./manifest.json")).write(JSON.stringify(manifest)),
534 maker.minifyCode(config, codes.join("")).then(content => {
535 return new File(Path.resolve(config.index_path, "./serviceworker.js")).write(`'use strict';${content}`);
536 }),
537 new File(Path.resolve(config.index_path, "./index.html")).write(content)
538 ]);
539 });
540 },
541 hashFiles(map) {
542 util.getAllSourcePaths(config.dist_path).forEach(path => {
543 let suffix = new File(path).suffix();
544 let a = path.substring(config.dist_path.length).replace(/\\/g, "/");
545 let b = "";
546 if (!isbinaryfile.sync(path)) {
547 b = map[util.getMappedPath(a)];
548 if (!b) {
549 b = map[a.split(".").shift()];
550 }
551 }
552 if (b) {
553 new File(path).renameSync(Path.resolve(config.dist_path, util.getHashPath(a, b)));
554 }
555 });
556 new File(Path.resolve(config.dist_path, "./ada.js")).renameSync(Path.resolve(config.dist_path, `./ada-${config.adaHash}.js`));
557 },
558 logResult() {
559 let success = [], error = {};
560 let maxLine = 10, _localLength = 0, _moduleLength = 0;
561 Reflect.ownKeys(this.logs).forEach(key => {
562 if (key.indexOf("node_modules") === -1) {
563 _localLength += 1;
564 } else {
565 _moduleLength += 1;
566 }
567 if (this.logs[key] === "done") {
568 success.push(key);
569 } else {
570 error[key] = this.logs[key].message;
571 }
572 });
573 console.log("");
574 console.log(` ${util.formatDate()} LOCAL[`, `${_localLength}`.yellow, `] NODE-MODULES[`, `${_moduleLength}`.yellow, `]`);
575 let hasSuccess = false, hasError = false;
576 if (success.length > 0) {
577 hasSuccess = true;
578 console.log(` COMPILED`.green, util.padEnd(" ", 37 + `${_localLength}`.length + `${_moduleLength}`.length, "-").grey);
579 success.splice(0, maxLine).forEach((path, index) => {
580 if (path.indexOf("node_modules") === -1) {
581 console.log(` [${index + 1}]`.grey, `${path.substring(config.source_path.length)}`.cyan, `[local]`.grey);
582 } else {
583 console.log(` [${index + 1}]`.grey, `${path.substring(config.nmodule_path.length)}`.cyan, `[node_module]`.grey);
584 }
585 });
586 if (success.length > maxLine) {
587 console.log(` +[${success.length + maxLine}]...`.grey);
588 }
589 }
590 let et = Reflect.ownKeys(error);
591 if (et.length > 0) {
592 hasError = true;
593 console.log(` ERRORS`.red, util.padEnd(" ", 39 + `${_localLength}`.length + `${_moduleLength}`.length, "-").red);
594 et.forEach((path, index) => {
595 if (path.indexOf("node_modules") === -1) {
596 console.log(` [${index + 1}] ${path.substring(config.source_path.length)}`.grey);
597 } else {
598 console.log(` [${index + 1}] ${path.substring(config.nmodule_path.length)}`.grey);
599 }
600 console.log(` ${error[path]}`.red);
601 });
602 }
603 if (!hasSuccess && !hasError) {
604 console.log(` - [NOTHING TO DISPLAY] -`.grey);
605 }
606 let _length = 0, __length = 0;
607 Reflect.ownKeys(this.packageLogs).forEach(key => {
608 if (key.length > _length) {
609 _length = key.length;
610 }
611 let info = this.packageLogs[key];
612 let _a = key.length + info.hash.length + info.size.length + info.key.length + info.gsize.length;
613 if (_a > __length) {
614 __length = _a;
615 }
616 });
617 __length = __length + 16;
618 console.log(` PACKAGES`.green, util.padEnd(" ", __length - 10, "-").grey);
619 Reflect.ownKeys(this.packageLogs).forEach((key, index) => {
620 let info = this.packageLogs[key];
621 if (index === 0) {
622 console.log(` [${info.key}]`.grey, `${util.padEnd(key, _length, " ")}`.green, `[${info.size} GZIP:${info.gsize}]`.yellow, `[${info.hash}]`.grey);
623 } else {
624 console.log(` [${info.key}]`.grey, `${util.padEnd(key, _length, " ")}`.cyan, `[${info.size} GZIP:${info.gsize}]`.yellow, `[${info.hash}]`.grey);
625 }
626 });
627 },
628 bundle() {
629 let spinner = ora({
630 color: "yellow",
631 text: "Built Project"
632 }).start();
633 this.logs = {};
634 this.doneMap.length = [];
635 return this.getAppSourceInfo().then(({mainEntry, otherEnteries}) => {
636 otherEnteries.forEach(file => {
637 let r = {};
638 Reflect.ownKeys(file.code).forEach(key => {
639 if (!mainEntry.code[key]) {
640 r[key] = file.code[key];
641 }
642 });
643 file.code = r;
644 });
645 otherEnteries.unshift(mainEntry);
646 let map = {}, packages = {};
647 otherEnteries = otherEnteries.filter(file => {
648 let inp = [];
649 Reflect.ownKeys(file.code).forEach(key => {
650 map[key] = file.code[key].hash;
651 inp.push(file.code[key].hash);
652 });
653 if (inp.length > 1) {
654 packages[file.key] = inp.join("|");
655 return true;
656 }
657 });
658
659 let ps = Promise.resolve();
660 if (config.entry_auto) {
661 ps = ps.then(() => {
662 let allFiles = this.getAllSource(), _prentries = [];
663 allFiles.forEach(path => {
664 let a = util.getMappedPath(path.substring(config.source_path.length).replace(/\\/g, "/"));
665 if (!map[a]) {
666 _prentries.push(path);
667 }
668 });
669 return this.getEntriesInfo(_prentries).then(({otherEnteries: _otherEnteries}) => {
670 _otherEnteries.forEach(file => {
671 let r = {};
672 Reflect.ownKeys(file.code).forEach(key => {
673 if (!mainEntry.code[key]) {
674 r[key] = file.code[key];
675 }
676 });
677 file.code = r;
678 });
679 let _realOtherEnteries = [];
680 _otherEnteries.forEach(file => {
681 let inp = [];
682 Reflect.ownKeys(file.code).forEach(key => {
683 map[key] = file.code[key].hash;
684 inp.push(file.code[key].hash);
685 });
686 if (inp.length > 1) {
687 packages[file.key] = inp.join("|");
688 _realOtherEnteries.push(file);
689 }
690 });
691 otherEnteries.push(..._realOtherEnteries);
692 });
693 });
694 }
695 ps = ps.then(() => {
696 map.packages = packages;
697 let tasks = otherEnteries.map(file => () => {
698 let p = file.key;
699 let c = `Ada.unpack(${JSON.stringify(file.code)})`;
700 file.hash = hash.md5(map.packages[p].split("|").sort().join("|")).substring(0, 8);
701 map[p] = file.hash;
702 return new File(Path.resolve(config.dist_path, p) + ".js").write(c).then(() => {
703 this.packageLogs[file.name] = {
704 size: new File(Path.resolve(config.dist_path, p) + ".js").getFileSizeAuto(),
705 key: p,
706 hash: file.hash,
707 gsize: util.getFileSizeAuto(gzipSize.sync(c))
708 };
709 });
710 });
711 tasks.push(() => {
712 if (config.develop) {
713 config._adaPath = config.site_url + "ada.js";
714 } else {
715 config._adaPath = `${config.site_url}ada-${config.adaHash}.js`;
716 }
717 config.ada = {
718 basePath: config.site_url,
719 root: Path.resolve(config.base_path, config.main).replace(/\\/g, "/").substring(config.source_path.length),
720 map: map,
721 develop: config.develop
722 };
723 if (!config.develop) {
724 this.hashFiles(map);
725 }
726 return Promise.resolve();
727 });
728 tasks.push(() => {
729 return this.outputPWAFile(config);
730 });
731 tasks.push(() => {
732 return queue(this.getAllFiles().map(path => path.substring(config.source_path.length).replace(/\\/g, "/")).filter(path => {
733 return map[util.getMappedPath(path)] === undefined;
734 }).map(path => () => {
735 return new File(Path.resolve(config.source_path, path)).copyTo(Path.resolve(config.dist_path, path));
736 }));
737 });
738 return queue(tasks).then(() => {
739 spinner.stop();
740 this.logResult();
741 return map;
742 });
743 });
744 return ps;
745 }).then(map => {
746 if (config.complete) {
747 config.complete();
748 config.complete = null;
749 }
750 return {map, log: this.logs};
751 }).catch(e => console.log(e));
752 }
753};
754
755let action = {
756 addFiles(files) {
757 return base.bundle();
758 },
759 editFiles(files) {
760 return base.bundle();
761 },
762 removeFiles(files) {
763 return base.bundle();
764 },
765 publish() {
766 return base.bundle();
767 }
768};
769
770module.exports = function (option) {
771 util.extend(true, config, option);
772 config.base_path = config.base_path.replace(/\\/g, "/");
773 config.dist_path = Path.join(config.base_path, config.dist_path).replace(/\\/g, "/");
774 config.source_path = Path.join(config.base_path, config.source_path).replace(/\\/g, "/");
775 config.nmodule_path = Path.resolve(config.projectPath, "./node_modules/").replace(/\\/g, "/") + "/";
776 config.index_path = Path.resolve(config.base_path, config.index_path, "./../").replace(/\\/g, "/");
777 config.ignore = ignore().add(config.ignore);
778 if (config.site_url[config.site_url.length - 1] !== "/") {
779 config.site_url = config.site_url + "/";
780 }
781 return maker.installAllDependence(config.source_path, config).then(() => {
782 return base.bundleAda(config.develop).then(() => {
783 return action;
784 });
785 });
786};
\No newline at end of file