diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 5b2bba82fcbec..b07028dc89cf2 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -56,7 +56,6 @@ "eslint-plugin-react": "^7.8.2", "express": "^4.16.3", "express-graphql": "^0.6.12", - "express-history-api-fallback": "^2.2.1", "fast-levenshtein": "~2.0.4", "file-loader": "^1.1.11", "flat": "^4.0.0", diff --git a/packages/gatsby/src/commands/serve.js b/packages/gatsby/src/commands/serve.js index d8d84f3d617fd..a6e062e11376c 100644 --- a/packages/gatsby/src/commands/serve.js +++ b/packages/gatsby/src/commands/serve.js @@ -1,13 +1,39 @@ /* @flow weak */ const path = require(`path`) const openurl = require(`better-opn`) +const fs = require(`fs-extra`) const signalExit = require(`signal-exit`) const compression = require(`compression`) const express = require(`express`) -const historyFallback = require(`express-history-api-fallback`) const getConfigFile = require(`../bootstrap/get-config-file`) const preferDefault = require(`../bootstrap/prefer-default`) const chalk = require(`chalk`) +const { match: reachMatch } = require(`@reach/router/lib/utils`) + +const getPages = directory => + fs + .readFile(path.join(directory, `.cache`, `pages.json`)) + .then(contents => JSON.parse(contents)) + .catch(() => []) + +const clientOnlyPathsRouter = (pages, options) => { + const clientOnlyRoutes = pages + .filter(page => page.matchPath) + .map(page => page.matchPath) + return (req, res, next) => { + const { url } = req + if (req.accepts(`html`)) { + if (clientOnlyRoutes.some(route => reachMatch(route, url) !== null)) { + return res.sendFile(`index.html`, options, err => { + if (err) { + next() + } + }) + } + } + return next() + } +} module.exports = async program => { let { prefixPaths, port, open, host } = program @@ -21,18 +47,18 @@ module.exports = async program => { pathPrefix = prefixPaths && pathPrefix ? pathPrefix : `/` const root = path.join(program.directory, `public`) + const pages = await getPages(program.directory) const app = express() const router = express.Router() router.use(compression()) router.use(express.static(`public`)) - router.use(historyFallback(`index.html`, { root })) + router.use(clientOnlyPathsRouter(pages, { root })) router.use((req, res, next) => { if (req.accepts(`html`)) { - res.status(404).sendFile(`404.html`, { root }) - } else { - next() + return res.status(404).sendFile(`404.html`, { root }) } + return next() }) app.use(pathPrefix, router) @@ -55,7 +81,5 @@ module.exports = async program => { } }) - signalExit((code, signal) => { - server.close() - }) + signalExit(() => server.close()) } diff --git a/yarn.lock b/yarn.lock index 39985657fb110..8dfbab0309055 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7759,11 +7759,6 @@ express-graphql@^0.6.12: http-errors "^1.3.0" raw-body "^2.3.2" -express-history-api-fallback@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/express-history-api-fallback/-/express-history-api-fallback-2.2.1.tgz#3a2ad27f7bebc90fc533d110d7c6d83097bcd057" - integrity sha1-OirSf3vryQ/FM9EQ18bYMJe80Fc= - express@^4.16.2, express@^4.16.3: version "4.16.3" resolved "http://registry.npmjs.org/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53"