Skip to content

Commit d6293e3

Browse files
piehimjoshin
andauthored
feat(gatsby): support node: protocol when bundling engines (#36506)
Co-authored-by: Josh Johnson <[email protected]>
1 parent 3f5e57c commit d6293e3

File tree

9 files changed

+93
-2
lines changed

9 files changed

+93
-2
lines changed

e2e-tests/production-runtime/cypress/integration/ssr.js

+12
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,15 @@ describe(`500 status`, () => {
173173
.should(`exist`)
174174
})
175175
})
176+
177+
describe(`"node:" protocol`, () => {
178+
it(`engines work when bundled code contains node:path import`, () => {
179+
cy.visit(`/ssr/using-node-protocol/`).waitForRouteChange()
180+
181+
// validating that this page was rendered with SSR mode
182+
cy.getTestElement(`is-ssr`).contains(`true`)
183+
184+
// content of field is generated using `node:path` import
185+
cy.getTestElement(`field-result`).contains(`"foo/bar"`)
186+
})
187+
})

e2e-tests/production-runtime/gatsby-config.js

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ module.exports = {
2626
},
2727
`gatsby-plugin-local-worker`,
2828
`gatsby-ssr-tsx`,
29+
`gatsby-plugin-node-protocol-test`,
2930
`gatsby-plugin-image`,
3031
`gatsby-plugin-sharp`,
3132
`gatsby-plugin-sass`,

e2e-tests/production-runtime/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
],
2828
"license": "MIT",
2929
"scripts": {
30-
"build": "cross-env GATSBY_PREFIXED_FROM_COMMAND_LINE=YES FROM_COMMAND_LINE=YES CYPRESS_SUPPORT=y gatsby build",
30+
"build": "cross-env GATSBY_PREFIXED_FROM_COMMAND_LINE=YES FROM_COMMAND_LINE=YES CYPRESS_SUPPORT=y NODE_OPTIONS='--require ./polyfill-node-protocol-imports.js' gatsby build",
3131
"build:offline": "cross-env GATSBY_PREFIXED_FROM_COMMAND_LINE=YES FROM_COMMAND_LINE=YES TEST_PLUGIN_OFFLINE=y CYPRESS_SUPPORT=y gatsby build",
3232
"develop": "cross-env CYPRESS_SUPPORT=y gatsby develop",
3333
"format": "prettier --write '**/*.js' --ignore-path .gitignore",
@@ -66,4 +66,4 @@
6666
"type": "git",
6767
"url": "https://github.com/gatsbyjs/gatsby-starter-default"
6868
}
69-
}
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const path = require(`node:path`)
2+
3+
exports.createResolvers = ({ createResolvers }) => {
4+
createResolvers({
5+
Query: {
6+
fieldWithResolverThatMakeUseOfImportWithNodeProtocol: {
7+
type: `String`,
8+
args: {
9+
left: `String!`,
10+
right: `String!`,
11+
},
12+
resolve: (_, args) => {
13+
return path.posix.join(args.left, args.right)
14+
},
15+
},
16+
},
17+
})
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// noop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// this polyfill adds support for "require('node:<node_builtin>')" imports
2+
// this feature is available in Node v14.18.0+ and v16.0.0+
3+
// gatsby's minimal version (v14.15.0) does not support this feature
4+
// so the environment we run our e2e tests in doesn't support it
5+
// and we need to use polyfill to test if our bundlers support it correctly
6+
7+
// this file is injected with NODE_OPTIONS env var via package.json's
8+
// "build" script
9+
10+
try {
11+
require(`node:path`)
12+
} catch (e) {
13+
const mod = require("module")
14+
const originalModuleLoad = mod._load
15+
mod._load = (request, parent, isMain) => {
16+
if (request.startsWith(`node:`)) {
17+
request = request.replace(`node:`, ``)
18+
}
19+
return originalModuleLoad(request, parent, isMain)
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from "react"
2+
import { graphql } from "gatsby"
3+
4+
export default function StaticPath({ data, serverData }) {
5+
return (
6+
<>
7+
<pre data-testid="field-result">
8+
{JSON.stringify(
9+
data?.fieldWithResolverThatMakeUseOfImportWithNodeProtocol
10+
)}
11+
</pre>
12+
<pre data-testid="is-ssr">
13+
{JSON.stringify(serverData?.usingEngines ?? false)}
14+
</pre>
15+
</>
16+
)
17+
}
18+
19+
// just mark it as page that will use engine
20+
export async function getServerData() {
21+
return {
22+
props: {
23+
usingEngines: true,
24+
},
25+
}
26+
}
27+
28+
export const q = graphql`
29+
{
30+
fieldWithResolverThatMakeUseOfImportWithNodeProtocol(
31+
left: "foo"
32+
right: "bar"
33+
)
34+
}
35+
`

packages/gatsby/src/schema/graphql-engine/bundle-webpack.ts

+2
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,10 @@ export async function createGraphqlEngineBundle(
8686
mod.builtinModules.reduce((acc, builtinModule) => {
8787
if (builtinModule === `fs`) {
8888
acc[builtinModule] = `global _actualFsWrapper`
89+
acc[`node:${builtinModule}`] = `global _actualFsWrapper`
8990
} else {
9091
acc[builtinModule] = `commonjs ${builtinModule}`
92+
acc[`node:${builtinModule}`] = `commonjs ${builtinModule}`
9193
}
9294

9395
return acc

0 commit comments

Comments
 (0)