1
1
import Resolver from "enhanced-resolve/lib/Resolver"
2
+ import mod from "module"
2
3
3
4
interface IRequest {
4
5
request ?: string
@@ -8,17 +9,98 @@ interface IRequest {
8
9
type ProcessWithPNP = NodeJS . ProcessVersions & { pnp ?: string }
9
10
10
11
/**
11
- * To support PNP we have to make sure dependencies resolved from the .cache folder should be resolved from the gatsby package directory
12
+ * To support Yarn PNP and pnpm we have to make sure dependencies resolved from
13
+ * the .cache folder should be resolved from the gatsby package directory
14
+ * If you see error like
15
+ *
16
+ * ModuleNotFoundError: Module not found: Error: Can't resolve 'prop-types'
17
+ * in '<site-directory>/.cache'
18
+ *
19
+ * it probably means this plugin is not enabled when it should be and there
20
+ * might be need to adjust conditions for setting `this.isEnabled` in the
21
+ * constructor.
22
+ *
23
+ * It's not enabled always because of legacy behavior and to limit potential
24
+ * regressions. Might be good idea to enable it always in the future
25
+ * OR remove the need for the plugin completely by not copying `cache-dir`
26
+ * contents to `.cache` folder and instead adjust setup to use those browser/node
27
+ * html renderer runtime files directly from gatsby package
12
28
*/
13
29
export class CacheFolderResolver {
14
30
private requestsFolder : string
31
+ private isEnabled = false
15
32
16
33
constructor ( requestsFolder : string ) {
17
34
this . requestsFolder = requestsFolder
35
+
36
+ if ( ( process . versions as ProcessWithPNP ) . pnp ) {
37
+ // Yarn PnP
38
+ this . isEnabled = true
39
+ } else if ( / n o d e _ m o d u l e s [ / \\ ] \. p n p m / . test ( process . env . NODE_PATH ?? `` ) ) {
40
+ // pnpm when executing through `pnpm` CLI
41
+ this . isEnabled = true
42
+ } else {
43
+ // pnpm when executing through regular `gatsby` CLI / `./node_modules/.bin/gatsby`
44
+ // would not set NODE_PATH, but node_modules structure would not allow to resolve
45
+ // gatsby deps from the cache folder (unless user would install same deps too)
46
+ // so we are checking if we can resolve deps from the cache folder
47
+ // this check is not limited to pnpm and other package managers could hit this path too
48
+
49
+ // Hardcoded list of gatsby deps used in gatsby browser and ssr runtimes
50
+ // instead of checking if we use Yarn PnP (via `process.versions.pnp`),
51
+ // we check if we can resolve the external deps from the cache-dir folder
52
+ // to know if we need to enable this plugin so we also cover pnpm
53
+ // It might be good idea to always enable it overall, but to limit potential
54
+ // regressions we only enable it if we are sure we need it.
55
+ const modulesToCheck = [
56
+ `prop-types` ,
57
+ `lodash/isEqual` ,
58
+ `mitt` ,
59
+ `shallow-compare` ,
60
+ `@gatsbyjs/reach-router` ,
61
+ `gatsby-react-router-scroll` ,
62
+ `react-server-dom-webpack` ,
63
+ `gatsby-link` ,
64
+ ]
65
+
66
+ // test if we can resolve deps from the cache folder
67
+ let isEverythingResolvableFromCacheDir = true
68
+ const cacheDirReq = mod . createRequire ( requestsFolder )
69
+ for ( const cacheDirDep of modulesToCheck ) {
70
+ try {
71
+ cacheDirReq . resolve ( cacheDirDep )
72
+ } catch {
73
+ // something is not resolvable from the cache folder, so we should not enable this plugin
74
+ isEverythingResolvableFromCacheDir = false
75
+ break
76
+ }
77
+ }
78
+
79
+ // test if we can resolve deps from the gatsby package
80
+ let isEverythingResolvableFromGatsbyPackage = true
81
+ for ( const cacheDirDep of modulesToCheck ) {
82
+ try {
83
+ require . resolve ( cacheDirDep )
84
+ } catch {
85
+ // something is not resolvable from the gatsby package
86
+ isEverythingResolvableFromGatsbyPackage = false
87
+ break
88
+ }
89
+ }
90
+
91
+ // we only enable this plugin if we are unable to resolve cache-dir deps from .cache folder
92
+ // and we can resolve them from gatsby package
93
+ if (
94
+ ! isEverythingResolvableFromCacheDir &&
95
+ isEverythingResolvableFromGatsbyPackage
96
+ ) {
97
+ this . isEnabled = true
98
+ }
99
+ }
18
100
}
19
101
20
102
apply ( resolver : Resolver ) : void {
21
- if ( ! ( process . versions as ProcessWithPNP ) . pnp ) {
103
+ if ( ! this . isEnabled ) {
22
104
return
23
105
}
24
106
0 commit comments