www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

js.js (3806B)


      1 const globby = require('globby');
      2 const path = require('path');
      3 const os = require('os');
      4 const fs = require('fs-extra');
      5 const cluster = require('cluster');
      6 const { getSignatures, compareSignatures, getFileSignature, writeSignatures, cleanUp, onSuccess, onError, onProgress } = require('./utils');
      7 const { jsFiles, ignoreMask } = require('./config');
      8 
      9 const NODE_ENV = process.env.NODE_ENV;
     10 const ROOT = path.resolve(__dirname, '..');
     11 
     12 async function getJS(source, options, signatures) {
     13 	const t1 = Date.now();
     14 	const matchingJSFiles = await globby(source, Object.assign({ cwd: ROOT }, options));
     15 	const cpuCount = os.cpus().length;
     16 	const totalCount = matchingJSFiles.length;
     17 	var count = 0;
     18 	var isError = false;
     19 
     20 	cluster.setupMaster({
     21 		exec: path.join(__dirname, 'babel-worker.js')
     22 	});
     23 
     24 	// check signatures, collect signatures for files to be processes 
     25 	const newFilesSignatures = {};
     26 	const filesForProcessing = [];
     27 	var f;
     28 	while ((f = matchingJSFiles.pop()) != null) {
     29 		const newFileSignature = await getFileSignature(f);
     30 		const dest = path.join('build', f);
     31 		f = path.normalize(f);
     32 		if (f in signatures) {
     33 			if (compareSignatures(newFileSignature, signatures[f])) {
     34 				try {
     35 					await fs.access(dest, fs.constants.F_OK);
     36 					continue;
     37 				} catch (_) {
     38 					// file does not exists in build, fallback to browserifing
     39 				}
     40 			}
     41 		}
     42 		filesForProcessing.push(f);
     43 		newFilesSignatures[f] = newFileSignature;
     44 	}
     45 
     46 	// shortcut if no files need rebuilding
     47 	if (Object.keys(filesForProcessing).length === 0) {
     48 		const t2 = Date.now();
     49 		return Promise.resolve({
     50 				action: 'js',
     51 				count,
     52 				totalCount,
     53 				processingTime: t2 - t1
     54 		});
     55 	}
     56 
     57 	// distribute processing among workers
     58 	const workerCount = Math.min(cpuCount, filesForProcessing.length);
     59 	var workersActive = workerCount;
     60 	NODE_ENV == 'debug' && console.log(`Will process ${filesForProcessing.length} files using ${workerCount} processes`);
     61 	return new Promise((resolve, reject) => {
     62 		for (let i = 0; i < workerCount; i++) {
     63 			var worker = cluster.fork();
     64 
     65 			worker.on('message', function(ev) {
     66 				if (ev.error) {
     67 					isError = true;
     68 					let errorMsg = `Failed while processing ${ev.sourcefile}: ${ev.error}`;
     69 					reject(errorMsg);
     70 				} else {
     71 					signatures[ev.sourcefile] = newFilesSignatures[ev.sourcefile];
     72 					
     73 					if (ev.isSkipped) {
     74 						NODE_ENV == 'debug' && console.log(`process ${this.id} SKIPPED ${ev.sourcefile}`);
     75 					} else {
     76 						NODE_ENV == 'debug' && console.log(`process ${this.id} took ${ev.processingTime} ms to process ${ev.sourcefile} into ${ev.outfile}`);
     77 						NODE_ENV != 'debug' && onProgress(ev.sourcefile, ev.outfile, 'js');
     78 						count++;
     79 					}
     80 				}
     81 
     82 				let nextFile = filesForProcessing.pop();
     83 
     84 				if (!isError && nextFile) {
     85 					NODE_ENV == 'debug' && console.log(`process ${this.id} scheduled to process ${nextFile}`);
     86 					this.send({
     87 						file: nextFile
     88 					});
     89 				} else {
     90 					if (this.isConnected()) {
     91 						this.kill();
     92 					}
     93 					NODE_ENV == 'debug' && console.log(`process ${this.id} has terminated`);
     94 					if (!--workersActive) {
     95 						const t2 = Date.now();
     96 						resolve({
     97 							action: 'js',
     98 							count,
     99 							totalCount,
    100 							processingTime: t2 - t1
    101 						});
    102 					}
    103 				}
    104 			});
    105 
    106 			let nextFile = filesForProcessing.pop();
    107 			NODE_ENV == 'debug' && console.log(`process ${worker.id} scheduled to process ${nextFile}`);
    108 			worker.send({
    109 				file: nextFile
    110 			});
    111 		}
    112 	});
    113 }
    114 
    115 module.exports = getJS;
    116 
    117 if (require.main === module) {
    118 	(async () => {
    119 		try {
    120 			const signatures = await getSignatures();
    121 			onSuccess(await getJS(jsFiles, { ignore: ignoreMask }, signatures));
    122 			onSuccess(await cleanUp(signatures));
    123 			await writeSignatures(signatures);
    124 		} catch (err) {
    125 			process.exitCode = 1;
    126 			global.isError = true;
    127 			onError(err);
    128 		}
    129 	})();
    130 }