diff --git a/package.json b/package.json index 754c00c6..d2e41e18 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "glob-promise": "3.3.0", "hoist-non-react-statics": "2.3.1", "htmlescape": "1.1.1", + "http-errors": "1.6.2", "http-status": "1.0.1", "json-loader": "0.5.7", "loader-utils": "1.1.0", @@ -84,7 +85,7 @@ "mkdirp-then": "1.2.0", "mv": "2.1.1", "mz": "2.7.0", - "path-match": "1.2.4", + "path-to-regexp": "2.1.0", "pkg-up": "2.0.0", "prop-types": "15.6.0", "prop-types-exact": "1.1.1", diff --git a/server/index.js b/server/index.js index 04c5a592..0cdbfde8 100644 --- a/server/index.js +++ b/server/index.js @@ -179,7 +179,11 @@ export default class Server { await serveStatic(req, res, path) }, - '/_next/:buildId/page/_error*': async (req, res, params) => { + // This is very similar to the following route. + // But for this one, the page already built when the Next.js process starts. + // There's no need to build it in on-demand manner and check for other things. + // So, it's clean to have a seperate route for this. + '/_next/:buildId/page/_error.js': async (req, res, params) => { if (!this.handleBuildId(params.buildId, res)) { const error = new Error('INVALID_BUILD_ID') const customFields = { buildIdMismatched: true } diff --git a/server/lib/path-match.js b/server/lib/path-match.js new file mode 100644 index 00000000..a8fefa11 --- /dev/null +++ b/server/lib/path-match.js @@ -0,0 +1,41 @@ +// We borrow this code from https://github.com/pillarjs/path-match +// That's because, ^^^ package comes with very old version of path-to-regexp +// So, it'll give us issues when the app has used a newer version of path-to-regexp +// (When webpack resolving packages) +var pathToRegexp = require('path-to-regexp') +var createError = require('http-errors') + +module.exports = function (options) { + options = options || {} + + return function (path) { + var keys = [] + var re = pathToRegexp(path, keys, options) + + return function (pathname, params) { + var m = re.exec(pathname) + if (!m) return false + + params = params || {} + + var key, param + for (var i = 0; i < keys.length; i++) { + key = keys[i] + param = m[i + 1] + if (!param) continue + params[key.name] = decodeParam(param) + if (key.repeat) params[key.name] = params[key.name].split(key.delimiter) + } + + return params + } + } +} + +function decodeParam (param) { + try { + return decodeURIComponent(param) + } catch (_) { + throw createError(400, 'failed to decode param "' + param + '"') + } +} diff --git a/server/router.js b/server/router.js index b393a114..50efd70e 100644 --- a/server/router.js +++ b/server/router.js @@ -1,4 +1,4 @@ -import pathMatch from 'path-match' +import pathMatch from './lib/path-match' const route = pathMatch() diff --git a/yarn.lock b/yarn.lock index 9a23bc01..7c871e3b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2912,14 +2912,7 @@ htmlparser2@^3.9.1: inherits "^2.0.1" readable-stream "^2.0.2" -http-errors@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.4.0.tgz#6c0242dea6b3df7afda153c71089b31c6e82aabf" - dependencies: - inherits "2.0.1" - statuses ">= 1.2.1 < 2" - -http-errors@~1.6.2: +http-errors@1.6.2, http-errors@~1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" dependencies: @@ -3230,10 +3223,6 @@ is-windows@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9" -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -4512,13 +4501,6 @@ path-key@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" -path-match@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/path-match/-/path-match-1.2.4.tgz#a62747f3c7e0c2514762697f24443585b09100ea" - dependencies: - http-errors "~1.4.0" - path-to-regexp "^1.0.0" - path-parse@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" @@ -4527,11 +4509,9 @@ path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" -path-to-regexp@^1.0.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" - dependencies: - isarray "0.0.1" +path-to-regexp@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.1.0.tgz#7e30f9f5b134bd6a28ffc2e3ef1e47075ac5259b" path-type@^1.0.0: version "1.1.0" @@ -5448,7 +5428,7 @@ standard@9.0.2: eslint-plugin-standard "~2.0.1" standard-engine "~5.4.0" -"statuses@>= 1.2.1 < 2", "statuses@>= 1.3.1 < 2", statuses@~1.3.1: +"statuses@>= 1.3.1 < 2", statuses@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"