Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(gatsby): fix PNP resolving from the .cache folder #31732

Merged
merged 2 commits into from
Jun 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/gatsby/src/utils/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const fs = require(`fs-extra`)
const path = require(`path`)
const dotenv = require(`dotenv`)
const { CoreJSResolver } = require(`./webpack/corejs-resolver`)
const { CacheFolderResolver } = require(`./webpack/cache-folder-resolver`)
const { store } = require(`../redux`)
const { actions } = require(`../redux/actions`)
const { getPublicPath } = require(`./get-public-path`)
Expand Down Expand Up @@ -442,7 +443,10 @@ module.exports = async (
),
$virtual: getAbsolutePathForVirtualModule(`$virtual`),
},
plugins: [new CoreJSResolver()],
plugins: [
new CoreJSResolver(),
new CacheFolderResolver(path.join(program.directory, `.cache`)),
],
}

const target =
Expand Down
65 changes: 65 additions & 0 deletions packages/gatsby/src/utils/webpack/cache-folder-resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import Resolver from "enhanced-resolve/lib/Resolver"

interface IRequest {
request?: string
path: string
}

type ProcessWithPNP = NodeJS.ProcessVersions & { pnp?: string }

/**
* To support PNP we have to make sure dependencies resolved from the .cache folder should be resolved from the gatsby package directory
*/
export class CacheFolderResolver {
private requestsFolder: string

constructor(requestsFolder: string) {
this.requestsFolder = requestsFolder
}

apply(resolver: Resolver): void {
if (!(process.versions as ProcessWithPNP).pnp) {
return
}
Comment on lines +21 to +23
Copy link
Contributor

@merceyz merceyz Jun 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry if I'm missing some context here but shouldn't it always do this regardless if PnP is enabled or not? Otherwise it's relying on hoisting quite a lot - https://yarnpkg.com/advanced/rulebook#packages-should-only-ever-require-what-they-formally-list-in-their-dependencies

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should but it could be a subtle breaking change for some so I made sure to only fix it for pnp in v3


const target = resolver.ensureHook(`raw-module`)
resolver
.getHook(`raw-module`)
.tapAsync(
`CacheFolderResolver`,
(
request: IRequest,
resolveContext: unknown,
callback: (err?: Error | null, result?: unknown) => void
) => {
const req = request.request
if (!req) {
return callback()
}

if (!request.path.startsWith(this.requestsFolder)) {
pieh marked this conversation as resolved.
Show resolved Hide resolved
return callback()
}

const packageMatch = /^(@[^/]+\/)?[^/]+/.exec(req)
pieh marked this conversation as resolved.
Show resolved Hide resolved
if (!packageMatch) {
return callback()
}

// We change the issuer but keep everything as is and re-run resolve
const obj = {
...request,
path: __dirname,
}

return resolver.doResolve(
target,
obj,
`change issuer to gatsby package by cache-folder-resolver to fix pnp`,
resolveContext,
callback
)
}
)
}
}