-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
feat(gatsby): enable modern builds for gatsby #14289
Conversation
Great work! Is the idea we'll release this behind a command-line flag / experimental config value? |
- add module scripts to static build html - make sure prefetch works with modern files - combine modern & legacy stats together
c8c5b4c
to
39a60a8
Compare
I was thinking of writing an issue about creating a new options inside |
@wardpeet please do! I've been thinking that would be really valuable--basically a way that we can get more fine-grained control (and likely analytics data, as well) of these experiments and make them a little more user-friendly than setting an environment variable. (It shouldn't necessarily block this though--but I do love the idea!) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some comments for myself so I don't forget XD
@@ -275,6 +298,8 @@ export default (pagePath, callback) => { | |||
scripts | |||
.slice(0) | |||
.reverse() | |||
// remove legacy scripts from our preload as we preload our modern files instead |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unsure if there is a workaround for this that we can have our cake and eat it too. A way to do this is document.write but I rather don't want to use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's add a disclaimer to the PR to say that we lose preload for legacy browers on first run
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added the note!
}) | ||
|
||
// Patches browsers who have a flawed noModule - module system | ||
// Sadly we lose preload for legacy browsers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Sadly we lose preload for legacy browsers | |
// Sadly we lose the benefit of the preload scanner for legacy browsers | |
// because the the sources are hidden in javascript. |
// @see https://caniuse.com/#feat=es6-module | ||
// 1. Safari 10.1 supports modules, but does not support the `nomodule` attribute - it will load <script nomodule> anyway. | ||
// 2. Edge does not executes noModule but still fetches it | ||
const noModuleBugFixScripts = `(function(b){function c(e){var d=b.createElement("script");d.src=e;b.body.appendChild(d)}"noModule"in b.createElement("script")||/Version\\/10\\.1(\\.\\d+)* Safari|Version\\/10\\.\\d(\\.\\d+)*.*Safari|Edge\\/1[6-8]\\.\\d/i.test(navigator.userAgent)||(%scripts%)})(document)` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had no clue on how to write this in a nicer way. Basically it detects if noModule exists or it does not exists and is safari 10.1.x or safari ios 10.x as they do have know type="module"
but not nomodule
const noModuleBugFixScripts = `(function(b){function c(e){var d=b.createElement("script");d.src=e;b.body.appendChild(d)}"noModule"in b.createElement("script")||/Version\\/10\\.1(\\.\\d+)* Safari|Version\\/10\\.\\d(\\.\\d+)*.*Safari|Edge\\/1[6-8]\\.\\d/i.test(navigator.userAgent)||(%scripts%)})(document)` | |
const noModuleBugFixScripts = `(function(b){function c(e){var d=b.createElement("script");d.src=e;b.body.appendChild(d)}"noModule"in b.createElement("script")||/Version\\/10\\.1(\\.\\d+)* Safari|Version\\/10\\.\\d(\\.\\d+)*.*Safari/i.test(navigator.userAgent)||(%scripts%)})(document)` |
@DSchau I think it's best to keep this under an experiment for now, I have no idea if this is going to be flawless 😄 for all websites. |
I think you should document 3 things on the blog post/documentation page:
Once per page manifest lands, we have to update this (cc @Moocar ) Random thought: In the future, a build that is set using browserslist might be "more modern" than modern so we might need to be careful about naming here 😉 |
This may be helpful: |
Thanks @moonmeister! I will indeed thinker a bit about that blog post |
packages/gatsby/cache-dir/loader.js
Outdated
createComponentUrls(resourceName).map(url => prefetchHelper(url)) | ||
) | ||
let componentUrls = createComponentUrls(resourceName) | ||
if (process.env.MODERN_BUILD) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets filter inside static-entry to only save modern / legacy assets inside the window.___chunkMapping
variable
@@ -275,6 +298,8 @@ export default (pagePath, callback) => { | |||
scripts | |||
.slice(0) | |||
.reverse() | |||
// remove legacy scripts from our preload as we preload our modern files instead |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's add a disclaimer to the PR to say that we lose preload for legacy browers on first run
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking great overall! Thank you @wardpeet ❤️
Left a few small comments
@@ -0,0 +1,3 @@ | |||
# production-runtime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# production-runtime | |
# modern-builds |
@@ -0,0 +1,3 @@ | |||
# production-runtime | |||
|
|||
A Gatsby project to test our production runtime for Themes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A Gatsby project to test our production runtime for Themes | |
A Gatsby project to test out modern builds |
@@ -0,0 +1,5 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File can be deleted since it isn't used
@@ -0,0 +1,17 @@ | |||
// *********************************************************** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably get rid of this folder and its contents as well
e2e-tests/modern-builds/package.json
Outdated
@@ -0,0 +1,34 @@ | |||
{ | |||
"name": "production-runtime", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"name": "production-runtime", | |
"name": "modern-builds", |
e2e-tests/modern-builds/package.json
Outdated
"name": "production-runtime", | ||
"description": "Gatsby default starter", | ||
"version": "1.0.0", | ||
"author": "Sidhartha Chatterjee <sid@gatsbyjs.com>", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"author": "Sidhartha Chatterjee <sid@gatsbyjs.com>", | |
"author": "Ward Peeters <ward@gatsbyjs.com>", |
Looks like this takes advantage of webpack multi-compiler yeah? Might affect gatsby-plugin-mdx's |
I'm going to restructure this PR in small chunks and probably remove the multi compiler instance as it's probably going to break things. I'll close this PR for now and re-open smaller chunks. I'll keep the branch alive. |
Description
Gatsby generates 2 bundles. One .js & one .mjs, the .js will be used for legacy browsers (<script nomodule>) & mjs will be used for es supported modules.
Changes I made:
I wonder if we should detect if a given browserlist is already > modern zo we don't have to add 2 script tags. Perhaps just disable when a custom babelrc and browserlist are given?
@DSchau created a killer todo, so for more info:
#2114 (comment)
Related Issues
#2114
Note
We lose preload for legacy browsers on first visit when a modern build is generated because there is no way for us to conditionally preload one set (legacy or modern) before knowing the browser and by then it is perhaps too late to add preload tags