Skip to content

Commit fc22f4b

Browse files
gatsbybotpieh
andauthored
fix(gatsby): don't serve codeframes for files outside of compilation (#38059) (#38063)
* 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 8889bfe commit fc22f4b

File tree

5 files changed

+80
-3
lines changed

5 files changed

+80
-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,11 @@
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+
})

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

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import { PackageJson } from "../.."
2020
import { IPageDataWithQueryResult } from "../utils/page-data"
2121

2222
import type { GatsbyWorkerPool } from "../utils/worker/pool"
23+
import { setFilesFromDevelopHtmlCompilation } from "../utils/webpack/utils/is-file-inside-compilations"
24+
2325
type IActivity = any // TODO
2426

2527
const isPreview = process.env.GATSBY_IS_PREVIEW === `true`
@@ -211,6 +213,10 @@ const doBuildRenderer = async (
211213
)
212214
}
213215

216+
if (stage === `develop-html`) {
217+
setFilesFromDevelopHtmlCompilation(stats.compilation)
218+
}
219+
214220
// render-page.js is hard coded in webpack.config
215221
return {
216222
rendererPath: `${directory}/${ROUTES_DIRECTORY}render-page.js`,

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

+20-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 { graphqlHTTP, OptionsData } from "express-graphql"
@@ -55,6 +55,7 @@ import { getPageMode } from "./page-mode"
5555
import { configureTrailingSlash } from "./express-middlewares"
5656
import type { Express } from "express"
5757
import { addImageRoutes } from "gatsby-plugin-utils/polyfill-remote-file"
58+
import { isFileInsideCompilations } from "./webpack/utils/is-file-inside-compilations"
5859

5960
type ActivityTracker = any // TODO: Replace this with proper type once reporter is typed
6061

@@ -502,7 +503,24 @@ export async function startServer(
502503
return
503504
}
504505

505-
const sourceContent = await fs.readFile(filePath, `utf-8`)
506+
const absolutePath = path.resolve(
507+
store.getState().program.directory,
508+
filePath
509+
)
510+
511+
const compilation: Compilation =
512+
res.locals?.webpack?.devMiddleware?.stats?.compilation
513+
if (!compilation) {
514+
res.json(emptyResponse)
515+
return
516+
}
517+
518+
if (!isFileInsideCompilations(absolutePath, compilation)) {
519+
res.json(emptyResponse)
520+
return
521+
}
522+
523+
const sourceContent = await fs.readFile(absolutePath, `utf-8`)
506524

507525
const codeFrame = codeFrameColumns(
508526
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)