diff --git a/scripts/build/cache.js b/scripts/build/cache.js index 1bcb061a9..ae599f0a1 100644 --- a/scripts/build/cache.js +++ b/scripts/build/cache.js @@ -1,7 +1,7 @@ "use strict"; const util = require("util"); -const assert = require("assert"); +const assert = require("assert").strict; const crypto = require("crypto"); const fs = require("fs"); const path = require("path"); @@ -12,97 +12,99 @@ const writeFile = util.promisify(fs.writeFile); const ROOT = path.join(__dirname, "..", ".."); -function Cache(cacheDir, version) { - this.cacheDir = path.resolve(cacheDir || required("cacheDir")); - this.manifest = path.join(this.cacheDir, "manifest.json"); - this.version = version || required("version"); - this.checksums = {}; - this.files = {}; - this.updated = { - version: this.version, - checksums: {}, - files: {}, - }; -} - -// Loads the manifest.json file with the information from the last build -Cache.prototype.load = async function () { - // This should never throw, if it does, let it fail the build - const lockfile = await readFile("yarn.lock", "utf-8"); - const lockfileHash = hashString(lockfile); - this.updated.checksums["yarn.lock"] = lockfileHash; - - try { - const manifest = await readFile(this.manifest, "utf-8"); - const { version, checksums, files } = JSON.parse(manifest); - - // Ignore the cache if the version changed - assert.equal(this.version, version); - - assert.ok(typeof checksums === "object"); - // If yarn.lock changed, rebuild everything - assert.equal(lockfileHash, checksums["yarn.lock"]); - this.checksums = checksums; - - assert.ok(typeof files === "object"); - this.files = files; - - for (const files of Object.values(this.files)) { - assert.ok(Array.isArray(files)); - } - } catch (err) { +class Cache { + constructor(cacheDir, version) { + this.cacheDir = path.resolve(cacheDir || required("cacheDir")); + this.manifest = path.join(this.cacheDir, "manifest.json"); + this.version = version || required("version"); this.checksums = {}; this.files = {}; + this.updated = { + version: this.version, + checksums: {}, + files: {}, + }; } -}; -// Run rollup to get the list of files included in the bundle and check if -// any (or the list itself) have changed. -// This takes the same rollup config used for bundling to include files that are -// resolved by specific plugins. -Cache.prototype.checkBundle = async function (id, inputOptions, outputOptions) { - const files = new Set(this.files[id]); - const newFiles = (this.updated.files[id] = []); + // Loads the manifest.json file with the information from the last build + async load() { + // This should never throw, if it does, let it fail the build + const lockfile = await readFile("yarn.lock", "utf-8"); + const lockfileHash = hashString(lockfile); + this.updated.checksums["yarn.lock"] = lockfileHash; - let dirty = false; + try { + const manifest = await readFile(this.manifest, "utf-8"); + const { version, checksums, files } = JSON.parse(manifest); - const bundle = await rollup(getRollupConfig(inputOptions)); - const { output } = await bundle.generate(outputOptions); + // Ignore the cache if the version changed + assert.strictEqual(this.version, version); - const modules = output - .filter((mod) => !/\0/.test(mod.facadeModuleId)) - .map((mod) => [path.relative(ROOT, mod.facadeModuleId), mod.code]); + assert.ok(typeof checksums === "object"); + // If yarn.lock changed, rebuild everything + assert.strictEqual(lockfileHash, checksums["yarn.lock"]); + this.checksums = checksums; - for (const [id, code] of modules) { - newFiles.push(id); - // If we already checked this file for another bundle, reuse the hash - if (!this.updated.checksums[id]) { - this.updated.checksums[id] = hashString(code); - } - const hash = this.updated.checksums[id]; + assert.ok(typeof files === "object"); + this.files = files; - // Check if this file changed - if (!this.checksums[id] || this.checksums[id] !== hash) { - dirty = true; - } - - // Check if this file is new - if (!files.delete(id)) { - dirty = true; + for (const files of Object.values(this.files)) { + assert.ok(Array.isArray(files)); + } + } catch (err) { + this.checksums = {}; + this.files = {}; } } - // Final check: if any file was removed, `files` is not empty - return !dirty && files.size === 0; -}; + // Run rollup to get the list of files included in the bundle and check if + // any (or the list itself) have changed. + // This takes the same rollup config used for bundling to include files that are + // resolved by specific plugins. + async checkBundle(id, inputOptions, outputOptions) { + const files = new Set(this.files[id]); + const newFiles = (this.updated.files[id] = []); -Cache.prototype.save = async function () { - try { - await writeFile(this.manifest, JSON.stringify(this.updated, null, 2)); - } catch (err) { - // Don't fail the build + let dirty = false; + + const bundle = await rollup(getRollupConfig(inputOptions)); + const { output } = await bundle.generate(outputOptions); + + const modules = output + .filter((mod) => !/\0/.test(mod.facadeModuleId)) + .map((mod) => [path.relative(ROOT, mod.facadeModuleId), mod.code]); + + for (const [id, code] of modules) { + newFiles.push(id); + // If we already checked this file for another bundle, reuse the hash + if (!this.updated.checksums[id]) { + this.updated.checksums[id] = hashString(code); + } + const hash = this.updated.checksums[id]; + + // Check if this file changed + if (!this.checksums[id] || this.checksums[id] !== hash) { + dirty = true; + } + + // Check if this file is new + if (!files.delete(id)) { + dirty = true; + } + } + + // Final check: if any file was removed, `files` is not empty + return !dirty && files.size === 0; } -}; + + async save() { + try { + await writeFile(this.manifest, JSON.stringify(this.updated, null, 2)); + } catch (err) { + // Don't fail the build + } + } +} function required(name) { throw new Error(name + " is required");