Stable babel transformation cache key

Summary:
This diff makes babel transformation cache key stable. With the previous approach it was changed on each CI build so it was not possible to persist cache between builds. Now it is computed from the transformation package content after each build. Because of that it is equal for every CI build while Babel transformations unchanged and so we could use same cache on different Sandcastle agents.

In addition to that, it makes it possible to specify directory for Metro cache so we can save/restore it in CI builds.

Reviewed By: mweststrate

Differential Revision: D26877989

fbshipit-source-id: 7cb04a177f86e61986585e5a74d9c7396ddddc18
This commit is contained in:
Anton Nikolaev
2021-03-10 08:06:19 -08:00
committed by Facebook GitHub Bot
parent baeb8ba5be
commit c065760d15
10 changed files with 142 additions and 34 deletions

View File

@@ -14,16 +14,41 @@ import fs from 'fs-extra';
export default async function computePackageChecksum(
dir: string,
checksumFilePath?: string,
): Promise<string> {
const fullChecksumFilePath = checksumFilePath
? path.resolve(dir, checksumFilePath)
: undefined;
if (fullChecksumFilePath) {
// This block is an optimisation to not recompute checksum if nothing changed.
// tsbuildinfo file is changed every time when typescript compiler re-compiles anything,
// so we could compare its modification date with checksum modification date to
// decide whether we need to re-compute checksum or we can just use already computed one.
const tsBuildInfoPath = path.join(dir, 'tsconfig.tsbuildinfo');
try {
const [tsBuildInfoStat, checksumStat] = await Promise.all([
fs.stat(tsBuildInfoPath),
fs.stat(fullChecksumFilePath),
]);
if (checksumStat.mtime > tsBuildInfoStat.mtime) {
return (await fs.readFile(fullChecksumFilePath)).toString();
}
} catch {}
}
const hash = crypto.createHash('sha1');
hash.setEncoding('hex');
const files = (await packlist({path: dir})).sort();
for (const file of files) {
// add hash of relative file path
hash.write(process.platform === 'win32' ? file.replace(/\\/g, '/') : file);
const filePath = path.resolve(dir, file);
if (filePath === fullChecksumFilePath) {
// If there is already existing checksum file, we need to ignore it as it is not a part of package content.
continue;
}
// add hash of relative normalized file path
hash.write(process.platform === 'win32' ? file.replace(/\\/g, '/') : file);
if (file === 'package.json') {
// add hash of package.json with version set to "0.0.0" to avoid changing hash when only version changed
const packageJson = await fs.readJson(filePath);
@@ -46,5 +71,9 @@ export default async function computePackageChecksum(
}
}
hash.end();
return hash.read();
const checksum = hash.read();
if (fullChecksumFilePath) {
await fs.writeFile(fullChecksumFilePath, checksum);
}
return checksum;
}

View File

@@ -12,6 +12,8 @@ import getWatchFolders from './getWatchFolders';
import path from 'path';
import fs from 'fs-extra';
import {getInstalledPluginDetails} from 'flipper-plugin-lib';
import {FileStore} from 'metro-cache';
import os from 'os';
let metroDir: string | undefined;
const metroDirPromise = getMetroDir().then((dir) => (metroDir = dir));
@@ -77,11 +79,18 @@ export default async function bundlePlugin(pluginDir: string, dev: boolean) {
sourceExts: ['js', 'jsx', 'ts', 'tsx', 'json', 'mjs', 'cjs'],
blacklistRE: /\.native\.js$/,
},
cacheStores: [
new FileStore({
root:
process.env.FLIPPER_METRO_CACHE ??
path.join(os.tmpdir(), 'metro-cache'),
}),
],
});
await Metro.runBuild(config, {
dev,
minify: !dev,
resetCache: !dev,
resetCache: false,
sourceMap: dev,
sourceMapUrl,
entry,