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

[1.0] Upgrade React Router to v4 #940

Merged
merged 18 commits into from
May 11, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Get router working in production w/ lazy loading of bundles
  • Loading branch information
KyleAMathews committed May 10, 2017
commit e5097827a6bd28cb65ebb76fa2470bf444ef0b04
3 changes: 2 additions & 1 deletion packages/gatsby-link/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
},
"dependencies": {
"@types/react-router": "^2.0.49",
"prop-types": "^15.5.8"
"prop-types": "^15.5.8",
"ric": "^1.3.0"
}
}
71 changes: 39 additions & 32 deletions packages/gatsby-link/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import React from "react"
import { Link } from "react-router-dom"
import PropTypes from "prop-types"

if (typeof window !== `undefined`) {
require(`ric`)
}

let linkPrefix = ``
if (__PREFIX_LINKS__) {
linkPrefix = __LINK_PREFIX__
Expand All @@ -11,42 +15,45 @@ class GatsbyLink extends React.Component {
propTypes: {
to: PropTypes.string.isRequired,
}
// componentDidMount() {
// // Only enable prefetching of Link resources in production and for browsers
// // that don't support service workers *cough* Safari/IE *cough*.
// if (
// (process.env.NODE_ENV === `production` &&
// !(`serviceWorker` in navigator)) ||
// window.location.protocol !== `https:`
// ) {
// const routes = window.gatsbyRootRoute
// const { createMemoryHistory } = require(`history`)
// const matchRoutes = require(`react-router/lib/matchRoutes`)
// const getComponents = require(`react-router/lib/getComponents`)

// const createLocation = createMemoryHistory().createLocation

// if (typeof routes !== `undefined`) {
// matchRoutes(
// [routes],
// createLocation(this.props.to),
// (error, nextState) => {
// if (error) {
// return console.error(error)
// }
componentDidMount() {
// Only enable prefetching of Link resources in production and for browsers
// that don't support service workers *cough* Safari/IE *cough*.
// TODO also add check if user is using SW, e.g. window.caches
if (
(process.env.NODE_ENV === `production` &&
!(`serviceWorker` in navigator)) ||
window.location.protocol !== `https:`
) {
requestUserIdle(() => {
console.log(`the user is idle`)
___loadScriptsForPath(this.props.to)
})
}
}

// if (nextState) {
// getComponents(nextState)
// }
// }
// )
// }
// }
// },
render() {
const to = linkPrefix + this.props.to
return <Link {...this.props} to={to} />
return (
<Link
onClick={e => {
// In production, make sure the necessary scripts are
// loaded before continuing.
if (process.env.NODE_ENV === `production`) {
e.preventDefault()
window.___loadScriptsForPath(this.props.to, () => {
this.context.router.history.push(this.props.to)
})
}
}}
{...this.props}
to={to}
/>
)
}
}

GatsbyLink.contextTypes = {
router: PropTypes.object,
}

module.exports = GatsbyLink
13 changes: 5 additions & 8 deletions packages/gatsby-link/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -365,13 +365,6 @@ core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"

create-react-class@^15.5.2:
version "15.5.2"
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.5.2.tgz#6a8758348df660b88326a0e764d569f274aad681"
dependencies:
fbjs "^0.8.9"
object-assign "^4.1.1"

cryptiles@2.x.x:
version "2.0.5"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
Expand Down Expand Up @@ -924,7 +917,7 @@ oauth-sign@~0.8.1:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"

object-assign@^4.1.0, object-assign@^4.1.1:
object-assign@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"

Expand Down Expand Up @@ -1106,6 +1099,10 @@ request@^2.81.0:
tunnel-agent "^0.6.0"
uuid "^3.0.0"

ric@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/ric/-/ric-1.3.0.tgz#8e95042609ce8213548a83164d08e94fae94909f"

rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d"
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby-plugin-catch-links/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/gatsby-browser.js
/catch-links.js
10 changes: 3 additions & 7 deletions packages/gatsby-plugin-catch-links/src/gatsby-browser.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import catchLinks from "./catch-links"
import createHistory from "history/createBrowserHistory"

const history = createHistory()
console.log(history)
window.gatsby_history = history

catchLinks(window, href => {
console.log(href)
// TODO figure out why this isn't working...
history.push(href)
window.___loadScriptsForPath(href, () => {
window.___history.push(href)
})
})
127 changes: 104 additions & 23 deletions packages/gatsby/lib/cache-dir/production-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,56 @@ import ReactDOM from "react-dom"
import { BrowserRouter as Router, Route, Switch } from "react-router-dom"
import { ScrollContext } from "react-router-scroll"
import createHistory from "history/createBrowserHistory"
import routes from "./routes.json"

const requires = require(`./async-requires`)
import requires from "./async-requires"

console.log(routes)
console.log(requires)

// Load scripts
const preferDefault = m => (m && m.default) || m
const scriptsCache = {}
const loadScriptsForPath = (path, cb = () => {}) => {
console.log(`loading scripts for`, path)

if (!path) {
return cb()
}

if (scriptsCache[path]) {
return cb(scriptsCache[path])
}

const page = routes.find(r => r.path === path)
console.time(`load scripts`)
let scripts = {
layout: false,
component: false,
pageData: false,
}
const loaded = () => {
if (scripts.layout && scripts.component && scripts.pageData) {
console.timeEnd(`load scripts`)
scriptsCache[path] = scripts
cb(scripts)
}
}
requires.layouts.index(layout => {
scripts.layout = preferDefault(layout)
loaded()
})
requires.components[page.componentChunkName](component => {
scripts.component = preferDefault(component)
loaded()
})
requires.json[page.jsonName](pageData => {
scripts.pageData = pageData
loaded()
})
}

window.___loadScriptsForPath = loadScriptsForPath

const history = createHistory()
history.listen((location, action) => {
Expand All @@ -33,25 +81,58 @@ function shouldUpdateScroll(prevRouterProps, { location: { pathname } }) {
return true
}

// Match, ensure all necessary bundles are loaded, then runder.
// match(
// { history: browserHistory, routes: rootRoute },
// (error, redirectLocation, renderProps) => {
// const Root = () => (
// <Router
// {...renderProps}
// render={applyRouterMiddleware(useScroll(shouldUpdateScroll))}
// onUpdate={() => {
// apiRunner(`onRouteUpdate`, currentLocation)
// }}
// />
// )
// const NewRoot = apiRunner(`wrapRootComponent`, { Root }, Root)[0]
// ReactDOM.render(
// <NewRoot />,
// typeof window !== `undefined`
// ? document.getElementById(`___gatsby`)
// : void 0
// )
// }
// )
// Load 404 page component and scripts
let notFoundScripts
loadScriptsForPath(`/404.html`, scripts => {
notFoundScripts = scripts
})

const renderPage = props => {
const page = routes.find(r => r.path === props.location.pathname)
if (page) {
return $(scriptsCache[props.location.pathname].component, {
...props,
...scriptsCache[props.location.pathname].pageData,
})
} else {
$(notFoundScripts.component, {
...props,
...notFoundScripts.pageData,
})
}
}

const renderSite = ({ scripts, props }) => {
return $(scripts.layout, { ...props }, renderPage(props))
}

const $ = React.createElement

loadScriptsForPath(window.location.pathname, () => {
const Root = () =>
$(
Router,
null,
$(
ScrollContext,
{ shouldUpdateScroll },
$(Route, {
component: props => {
window.___history = props.history
return renderSite({
scripts: scriptsCache[props.location.pathname],
props,
})
},
})
)
)

const NewRoot = apiRunner(`wrapRootComponent`, { Root }, Root)[0]
ReactDOM.render(
<NewRoot />,
typeof window !== `undefined`
? document.getElementById(`___gatsby`)
: void 0
)
})
13 changes: 6 additions & 7 deletions packages/gatsby/lib/cache-dir/root.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ import apiRunner from "./api-runner-browser"
import syncRequires from "./sync-requires"
import routes from "./routes.json"

console.log(syncRequires)
console.log(routes)

const history = createHistory()
history.listen((location, action) => {
apiRunner(`onRouteUpdate`, location, action)
Expand Down Expand Up @@ -47,12 +44,13 @@ const Root = () =>
ScrollContext,
{ shouldUpdateScroll },
$(Route, {
component: location =>
component: props => {
window.__history = props.history
// TODO add support for multiple nested layouts
// and for layouts to be able to have their own queries.
$(
return $(
syncRequires.layouts[`index`],
{ ...location },
{ ...props },
$(Switch, null, [
...filteredRoutes.map(route => {
return $(Route, {
Expand All @@ -73,7 +71,8 @@ const Root = () =>
}),
}),
])
),
)
},
})
)
)
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby/lib/cache-dir/static-entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ module.exports = (locals, callback) => {
const dascripts = [
`commons`,
`app`,
`layout-component---index`,
pathChunkName(locals.path),
pages.find(page => page.path === locals.path).componentChunkName,
]
Expand Down
6 changes: 0 additions & 6 deletions packages/gatsby/lib/utils/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ async function html(program: any) {
})

console.log(`Generating Static HTML`)
// Write out pages data to file so it's available to the static-entry.js
// file.
fs.writeFileSync(
`${program.directory}/public/tmp-pages.json`,
JSON.stringify(store.getState().pages)
)
await buildHTML(program).catch(err => {
console.log(``)
console.log(`Generating HTML failed`)
Expand Down
1 change: 0 additions & 1 deletion packages/gatsby/lib/utils/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,6 @@ module.exports = async (
.pages.map(page => page.componentChunkName)
components = uniq(components)
components.push(`layout-component---index`)
console.log("components", components)
return [
// Moment.js includes 100s of KBs of extra localization data
// by default in Webpack that most sites don't want.
Expand Down