From 51d2a379f5e8235ced3589533fa303595521b309 Mon Sep 17 00:00:00 2001 From: pieh Date: Fri, 12 Aug 2022 11:52:33 +0200 Subject: [PATCH 1/3] fix(gatsby): close parcel cache db before clearing cache and retrying --- packages/gatsby/package.json | 1 + .../compile-gatsby-files.ts.snap | 1 + .../src/utils/parcel/compile-gatsby-files.ts | 31 ++++++++++++++++--- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 278b70dde73a3..88ff5a8e11b9d 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -30,6 +30,7 @@ "@graphql-tools/load": "^7.5.10", "@jridgewell/trace-mapping": "^0.3.13", "@nodelib/fs.walk": "^1.2.8", + "@parcel/cache": "2.6.2", "@parcel/core": "2.6.2", "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3", "@types/http-proxy": "^1.17.7", diff --git a/packages/gatsby/src/utils/parcel/__tests__/__snapshots__/compile-gatsby-files.ts.snap b/packages/gatsby/src/utils/parcel/__tests__/__snapshots__/compile-gatsby-files.ts.snap index 15f6a05c0d88e..28b4507270d94 100644 --- a/packages/gatsby/src/utils/parcel/__tests__/__snapshots__/compile-gatsby-files.ts.snap +++ b/packages/gatsby/src/utils/parcel/__tests__/__snapshots__/compile-gatsby-files.ts.snap @@ -2,6 +2,7 @@ exports[`gatsby file compilation constructBundler should construct Parcel relative to passed directory 1`] = ` Object { + "cache": undefined, "cacheDir": "/packages/gatsby/src/utils/parcel/__tests__/fixtures/js/.cache/.parcel-cache", "defaultConfig": "/packages/gatsby-parcel-config/lib/index.json", "entries": Array [ diff --git a/packages/gatsby/src/utils/parcel/compile-gatsby-files.ts b/packages/gatsby/src/utils/parcel/compile-gatsby-files.ts index 2ea07a70ab882..aeafeb234f494 100644 --- a/packages/gatsby/src/utils/parcel/compile-gatsby-files.ts +++ b/packages/gatsby/src/utils/parcel/compile-gatsby-files.ts @@ -1,4 +1,5 @@ import { Parcel } from "@parcel/core" +import { LMDBCache, Cache } from "@parcel/cache" import path from "path" import type { Diagnostic } from "@parcel/diagnostic" import reporter from "gatsby-cli/lib/reporter" @@ -27,7 +28,7 @@ function exponentialBackoff(retry: number): Promise { * Construct Parcel with config. * @see {@link https://parceljs.org/features/targets/} */ -export function constructParcel(siteRoot: string): Parcel { +export function constructParcel(siteRoot: string, cache?: Cache): Parcel { return new Parcel({ entries: [ `${siteRoot}/${gatsbyFileRegex}`, @@ -35,6 +36,7 @@ export function constructParcel(siteRoot: string): Parcel { ], defaultConfig: require.resolve(`gatsby-parcel-config`), mode: `production`, + cache, targets: { root: { outputFormat: `commonjs`, @@ -100,8 +102,22 @@ export async function compileGatsbyFiles( await exponentialBackoff(retry) - const parcel = constructParcel(siteRoot) + // for whatever reason TS things LMDBCache is some browser Cache and not actually Parcel's Cache + // so we force type it to Parcel's Cache + const cache = new LMDBCache(getCacheDir(siteRoot)) as any as Cache + const parcel = constructParcel(siteRoot, cache) const { bundleGraph } = await parcel.run() + let cacheClosePromise = Promise.resolve() + try { + // @ts-ignore store is public field on LMDBCache class, but public interface for Cache + // doesn't have it. There doesn't seem to be proper public API for this, so we have to + // resort to reaching into internals. Just in case this is wrapped in try/catch if + // parcel changes internals in future (closing cache is only needed when retrying + // so the if the change happens we shouldn't fail on happy builds) + cacheClosePromise = cache.store.close() + } catch (e) { + reporter.verbose(`Failed to close parcel cache\n${e.toString()}`) + } await exponentialBackoff(retry) @@ -138,8 +154,15 @@ export async function compileGatsbyFiles( ) } - // sometimes parcel cache gets in weird state - await remove(getCacheDir(siteRoot)) + // sometimes parcel cache gets in weird state and we need to clear the cache + await cacheClosePromise + + try { + await remove(getCacheDir(siteRoot)) + } catch { + // in windows we might get "EBUSY" errors if LMDB failed to close, so this try/catch is + // to prevent EBUSY errors from potentially hiding real import errors + } await compileGatsbyFiles(siteRoot, retry + 1) return From f4421bd8025ff74f2aad881ef964362ad0a745f5 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Fri, 12 Aug 2022 12:54:29 +0200 Subject: [PATCH 2/3] Update packages/gatsby/src/utils/parcel/compile-gatsby-files.ts Co-authored-by: Dan Kirkham --- packages/gatsby/src/utils/parcel/compile-gatsby-files.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby/src/utils/parcel/compile-gatsby-files.ts b/packages/gatsby/src/utils/parcel/compile-gatsby-files.ts index aeafeb234f494..ec8bb93a27140 100644 --- a/packages/gatsby/src/utils/parcel/compile-gatsby-files.ts +++ b/packages/gatsby/src/utils/parcel/compile-gatsby-files.ts @@ -102,7 +102,7 @@ export async function compileGatsbyFiles( await exponentialBackoff(retry) - // for whatever reason TS things LMDBCache is some browser Cache and not actually Parcel's Cache + // for whatever reason TS thinks LMDBCache is some browser Cache and not actually Parcel's Cache // so we force type it to Parcel's Cache const cache = new LMDBCache(getCacheDir(siteRoot)) as any as Cache const parcel = constructParcel(siteRoot, cache) From d7bcfe8e3a0c63947a914ed62a3782471a3c6c98 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Sun, 14 Aug 2022 09:30:16 +0200 Subject: [PATCH 3/3] Update packages/gatsby/src/utils/parcel/compile-gatsby-files.ts Co-authored-by: Lennart --- packages/gatsby/src/utils/parcel/compile-gatsby-files.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby/src/utils/parcel/compile-gatsby-files.ts b/packages/gatsby/src/utils/parcel/compile-gatsby-files.ts index ec8bb93a27140..11cd5fc8e1d6f 100644 --- a/packages/gatsby/src/utils/parcel/compile-gatsby-files.ts +++ b/packages/gatsby/src/utils/parcel/compile-gatsby-files.ts @@ -104,7 +104,7 @@ export async function compileGatsbyFiles( // for whatever reason TS thinks LMDBCache is some browser Cache and not actually Parcel's Cache // so we force type it to Parcel's Cache - const cache = new LMDBCache(getCacheDir(siteRoot)) as any as Cache + const cache = new LMDBCache(getCacheDir(siteRoot)) as unknown as Cache const parcel = constructParcel(siteRoot, cache) const { bundleGraph } = await parcel.run() let cacheClosePromise = Promise.resolve()