diff --git a/static/compilePlugins.js b/static/compilePlugins.js index b60b14f14..64703d12e 100644 --- a/static/compilePlugins.js +++ b/static/compilePlugins.js @@ -8,6 +8,8 @@ const path = require('path'); const fs = require('fs'); const metro = require('metro'); +const util = require('util'); +const recursiveReaddir = require('recursive-readdir'); const HOME_DIR = require('os').homedir(); module.exports = (reloadCallback, pluginPaths, pluginCache) => { @@ -135,6 +137,15 @@ function changeExport(path) { ); fs.writeFileSync(path, file); } +function mostRecentlyChanged(dir) { + return util + .promisify(recursiveReaddir)(dir) + .then(files => + files + .map(f => fs.lstatSync(f).ctime) + .reduce((a, b) => (a > b ? a : b), new Date(0)), + ); +} function compilePlugin( {rootDir, name, entry, packageJSON}, force, @@ -145,41 +156,43 @@ function compilePlugin( const out = path.join(pluginCache, fileName); const result = Object.assign({}, packageJSON, {rootDir, name, entry, out}); // check if plugin needs to be compiled - if ( - !force && - fs.existsSync(out) && - fs.lstatSync(rootDir).atime < fs.lstatSync(out).ctime - ) { - // eslint-disable-next-line no-console - console.log(`🥫 Using cached version of ${name}...`); - resolve(result); - } else { - console.log(`⚙️ Compiling ${name}...`); // eslint-disable-line no-console - metro - .runBuild({ - config: { - getProjectRoots: () => [rootDir, path.join(__dirname, '..')], - getTransformModulePath: () => - path.join(__dirname, 'transforms', 'index.js'), - // a custom hash function is required, because by default metro starts - // numbering the modules by 1. This means all plugins would start at - // ID 1, which causes a clash. This is why we have a custom IDFactory. - createModuleIdFactory, - }, - dev: false, - entry, - out, - }) - .then(() => { - changeExport(out); - resolve(result); - }) - .catch(err => { - console.error( - `❌ Plugin ${name} is ignored, because it could not be compiled.`, - ); - console.error(err); - }); - } + mostRecentlyChanged(rootDir).then(rootDirCtime => { + if ( + !force && + fs.existsSync(out) && + rootDirCtime < fs.lstatSync(out).ctime + ) { + // eslint-disable-next-line no-console + console.log(`🥫 Using cached version of ${name}...`); + resolve(result); + } else { + console.log(`⚙️ Compiling ${name}...`); // eslint-disable-line no-console + metro + .runBuild({ + config: { + getProjectRoots: () => [rootDir, path.join(__dirname, '..')], + getTransformModulePath: () => + path.join(__dirname, 'transforms', 'index.js'), + // a custom hash function is required, because by default metro starts + // numbering the modules by 1. This means all plugins would start at + // ID 1, which causes a clash. This is why we have a custom IDFactory. + createModuleIdFactory, + }, + dev: false, + entry, + out, + }) + .then(() => { + changeExport(out); + resolve(result); + }) + .catch(err => { + console.error( + `❌ Plugin ${name} is ignored, because it could not be compiled.`, + ); + console.error(err); + }); + } + }); }); } diff --git a/static/package.json b/static/package.json index 77c68eaf0..377653545 100644 --- a/static/package.json +++ b/static/package.json @@ -12,6 +12,7 @@ "babel-plugin-transform-object-rest-spread": "^7.0.0-beta.3", "babel-preset-react": "^7.0.0-beta.3", "babylon": "^7.0.0-beta.40", - "metro": "^0.28.0" + "metro": "^0.28.0", + "recursive-readdir": "2.2.2" } } diff --git a/static/yarn.lock b/static/yarn.lock index e828e1596..631675ca6 100644 --- a/static/yarn.lock +++ b/static/yarn.lock @@ -2252,7 +2252,7 @@ min-document@^2.19.0: dependencies: dom-walk "^0.1.0" -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: +minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -2574,6 +2574,12 @@ readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.1.4, readable string_decoder "~1.0.3" util-deprecate "~1.0.1" +recursive-readdir@2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" + dependencies: + minimatch "3.0.4" + regenerate@^1.2.1: version "1.3.3" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f"