|
1 | 1 | import { Parcel } from "@parcel/core"
|
| 2 | +import { LMDBCache, Cache } from "@parcel/cache" |
2 | 3 | import path from "path"
|
3 | 4 | import type { Diagnostic } from "@parcel/diagnostic"
|
4 | 5 | import reporter from "gatsby-cli/lib/reporter"
|
@@ -27,14 +28,15 @@ function exponentialBackoff(retry: number): Promise<void> {
|
27 | 28 | * Construct Parcel with config.
|
28 | 29 | * @see {@link https://parceljs.org/features/targets/}
|
29 | 30 | */
|
30 |
| -export function constructParcel(siteRoot: string): Parcel { |
| 31 | +export function constructParcel(siteRoot: string, cache?: Cache): Parcel { |
31 | 32 | return new Parcel({
|
32 | 33 | entries: [
|
33 | 34 | `${siteRoot}/${gatsbyFileRegex}`,
|
34 | 35 | `${siteRoot}/plugins/**/${gatsbyFileRegex}`,
|
35 | 36 | ],
|
36 | 37 | defaultConfig: require.resolve(`gatsby-parcel-config`),
|
37 | 38 | mode: `production`,
|
| 39 | + cache, |
38 | 40 | targets: {
|
39 | 41 | root: {
|
40 | 42 | outputFormat: `commonjs`,
|
@@ -100,8 +102,22 @@ export async function compileGatsbyFiles(
|
100 | 102 |
|
101 | 103 | await exponentialBackoff(retry)
|
102 | 104 |
|
103 |
| - const parcel = constructParcel(siteRoot) |
| 105 | + // for whatever reason TS thinks LMDBCache is some browser Cache and not actually Parcel's Cache |
| 106 | + // so we force type it to Parcel's Cache |
| 107 | + const cache = new LMDBCache(getCacheDir(siteRoot)) as unknown as Cache |
| 108 | + const parcel = constructParcel(siteRoot, cache) |
104 | 109 | const { bundleGraph } = await parcel.run()
|
| 110 | + let cacheClosePromise = Promise.resolve() |
| 111 | + try { |
| 112 | + // @ts-ignore store is public field on LMDBCache class, but public interface for Cache |
| 113 | + // doesn't have it. There doesn't seem to be proper public API for this, so we have to |
| 114 | + // resort to reaching into internals. Just in case this is wrapped in try/catch if |
| 115 | + // parcel changes internals in future (closing cache is only needed when retrying |
| 116 | + // so the if the change happens we shouldn't fail on happy builds) |
| 117 | + cacheClosePromise = cache.store.close() |
| 118 | + } catch (e) { |
| 119 | + reporter.verbose(`Failed to close parcel cache\n${e.toString()}`) |
| 120 | + } |
105 | 121 |
|
106 | 122 | await exponentialBackoff(retry)
|
107 | 123 |
|
@@ -138,8 +154,15 @@ export async function compileGatsbyFiles(
|
138 | 154 | )
|
139 | 155 | }
|
140 | 156 |
|
141 |
| - // sometimes parcel cache gets in weird state |
142 |
| - await remove(getCacheDir(siteRoot)) |
| 157 | + // sometimes parcel cache gets in weird state and we need to clear the cache |
| 158 | + await cacheClosePromise |
| 159 | + |
| 160 | + try { |
| 161 | + await remove(getCacheDir(siteRoot)) |
| 162 | + } catch { |
| 163 | + // in windows we might get "EBUSY" errors if LMDB failed to close, so this try/catch is |
| 164 | + // to prevent EBUSY errors from potentially hiding real import errors |
| 165 | + } |
143 | 166 |
|
144 | 167 | await compileGatsbyFiles(siteRoot, retry + 1)
|
145 | 168 | return
|
|
0 commit comments