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

refactor(html-ssr): remove fs from ssr bundle, remove static queries from ssr bundle #29396

Merged
merged 9 commits into from
Feb 15, 2021

Conversation

pieh
Copy link
Contributor

@pieh pieh commented Feb 8, 2021

Description

Documentation

Related Issues

[ch23634]

@pieh pieh added the breaking change If implemented, this proposed work would break functionality for older versions of Gatsby label Feb 8, 2021
@gatsbot gatsbot bot added the status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer label Feb 8, 2021
state.opts.stage === `develop-html` ||
state.opts.stage === `build-html`) &&
state.opts.stage === `develop-html`) &&
Copy link
Contributor Author

@pieh pieh Feb 8, 2021

Choose a reason for hiding this comment

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

breaking change no. 1 - babel plugin no longer inline static queries in build-html

Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious, why only build-html? It is not immediately clear.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For the most part because I don't "care" about develop-html in this PR (other than it still working heh).

I remove static queries results inlining from Prod SSR bundle so it doesn't impact SSR bundle compilation hash so we don't hit case of SSR bundle hash changing invalidating ALL the pages (so we can invalidate only pages that actually are affected by static query result changes).

return null
}
function loadPageDataSync() {
throw new Error(`"loadPageDataSync" is no longer available`)
Copy link
Contributor Author

@pieh pieh Feb 8, 2021

Choose a reason for hiding this comment

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

Breaking change no. 2

This might not need to be done, but only plugin that was making use of this was guess-js one

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This might be changed to "temporarairly unavailble, but using this will cause all pages to be rebuild all the time" when we wrap fs usage.

That would be safer given, that we didn't have deprecation for it, so we don't need to break it completely (so it continue to work but usage of it would disallow using partial html writes)

Copy link
Contributor

Choose a reason for hiding this comment

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

https://www.npmjs.com/package/gatsby-plugin-guess-js gets almost no downloads so I think it's fine saying adios.

@pieh pieh removed the status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer label Feb 8, 2021
@pieh pieh force-pushed the no-fs-in-ssr-no-static-queries-in-ssr-bundle branch 2 times, most recently from 98d992e to 2fb0aa1 Compare February 8, 2021 19:38
@pieh pieh marked this pull request as ready for review February 9, 2021 08:58
Comment on lines -517 to +523
res.sendFile(directoryPath(`public/index.html`), err => {
res.sendFile(directoryPath(`.cache/develop-html/index.html`), err => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just so develop skeleton index.html doesn't override prod one in public dir

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(and also this would be removed when DEV_SSR is stable)

@@ -586,6 +593,7 @@ export async function initialize({
.map(
plugin =>
`{
name: '${plugin.name}',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added only to decorate thrown error with plugin name when there is exception during gatsby-ssr execution (like trying to use removed loadPageDataSync helper

packages/gatsby/cache-dir/static-entry.js Show resolved Hide resolved
packages/gatsby/src/utils/worker/render-html.ts Outdated Show resolved Hide resolved
state.opts.stage === `develop-html` ||
state.opts.stage === `build-html`) &&
state.opts.stage === `develop-html`) &&
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious, why only build-html? It is not immediately clear.

Comment on lines 66 to 67
let scriptsAndStyles = flatten(
[`app`, componentChunkName].map(s => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I think we can use ["app", "componentChunkName"].flatMap() now that the minimum Node version is 12.13

Comment on lines 77 to 163
chunks = chunks.map(chunk => {
if (chunk === `/`) {
return null
}
return { rel: `preload`, name: chunk }
})

namedChunkGroups[s].assets.forEach(asset =>
chunks.push({ rel: `preload`, name: asset })
)

const childAssets = namedChunkGroups[s].childAssets
for (const rel in childAssets) {
chunks = concat(
chunks,
childAssets[rel].map(chunk => {
return { rel, name: chunk }
})
)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: to build this final chunks array we first use map, then forEach with push and then for with concat 😄 Maybe prettify for consistency?

I realize this was originally this way in static-entry.js but I doubt we'll find a better time to refactor it a bit :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, this was straight c&p, but we can use this opportunity to streamline this code (if not now then we never will heh)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TBH, I'll probably not use any "functional" array methods and just init array(s) ahead of time and do for loops adding as many things as needed inside.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done in 1e87c41 + follow up fix for 1 thing I messed up in 7c46317

Comment on lines 121 to 147
if (style.rel !== `prefetch`) {
const memoizedInlineCss = inlineCssCache.get(style.name)
if (memoizedInlineCss) {
return {
...style,
content: memoizedInlineCss,
}
}

let getInlineCssPromise = inFlightInlineCssPromise.get(style.name)
if (!getInlineCssPromise) {
getInlineCssPromise = fs
.readFile(join(process.cwd(), `public`, style.name), `utf-8`)
.then(content => {
inlineCssCache.set(style.name, content)
inFlightInlineCssPromise.delete(style.name)

return content
})

inFlightInlineCssPromise.set(style.name, getInlineCssPromise)
}

return {
...style,
content: await getInlineCssPromise,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: do we need this inlineCssCache cache? Maybe we can just keep inlineCssPromiseCache to simplify this a bit?

Suggested change
if (style.rel !== `prefetch`) {
const memoizedInlineCss = inlineCssCache.get(style.name)
if (memoizedInlineCss) {
return {
...style,
content: memoizedInlineCss,
}
}
let getInlineCssPromise = inFlightInlineCssPromise.get(style.name)
if (!getInlineCssPromise) {
getInlineCssPromise = fs
.readFile(join(process.cwd(), `public`, style.name), `utf-8`)
.then(content => {
inlineCssCache.set(style.name, content)
inFlightInlineCssPromise.delete(style.name)
return content
})
inFlightInlineCssPromise.set(style.name, getInlineCssPromise)
}
return {
...style,
content: await getInlineCssPromise,
}
if (style.rel !== `prefetch`) {
let getInlineCssPromise = inFlightInlineCssPromise.get(style.name)
if (!getInlineCssPromise) {
getInlineCssPromise = fs
.readFile(join(process.cwd(), `public`, style.name), `utf-8`)
inFlightInlineCssPromise.set(style.name, getInlineCssPromise)
}
return {
...style,
content: await getInlineCssPromise,
}

We still preserve inlineCssCache in memory so not a big difference. Or am I missing something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, you are right. This was just poor attempt at avoiding promise usage when not needed, but given that this would be used at most once per template there's no measurable diff there to gain and simplifying things is for the best

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done in f9016bb

@pieh pieh force-pushed the no-fs-in-ssr-no-static-queries-in-ssr-bundle branch from 0c83fdc to aac9d30 Compare February 15, 2021 11:50
Copy link
Contributor

@vladar vladar left a comment

Choose a reason for hiding this comment

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

Let's do it! 🚢

@pieh pieh merged commit f221c33 into master Feb 15, 2021
@pieh pieh deleted the no-fs-in-ssr-no-static-queries-in-ssr-bundle branch February 15, 2021 17:28
pragmaticpat pushed a commit to pragmaticpat/gatsby that referenced this pull request Apr 28, 2022
…from ssr bundle (gatsbyjs#29396)

* refactor(html-ssr): remove fs from ssr bundle, remove static queries from ssr bundle

* print plugin name that thrown

* rename timestamp to sessionId to better convey semantics on what it's used for

* use posix joins, so builds on windows dont use backslashes when generating urls

* no moar lodash

* simplify inline css caches by merging 2 caches into 1 promise cache

Co-authored-by: Vladimir Razuvaev <vladimir.razuvaev@gmail.com>

* apparently css is not scripting language

* set default param value

* add plugin annotation to message, don't create new error as this cause issues with creating pretty error message with codeframes etc

Co-authored-by: Vladimir Razuvaev <vladimir.razuvaev@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change If implemented, this proposed work would break functionality for older versions of Gatsby topic: build Related to the Gatsby build process
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants