Skip to content

Commit ae5a654

Browse files
gatsbybotpieh
andauthored
fix(gatsby): don't serve codeframes for files outside of compilation (#38059) (#38062)
* test: add test case for overlay handlers * fix: don't serve codeframes for files outside of compilation (cherry picked from commit ed5855e) Co-authored-by: Michal Piechowiak <[email protected]>
1 parent 18a47da commit ae5a654

File tree

5 files changed

+101
-3
lines changed

5 files changed

+101
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
this file shouldn't be allowed to be served
1+
this file shouldn't be allowed to be served. CYPRESS-MARKER
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const cwd = Cypress.config(`projectRoot`)
2+
3+
describe(`overlay handlers don't serve unrelated files`, () => {
4+
it(`__file-code-frame`, () => {
5+
cy.request(
6+
`__file-code-frame?filePath=${cwd}/SHOULD_NOT_SERVE&lineNumber=0`
7+
).should(response => {
8+
expect(response.body.codeFrame).not.to.match(/CYPRESS-MARKER/)
9+
})
10+
})
11+
12+
it(`__original-stack-frame`, () => {
13+
cy.request(
14+
`__original-stack-frame?moduleId=${cwd}/SHOULD_NOT_SERVE&lineNumber=0&skipSourceMap=1`
15+
).should(response => {
16+
expect(response.body.codeFrame).not.to.match(/CYPRESS-MARKER/)
17+
expect(response.body.sourceContent).not.to.match(/CYPRESS-MARKER/)
18+
})
19+
})
20+
})

packages/gatsby/src/commands/build-html.ts

+5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import type { ISlicePropsEntry } from "../utils/worker/child/render-html"
2626
import { getPageMode } from "../utils/page-mode"
2727
import { extractUndefinedGlobal } from "../utils/extract-undefined-global"
2828
import { modifyPageDataForErrorMessage } from "../utils/page-data"
29+
import { setFilesFromDevelopHtmlCompilation } from "../utils/webpack/utils/is-file-inside-compilations"
2930

3031
type IActivity = any // TODO
3132

@@ -218,6 +219,10 @@ const doBuildRenderer = async (
218219
)
219220
}
220221

222+
if (stage === `develop-html`) {
223+
setFilesFromDevelopHtmlCompilation(stats.compilation)
224+
}
225+
221226
// render-page.js is hard coded in webpack.config
222227
return {
223228
rendererPath: `${directory}/${ROUTES_DIRECTORY}render-page.js`,

packages/gatsby/src/utils/start-server.ts

+33-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import webpackHotMiddleware from "@gatsbyjs/webpack-hot-middleware"
22
import webpackDevMiddleware from "webpack-dev-middleware"
33
import got, { Method } from "got"
4-
import webpack from "webpack"
4+
import webpack, { Compilation } from "webpack"
55
import express from "express"
66
import compression from "compression"
77
import { createHandler as createGraphqlEndpointHandler } from "graphql-http/lib/use/express"
@@ -50,6 +50,7 @@ import { getPageMode } from "./page-mode"
5050
import { configureTrailingSlash } from "./express-middlewares"
5151
import type { Express } from "express"
5252
import { addImageRoutes } from "gatsby-plugin-utils/polyfill-remote-file"
53+
import { isFileInsideCompilations } from "./webpack/utils/is-file-inside-compilations"
5354

5455
type ActivityTracker = any // TODO: Replace this with proper type once reporter is typed
5556

@@ -413,6 +414,19 @@ export async function startServer(
413414
store.getState().program.directory,
414415
req.query.moduleId as string
415416
)
417+
418+
const compilation: Compilation =
419+
res.locals?.webpack?.devMiddleware?.stats?.compilation
420+
if (!compilation) {
421+
res.json(emptyResponse)
422+
return
423+
}
424+
425+
if (!isFileInsideCompilations(absolutePath, compilation)) {
426+
res.json(emptyResponse)
427+
return
428+
}
429+
416430
try {
417431
sourceContent = fs.readFileSync(absolutePath, `utf-8`)
418432
} catch (e) {
@@ -540,7 +554,24 @@ export async function startServer(
540554
return
541555
}
542556

543-
const sourceContent = await fs.readFile(filePath, `utf-8`)
557+
const absolutePath = path.resolve(
558+
store.getState().program.directory,
559+
filePath
560+
)
561+
562+
const compilation: Compilation =
563+
res.locals?.webpack?.devMiddleware?.stats?.compilation
564+
if (!compilation) {
565+
res.json(emptyResponse)
566+
return
567+
}
568+
569+
if (!isFileInsideCompilations(absolutePath, compilation)) {
570+
res.json(emptyResponse)
571+
return
572+
}
573+
574+
const sourceContent = await fs.readFile(absolutePath, `utf-8`)
544575

545576
const codeFrame = codeFrameColumns(
546577
sourceContent,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Compilation, NormalModule } from "webpack"
2+
3+
const filesInsideDevelopHtmlCompilation = new Set<string>()
4+
5+
function removeQueryParams(path: string): string {
6+
return path.split(`?`)[0]
7+
}
8+
9+
export function setFilesFromDevelopHtmlCompilation(
10+
developHtmlCompilation: Compilation
11+
): void {
12+
filesInsideDevelopHtmlCompilation.clear()
13+
14+
for (const module of developHtmlCompilation.modules) {
15+
if (module instanceof NormalModule && module.resource) {
16+
filesInsideDevelopHtmlCompilation.add(removeQueryParams(module.resource))
17+
}
18+
}
19+
}
20+
21+
/**
22+
* Checks if a file is inside either `develop` or `develop-html` compilation. Used to determine if
23+
* we should generate codeframe for this file for error overlay.
24+
*/
25+
export function isFileInsideCompilations(
26+
absolutePath: string,
27+
developBrowserCompilation: Compilation
28+
): boolean {
29+
if (filesInsideDevelopHtmlCompilation.has(absolutePath)) {
30+
return true
31+
}
32+
33+
for (const module of developBrowserCompilation.modules) {
34+
if (module instanceof NormalModule && module.resource) {
35+
if (absolutePath === removeQueryParams(module.resource)) {
36+
return true
37+
}
38+
}
39+
}
40+
41+
return false
42+
}

0 commit comments

Comments
 (0)