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

[v2] Build-html static file using the webpack magic comment to provide the link rel. #5901

Merged
8 changes: 8 additions & 0 deletions examples/using-prefetching-preloading-modules/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"env": {
"browser": true
},
"globals": {
"graphql": false
}
}
6 changes: 6 additions & 0 deletions examples/using-prefetching-preloading-modules/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Using Prefetching/Preloading modules

https://using-prefetch-preload-module.gatsbyjs.org

## References
- [Prefetching/Preloading Modules](https://webpack.js.org/guides/code-splitting/#prefetching-preloading-modules).
16 changes: 16 additions & 0 deletions examples/using-prefetching-preloading-modules/gatsby-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module.exports = {
siteMetadata: {
title: `Gatsby with styled components`,
},
plugins: [
`gatsby-plugin-styled-components`,
{
resolve: `gatsby-plugin-typography`,
options: {
pathToConfigModule: `src/utils/typography.js`,
},
},
`gatsby-plugin-react-helmet`,
`gatsby-plugin-offline`,
],
}
33 changes: 33 additions & 0 deletions examples/using-prefetching-preloading-modules/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "gatsby-example-using-prefetching-preloading-modules",
"private": true,
"description": "Gatsby example site using Prefetching/Preloading modules",
"version": "2.0.0",
"author": "Nuttapol Laoticharoen <[email protected]>",
"dependencies": {
"babel-plugin-styled-components": "^1.5.1",
"gatsby": "next",
"gatsby-plugin-offline": "next",
"gatsby-plugin-react-helmet": "next",
"gatsby-plugin-styled-components": "next",
"gatsby-plugin-typography": "next",
"lodash": "^4.16.4",
"react": "^16.4.0",
"react-dom": "^16.4.0",
"react-helmet": "^5.2.0",
"react-typography": "^0.16.13",
"slash": "^1.0.0",
"styled-components": "^3.3.2",
"typography": "^0.16.17",
"typography-breakpoint-constants": "^0.15.10"
},
"keywords": [
"gatsby"
],
"license": "MIT",
"main": "n/a",
"scripts": {
"develop": "gatsby develop",
"build": "gatsby build"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react'

class DynamicComponent extends React.Component {
handleClick = () => {
console.log(`Sync-Click!`)
import(/* webpackChunkName: "async-console", webpackPreload: true */ `../utils/async-console`).then(module => {
const asyncConsole = module.default
asyncConsole(`Async-Log!`)
})
}

render() {
return <button onClick={this.handleClick}>
Dynamic Log
</button>
}
}

export default DynamicComponent
65 changes: 65 additions & 0 deletions examples/using-prefetching-preloading-modules/src/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React from "react"
import Helmet from "react-helmet"
import styled from "styled-components"
import DynamicComponent from "../components/DynamicComponent"
import "./style.css"

// Create a Title component that'll render an <h1> tag with some styles
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: brown;
`

// Create a Wrapper component that'll render a <section> tag with some styles
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`


class IndexPage extends React.Component {
handleClick = () => {
console.log(`Sync-Click!`)
import(/* webpackChunkName: "async-alert", webpackPrefetch: true */ `../utils/async-alert`).then(module => {
const asyncAlert = module.default
asyncAlert(`Async-Click!`)
})
}

render() {
return (
<React.Fragment>
<Helmet>
<title>Gatsby Prefetching/Preloading modules</title>
<meta
name="description"
content="Gatsby example site using prefetching/preloading modules"
/>
<meta name="referrer" content="origin" />
</Helmet>
<div
style={{
margin: `0 auto`,
marginTop: `3rem`,
padding: `1.5rem`,
maxWidth: 900,
color: `red`,
}}
>
<Wrapper>
<Title>Hello World, this is my first prefetching/preloading component!</Title>
<p>
<button onClick={this.handleClick}>
Dynamic Alert!
</button>
<DynamicComponent />
</p>
</Wrapper>
</div>
</React.Fragment>
)
}
}

export default IndexPage
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

.changeable-title {
color: red;
}

button {
margin-right: 20px;
float: left;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@


module.exports = x => alert(x)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@


module.exports = (...x) => console.log(...x)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import Typography from "typography"
import {
MOBILE_MEDIA_QUERY,
TABLET_MEDIA_QUERY,
} from "typography-breakpoint-constants"

const options = {
baseFontSize: `18px`,
baseLineHeight: 1.45,
blockMarginBottom: 0.75,
scaleRatio: 2.15,
overrideStyles: ({ rhythm, scale }, options) => {
return {
"h1,h2,h3,h4": {
lineHeight: 1.2,
},
[TABLET_MEDIA_QUERY]: {
// Make baseFontSize on mobile 17px.
html: {
fontSize: `${17 / 16 * 100}%`,
},
},
[MOBILE_MEDIA_QUERY]: {
// Make baseFontSize on mobile 16px.
html: {
fontSize: `${16 / 16 * 100}%`,
},
},
}
},
}

const typography = new Typography(options)

export default typography
2 changes: 1 addition & 1 deletion packages/gatsby/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
"url-loader": "^1.0.1",
"uuid": "^3.1.0",
"v8-compile-cache": "^1.1.0",
"webpack": "^4.4.1",
"webpack": "^4.12.0",
"webpack-dev-middleware": "^3.0.1",
"webpack-dev-server": "^3.1.1",
"webpack-hot-middleware": "^2.21.0",
Expand Down
62 changes: 42 additions & 20 deletions packages/gatsby/src/cache-dir/static-entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const fs = require(`fs`)
const { join } = require(`path`)
const { renderToString, renderToStaticMarkup } = require(`react-dom/server`)
const { StaticRouter, Route } = require(`react-router-dom`)
const { get, merge, isString, flatten } = require(`lodash`)
const { get, merge, isObject, flatten, uniqBy } = require(`lodash`)

const apiRunner = require(`./api-runner-ssr`)
const syncRequires = require(`./sync-requires`)
Expand Down Expand Up @@ -150,26 +150,40 @@ export default (pagePath, callback) => {
}

// Create paths to scripts
const scriptsAndStyles = flatten(
let scriptsAndStyles = flatten(
[`app`, page.componentChunkName].map(s => {
const fetchKey = `assetsByChunkName[${s}]`

let chunks = get(stats, fetchKey)
let namedChunkGroups = get(stats, `namedChunkGroups`)

if (!chunks) {
return null
}

return chunks.map(chunk => {
chunks = chunks.map(chunk => {
if (chunk === `/`) {
return null
}
return chunk
return { rel: `preload`, name: chunk }
})

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

return chunks
})
).filter(s => isString(s))
const scripts = scriptsAndStyles.filter(s => s.endsWith(`.js`))
const styles = scriptsAndStyles.filter(s => s.endsWith(`.css`))
).filter(s => isObject(s))
.sort((s1, s2) => s1.rel == `preload` ? -1 : 1) // given priority to preload

scriptsAndStyles = uniqBy(scriptsAndStyles, item => item.name)

const scripts = scriptsAndStyles.filter(script => script.name && script.name.endsWith(`.js`))
const styles = scriptsAndStyles.filter(style => style.name && style.name.endsWith(`.css`))

apiRunner(`onRenderBody`, {
setHeadComponents,
Expand All @@ -189,23 +203,20 @@ export default (pagePath, callback) => {
.slice(0)
.reverse()
.forEach(script => {
// Add preload <link>s for scripts.
// Add preload/prefetch <link>s for scripts.
headComponents.push(
<link
as="script"
rel="preload"
key={script}
href={urlJoin(pathPrefix, script)}
rel={script.rel}
key={script.name}
href={urlJoin(pathPrefix, script.name)}
/>
)
})

if (page.jsonName in dataPaths) {
const dataPath = `${pathPrefix}static/d/${dataPaths[page.jsonName]}.json`
// Insert json data path after commons and app
headComponents.splice(
1,
0,
headComponents.push(
<link
rel="preload"
key={dataPath}
Expand All @@ -221,21 +232,30 @@ export default (pagePath, callback) => {
.reverse()
.forEach(style => {
// Add <link>s for styles.
headComponents.push(
<link
as="style"
rel={style.rel}
key={style.name}
href={urlJoin(pathPrefix, style.name)}
/>
)

headComponents.unshift(
<style
type="text/css"
data-href={urlJoin(pathPrefix, style)}
data-href={urlJoin(pathPrefix, style.name)}
dangerouslySetInnerHTML={{
__html: fs.readFileSync(
join(process.cwd(), `public`, style),
join(process.cwd(), `public`, style.name),
`utf-8`
),
}}
/>
)
})

// Add script loader for page scripts to the end of body element (after webpack manifest).
// Add page metadata for the current page
const windowData = `/*<![CDATA[*/window.page=${JSON.stringify(page)};${
page.jsonName in dataPaths
? `window.dataPath="${dataPaths[page.jsonName]}";`
Expand All @@ -252,8 +272,10 @@ export default (pagePath, callback) => {
/>
)

const bodyScripts = scripts.map(s => {
const scriptPath = `${pathPrefix}${JSON.stringify(s).slice(1, -1)}`
// Filter out prefetched bundles as adding them as a script tag
// would force high priority fetching.
const bodyScripts = scripts.filter(s => s.rel !== `prefetch`).map(s => {
const scriptPath = `${pathPrefix}${JSON.stringify(s.name).slice(1, -1)}`
return <script key={scriptPath} src={scriptPath} async />
})

Expand Down
10 changes: 6 additions & 4 deletions packages/gatsby/src/utils/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ module.exports = async (
`gatsby-webpack-stats-extractor`,
(stats, done) => {
let assets = {}

for (let chunkGroup of stats.compilation.chunkGroups) {
if (chunkGroup.name) {
let files = []
Expand All @@ -226,11 +225,14 @@ module.exports = async (
}
}

const webpackStats = {
...stats.toJson({ all: false, chunkGroups: true }),
assetsByChunkName: assets,
}

fs.writeFile(
path.join(`public`, `webpack.stats.json`),
JSON.stringify({
assetsByChunkName: assets,
}),
JSON.stringify(webpackStats),
done
)
}
Expand Down
4 changes: 2 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11383,7 +11383,7 @@ printj@~1.1.0, printj@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"

prismjs@^1.13.0:
prismjs@^1.13.0, prismjs@^1.14.0:
version "1.14.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.14.0.tgz#bbccfdb8be5d850d26453933cb50122ca0362ae0"
optionalDependencies:
Expand Down Expand Up @@ -15436,7 +15436,7 @@ webpack-stats-plugin@^0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/webpack-stats-plugin/-/webpack-stats-plugin-0.1.5.tgz#29e5f12ebfd53158d31d656a113ac1f7b86179d9"

webpack@^4.4.1:
webpack@^4.12.0:
version "4.12.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.12.0.tgz#14758e035ae69747f68dd0edf3c5a572a82bdee9"
dependencies:
Expand Down