sb-babel-cli
Version:
A smarter babel-cli
266 lines (211 loc) • 9.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _os = require('os');
var _os2 = _interopRequireDefault(_os);
var _sbFs = require('sb-fs');
var _sbFs2 = _interopRequireDefault(_sbFs);
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _chalk = require('chalk');
var _chalk2 = _interopRequireDefault(_chalk);
var _crypto = require('crypto');
var _crypto2 = _interopRequireDefault(_crypto);
var _mkdirp = require('mkdirp');
var _mkdirp2 = _interopRequireDefault(_mkdirp);
var _chokidar = require('chokidar');
var _chokidar2 = _interopRequireDefault(_chokidar);
var _sbPromisify = require('sb-promisify');
var _sbPromisify2 = _interopRequireDefault(_sbPromisify);
var _debounce = require('lodash/debounce');
var _debounce2 = _interopRequireDefault(_debounce);
var _child_process = require('child_process');
var _child_process2 = _interopRequireDefault(_child_process);
var _sbConfigFile = require('sb-config-file');
var _sbConfigFile2 = _interopRequireDefault(_sbConfigFile);
var _resolveFrom = require('resolve-from');
var _resolveFrom2 = _interopRequireDefault(_resolveFrom);
var _package = require('../package.json');
var _package2 = _interopRequireDefault(_package);
var _CLIError = require('./CLIError');
var _CLIError2 = _interopRequireDefault(_CLIError);
var _handleError = require('./handleError');
var _handleError2 = _interopRequireDefault(_handleError);
var _iterate = require('./iterate');
var _iterate2 = _interopRequireDefault(_iterate);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
var mkdirpAsync = (0, _sbPromisify2.default)(_mkdirp2.default);
function getSha1(contents) {
var hash = _crypto2.default.createHash('sha1');
hash.update(contents);
return hash.digest('hex');
}
exports.default = function () {
var _ref = _asyncToGenerator(function* (config) {
var processFile = function () {
var _ref2 = _asyncToGenerator(function* (sourceFile, outputFile, stats, configFile) {
if (!sourceFile.endsWith('.js')) return;
var transformed = yield getTransformFile()(sourceFile);
yield _sbFs2.default.writeFile(outputFile, transformed.code, {
mode: stats.mode
});
log(sourceFile, '->', outputFile);
if (config.writeFlowSources) {
try {
var flowOutputFile = outputFile + '.flow';
yield _sbFs2.default.unlink(flowOutputFile);
yield _sbFs2.default.symlink(_path2.default.resolve(sourceFile), flowOutputFile);
log(sourceFile, '->', flowOutputFile);
} catch (error) {
/* No Op */
}
}
writingQueue = writingQueue.then(function () {
return configFile.set(getSha1(sourceFile), stats.mtime.getTime());
});
yield writingQueue;
});
return function processFile(_x2, _x3, _x4, _x5) {
return _ref2.apply(this, arguments);
};
}();
var getCacheFile = function () {
var _ref3 = _asyncToGenerator(function* () {
var configDirectory = _path2.default.join(_os2.default.homedir(), '.sb-babel-cli');
yield mkdirpAsync(configDirectory);
var configFilePath = _path2.default.join(configDirectory, 'cache-timestamps-' + getSha1(config.sourceDirectory));
return (0, _sbConfigFile2.default)(configFilePath);
});
return function getCacheFile() {
return _ref3.apply(this, arguments);
};
}();
var execute = function () {
var _ref4 = _asyncToGenerator(function* () {
if (!config.execute) return;
if (!spawnedProcess) {
log(_chalk2.default.yellow(_package2.default.version));
log(_chalk2.default.yellow('to restart at any time, enter `rs`'));
}
log(_chalk2.default.green('starting \'node ' + config.execute + '\''));
if (spawnedProcess) {
spawnedProcess.kill();
}
spawnedProcess = _child_process2.default.spawn(process.execPath, [config.execute], {
stdio: 'inherit'
});
});
return function execute() {
return _ref4.apply(this, arguments);
};
}();
var writingQueue = Promise.resolve();
var executionQueue = Promise.resolve();
var spawnedProcess = void 0;
var transformFileCached = void 0;
function log() {
for (var _len = arguments.length, items = Array(_len), _key = 0; _key < _len; _key++) {
items[_key] = arguments[_key];
}
if (config.execute) {
var _console;
(_console = console).log.apply(_console, ['' + _chalk2.default.yellow('[sb-babel-cli]')].concat(items));
} else {
var _console2;
(_console2 = console).log.apply(_console2, items);
}
}
function getTransformFile() {
if (!transformFileCached) {
var resolved = void 0;
try {
resolved = (0, _resolveFrom2.default)(config.sourceDirectory, 'babel-core');
} catch (_) {
/* No Op */
}
if (!resolved) {
throw new _CLIError2.default('Unable to find babel-core in your project');
}
// $FlowIgnore: SORRY FLOW!
var babelCore = require(resolved); // eslint-disable-line global-require,import/no-dynamic-require
transformFileCached = (0, _sbPromisify2.default)(babelCore.transformFile);
}
return transformFileCached;
}
var debounceExecute = (0, _debounce2.default)(function () {
executionQueue = executionQueue.then(execute).catch(_handleError2.default);
}, config.executeDelay);
var configFile = yield getCacheFile();
yield (0, _iterate2.default)({
rootDirectory: config.sourceDirectory,
sourceDirectory: config.sourceDirectory,
outputDirectory: config.outputDirectory,
ignored: config.ignored,
keepExtraFiles: config.keepExtraFiles,
filesToKeep: function filesToKeep(input) {
return input.concat(config.writeFlowSources ? input.map(function (i) {
return i + '.flow';
}) : []);
},
callback: function callback(sourceFile, outputFile, stats) {
return _asyncToGenerator(function* () {
if (!config.disableCache && (yield configFile.get(getSha1(sourceFile))) === stats.mtime.getTime()) {
if (!config.execute) {
log(sourceFile, 'is unchanged');
}
return;
}
yield processFile(sourceFile, outputFile, stats, configFile);
})();
}
});
yield writingQueue;
if (!config.watch) return;
if (config.execute && process.stdin) {
if (typeof process.stdin.unref === 'function') {
process.stdin.unref();
}
process.stdin.on('data', function (chunk) {
if (chunk.toString().trim() === 'rs') {
debounceExecute();
}
});
}
var resolvedSourceDirectory = _path2.default.resolve(config.sourceDirectory);
var watcher = _chokidar2.default.watch(resolvedSourceDirectory, {
ignored: config.ignored,
alwaysStat: true,
ignoreInitial: true
});
watcher.on('add', function (givenFileName, stats) {
var fileName = _path2.default.relative(resolvedSourceDirectory, givenFileName);
var sourceFile = _path2.default.join(config.sourceDirectory, fileName);
var outputFile = _path2.default.join(config.outputDirectory, fileName);
mkdirpAsync(_path2.default.dirname(outputFile)).then(function () {
return processFile(sourceFile, outputFile, stats, configFile);
}).catch(_handleError2.default).then(debounceExecute);
});
watcher.on('change', function (givenFileName, stats) {
var fileName = _path2.default.relative(resolvedSourceDirectory, givenFileName);
var sourceFile = _path2.default.join(config.sourceDirectory, fileName);
var outputFile = _path2.default.join(config.outputDirectory, fileName);
mkdirpAsync(_path2.default.dirname(outputFile)).then(function () {
return processFile(sourceFile, outputFile, stats, configFile);
}).catch(_handleError2.default).then(debounceExecute);
});
watcher.on('unlink', function (givenFileName) {
var fileName = _path2.default.relative(resolvedSourceDirectory, givenFileName);
var outputFile = _path2.default.join(config.outputDirectory, fileName);
_sbFs2.default.unlink(outputFile).catch(function () {
/* No Op */
}).then(debounceExecute);
});
debounceExecute();
});
function doTheMagic(_x) {
return _ref.apply(this, arguments);
}
return doTheMagic;
}();