UNPKG

motion

Version:

motion - moving development forward

362 lines (271 loc) 14.3 kB
exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; exports.scripts = scripts; exports.afterBuild = afterBuild; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _libHelpers = require('./lib/helpers'); var _libStreams = require('./lib/streams'); var _libFns = require('../lib/fns'); var _libUnicodeToChar = require('../lib/unicodeToChar'); var _libUnicodeToChar2 = _interopRequireDefault(_libUnicodeToChar); var _index = require('./index'); var _libFindRequires = require('../lib/findRequires'); var _babel = require('./babel'); var _babel2 = _interopRequireDefault(_babel); var _bridge = require('../bridge'); var _bridge2 = _interopRequireDefault(_bridge); var _cache = require('../cache'); var _cache2 = _interopRequireDefault(_cache); var _builder = require('../builder'); var _builder2 = _interopRequireDefault(_builder); var _bundler = require('../bundler'); var _bundler2 = _interopRequireDefault(_bundler); var _scanner = require('./scanner'); var _scanner2 = _interopRequireDefault(_scanner); var _opts = require('../opts'); var _opts2 = _interopRequireDefault(_opts); var serializeCache = _libFns._.debounce(_cache2['default'].serialize, 600); var hasFinished = function hasFinished() { return hasBuilt() && _opts2['default']('hasRunInitialInstall'); }; var hasBuilt = function hasBuilt() { return _opts2['default']('hasRunInitialBuild'); }; var getAllImports = function getAllImports(src, imports) { return [].concat(_libFindRequires.findBabelRuntimeRequires(src), imports); }; var scanNow = function scanNow() { return _opts2['default']('build') || _opts2['default']('watch') || !_opts2['default']('hasRunInitialBuild'); }; function scripts(_ref) { var _ref$inFiles = _ref.inFiles; var inFiles = _ref$inFiles === undefined ? [] : _ref$inFiles; var userStream = _ref.userStream; var State = { curFile: null, lastError: null, lastSaved: {}, loaded: 0, total: inFiles.length, outsideSources: {} }; var scripts = userStream || _libHelpers.gulp.src(_libHelpers.SCRIPTS_GLOB).pipe(_libHelpers.$['if'](!_libHelpers.isBuilding(), _libHelpers.$.watch(_libHelpers.SCRIPTS_GLOB, { readDelay: 1 }))).pipe(_libHelpers.$['if'](function (file) { return file.event == 'unlink'; }, _libHelpers.$.ignore.exclude(true))); return (_libHelpers.isBuilding() ? scripts : _libHelpers.$.merge(scripts, _libStreams.dirAddStream(_opts2['default']('appDir')), new _libStreams.SuperStream().getStream())).pipe(_libHelpers.$['if'](buildCheck, _libHelpers.$.ignore.exclude(true))).pipe(_libHelpers.$.log(reset)).pipe(_libHelpers.$.plumber(catchError)).pipe(_libHelpers.$.log(setLastFile)).pipe(_scanner2['default']('pre')).pipe(_libHelpers.$.sourcemaps.init()).pipe(_babel2['default'].file()).pipe(_libHelpers.$.log(processDependencies)).pipe(_libHelpers.$.log(sendOutsideChanged)) // right after motion .pipe(_libHelpers.$['if'](!userStream, _libHelpers.$.rename({ extname: '.js' }))).pipe(_libHelpers.$['if'](function (file) { return file.babel.isExported; }, _libHelpers.$.multipipe(_libHelpers.$.log(removeNewlyInternal), _libHelpers.$.log(markFileSuccess), // before writing to preserve path _libHelpers.gulp.dest(_opts2['default']('deps').internalDir), _libHelpers.$.log(_bundler2['default'].internals.bind(null, { force: true })), _libHelpers.$.log(buildDone), _libHelpers.$.ignore.exclude(true)))).pipe(_libHelpers.$.sourcemaps.write('.')).pipe(_libHelpers.$.log(markFileSuccess)).pipe(_libHelpers.$['if'](checkWriteable, _libHelpers.gulp.dest(_opts2['default']('outDir')))).pipe(_libHelpers.$.log(afterWrite)) // temporary bugfix because gulp doesnt work well with watch (pending gulp 4) .pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()).pipe(_libHelpers.$.log()); function markDone(file) { State.loaded++; var done = State.loaded == State.total; _libFns.log.gulp('markDone', State.total, '/', State.loaded, done); // check if done, only run once if (done && !_opts2['default']('hasRunInitialBuild')) { _opts2['default'].set('finishingFirstBuild', true); file.finishingFirstBuild = true; } } // only do on first run function buildCheck(file) { // BUGFIX gulp sends deleted files through here, this filters them if (!file.contents) return true; // already done with first build if (hasBuilt()) return false; // hide behind cached flag for now if (!_opts2['default']('cached')) { markDone(file); return false; } var prevFile = _cache2['default'].getPrevious(file.path); if (!prevFile) return false; var outMTime = undefined, srcMTime = undefined; // read srcfile try { srcMTime = _libFns.fs.statSync(file.path).mtime; } catch (e) { return false; } // read outfile try { var relPath = _libFns.path.relative(_opts2['default']('appDir'), file.path); var outFile = prevFile.babel.isExported ? _libFns.path.join(_opts2['default']('deps').dir, 'internal', relPath) : _libFns.path.join(_opts2['default']('outDir'), relPath); outMTime = _libFns.fs.statSync(outFile).mtime; } catch (e) { _libFns.log.gulp('buildCheck', 'out file removed'); markDone(file); return false; } // final check var goodBuild = +outMTime > +srcMTime; var goodCache = prevFile.added > srcMTime; if (!goodBuild || !goodCache) return false; return finish(true); function finish() { var restored = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0]; markDone(file); if (restored) { _cache2['default'].restorePrevious(file.path); _libHelpers.out.goodScript(file); afterWrite(file); } return restored; } } function reset(file) { _libFns.emitter.emit('script:start', file); State.lastError = false; State.curFile = file; file.startTime = Date.now(); file.message = { startTime: file.startTime }; } function catchError(error) { _libFns.log.gulp('catchError', error); State.lastError = true; _libHelpers.out.badFile(State.curFile); error.timestamp = Date.now(); error.stack = _libUnicodeToChar2['default'](error.stack); _libFns.logError(error, State.curFile); _index.event.run('error', State.curFile, error); _cache2['default'].addError(error.fileName || '', error); if (error.fileName) error.file = _libFns.path.relative(_opts2['default']('appDir'), error.fileName); _bridge2['default'].broadcast('compile:error', { error: error }, 'error'); markDone(State.curFile); buildDone(State.curFile); } function setLastFile(file) { if (_libHelpers.isBuilding()) return; var name = file.path.replace(_opts2['default']('appDir'), ''); if (name.charAt(0) != '/') name = '/' + name; _libFns.log.gulp(name); // add to message file.message = _extends({}, file.message, { name: name, path: file.path, compiledAt: file.startTime }); State.curFile = file; } // sets isInternal and willInstall // for handling npm and bundling related things function processDependencies(file) { _cache2['default'].setFileInternal(file.path, file.babel.isExported); var scan = function scan() { _cache2['default'].setFileImports(file.path, file.babel.imports); _bundler2['default'].scanFile(file.path); }; // run scan if (file.babel.isExported || scanNow()) scan();else _libFns.debounce('install:' + file.path, 2000, scan); if (!_opts2['default']('build') || _opts2['default']('watch')) { _libFns.debounce('removeOldImports', 3000, _bundler2['default'].uninstall); // check will install file.willInstall = _bundler2['default'].willInstall(file.babel.imports); } } // detects if a file has changed not inside views for hot reloads correctness function sendOutsideChanged(file) { var src = file.contents.toString(); var meta = _cache2['default'].getFileMeta(file.path); if (!meta) return; var changed = true; var viewLocs = Object.keys(meta).map(function (view) { return meta[view].location; }); if (viewLocs.length) { (function () { // slice out all code not in views var outerSlice = function outerSlice(ls, start, end) { return ls.slice(0, start).concat(ls.slice(end)); }; var outside = viewLocs.reduce(function (src, loc) { return outerSlice(src, loc[0][0], loc[1][0] + 1); }, src.split("\n")).join(''); var prevOutside = State.outsideSources[file.path]; changed = prevOutside !== outside; State.outsideSources[file.path] = outside; // update })(); } if (_opts2['default']('hasRunInitialBuild')) _bridge2['default'].broadcast('file:outsideChange', { name: _cache2['default'].relative(file.path), changed: changed }); } function checkWriteable(file) { if (userStream || State.lastError) return false; if (_libHelpers.isBuilding()) return true; var isNew = !State.lastSaved[file.path] || file.startTime > State.lastSaved[file.path]; if (isNew) { State.lastSaved[file.path] = file.startTime; return true; } return false; } function afterWrite(file) { if (_libHelpers.isSourceMap(file.path)) return; buildDone(file); // avoid during initial build if (!hasFinished()) return; if (file.babel.isExported) return; // run stuff after each change on build --watch doBuild(); if (!_cache2['default'].get(file.path)) return; // avoid ?? todo: figure out why this is necessary if (State.lastError) return; // avoid if error // dont broadcast script if installing/bundling _libFns.log.gulp('bundler installing?', _bundler2['default'].isInstalling(), 'willInstall?', file.willInstall); if (_bundler2['default'].isInstalling() || file.willInstall) return; // ADD _bridge2['default'].broadcast('script:add', file.message); } function buildDone(file) { if (file.finishingFirstBuild) { _opts2['default'].set('hasRunInitialBuild', true); _libFns.log.gulp('buildDone!!'.green.bold); waitingForFirstBuild.forEach(function (res) { return res(); }); } } function doBuild() { if (_opts2['default']('watch') && hasBuilt()) { _builder2['default'].build(); return true; } } function markFileSuccess(file) { if (_libHelpers.isSourceMap(file.path)) return; _libFns.emitter.emit('script:end', file); _libHelpers.out.goodScript(file); _libFns.log.gulp('DOWN', 'success'.green, 'internal?', file.babel.isExported); if (file.babel.isExported) return; // update cache error / state _cache2['default'].update(file.path); // write cache state to disk if (_opts2['default']('hasRunInitialBuild')) serializeCache(); // message browser of compile success _bridge2['default'].broadcast('compile:success', file.message, 'error'); // check if other errors left still in queue var error = _cache2['default'].getLastError(); if (!error) return; _libFns.log.gulp('cache last error', error); _bridge2['default'].broadcast('compile:error', { error: error }, 'error'); } // ok so we start a file // its built into .motion/out // we then add an export // now we need to remove it from .motion/out function removeNewlyInternal(file) { // resolve path from .motion/.internal/deps/internals/xyz.js back to xyz.js var filePath = _libFns.path.relative(_libFns.p(_opts2['default']('deps').dir, 'internal'), file.path); // then resolve path to .motion/.internal/out/xyz.js var outPath = _libFns.p(_opts2['default']('outDir'), filePath); // log.gulp('remove newly internal', outPath) _libFns.rm(outPath); } } var waitingForFirstBuild = []; function afterBuild() { return new Promise(function (res, rej) { if (hasFinished()) return res();else waitingForFirstBuild.push(res); }); }