diff --git a/scripts/block-on-sdk-build.js b/scripts/block-on-sdk-build.js index cc29275a..022543c6 100644 --- a/scripts/block-on-sdk-build.js +++ b/scripts/block-on-sdk-build.js @@ -3,6 +3,37 @@ const chokidar = require('chokidar'); const AsyncLock = require('async-lock'); +// This script sits and waits for a build of an underlying SDK (js or react) +// to complete before exiting. This is done by cooperating with build-watch-sdk.js +// by waiting for it's signal to start watching for file changes, then watching +// the SDK's build output for a storm of file changes to stop. Both the js-sdk +// and react-sdk compile each file one by one, so by waiting for file changes to +// stop we know it is safe to continue and therefore exit this script. We give +// some leeway to the SDK's build process to handle larger/more complex files +// through use of a reset-on-touch countdown timer. When a file change occurs, +// we reset the countdown to WAIT_TIME and let it count down. If the count down +// completes, we consider ourselves having left the file system update storm and +// therefore can consider a build of the SDK to be fully completed. + +// Why do we block in the first place? Because if riot-web starts it's initial +// build (via webpack-dev-server) and the react-sdk or js-sdk are halfway through +// their initial builds, then riot-web's initial build fails out of the box. This +// can sometimes be corrected by waiting for the SDK build to complete and triggering +// a file change, thereby causing a cascading build, however it isn't great if the +// initial build of riot-web fails out of the box. We block at the js-sdk first so +// that the react-sdk build doesn't fall victim to the same problem, which also +// slows down the riot-web build. After the js-sdk completes, we start the react-sdk +// build which riot-web is waiting for. When complete, riot-web starts building as +// per normal. + +// Why the canary to begin watching? Because we can't reliably determine that the +// build triggered by `npm install` in each SDK is actually the process we need to +// be watching for. To work around this, build-watch-sdk.js does the `npm install` +// and follows through with a canary to signal to this script that it should start +// watching for changes produced by that SDK's `npm start` (run immediately after +// the canary is sent). + + const WAIT_TIME = 5000; // ms function waitForCanary(canaryName) { diff --git a/scripts/build-watch-sdk.js b/scripts/build-watch-sdk.js index 775ea4a5..e240e3a8 100644 --- a/scripts/build-watch-sdk.js +++ b/scripts/build-watch-sdk.js @@ -20,6 +20,7 @@ console.log(sdkPath); // We only want to build the SDK if it looks like it was `npm link`ed if (fs.existsSync(path.join(sdkPath, '.git'))) { + // Install the develop dependencies just in case they were forgotten by the developer. console.log("Installing develop dependencies"); const devEnv = Object.assign({}, process.env, {NODE_ENV: "development"}); child_process.execSync("npm install --only=dev", { @@ -36,9 +37,13 @@ if (fs.existsSync(path.join(sdkPath, '.git'))) { }); } + // Send a signal so that the various blocks can unblock. See the top of + // block-on-sdk-build.js for more information on how this is used. console.log("Sending signal that other processes may unblock"); triggerCanarySignal(sdkName); + // Actually start the watcher process for the sdk. This is what block-on-sdk-build.js + // is going to monitor. console.log("Performing task: " + task); child_process.execSync(`npm ${task === "build" ? "run build" : "start"}`, { env: process.env,