diff --git a/package.json b/package.json index fd334ca357..94bfff1d33 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "path-match": "1.2.4", "react": "15.3.2", "react-dom": "15.3.2", + "resolve": "1.1.7", "send": "0.14.1", "url": "0.11.0", "webpack": "1.13.2" diff --git a/server/index.js b/server/index.js index a8e7dad74a..ed72c88594 100644 --- a/server/index.js +++ b/server/index.js @@ -61,7 +61,7 @@ export default class Server { try { html = await render(path, req, res, { dir, dev }) } catch (err) { - if ('MODULE_NOT_FOUND' === err.code) { + if ('ENOENT' === err.code) { return this.render404(req, res) } throw err @@ -77,7 +77,7 @@ export default class Server { try { json = await renderJSON(path, { dir }) } catch (err) { - if ('MODULE_NOT_FOUND' === err.code) { + if ('ENOENT' === err.code) { return this.render404(req, res) } throw err diff --git a/server/read.js b/server/read.js new file mode 100644 index 0000000000..747207cca7 --- /dev/null +++ b/server/read.js @@ -0,0 +1,22 @@ +import fs from 'mz/fs' +import resolve from './resolve' + +const cache = {} + +/** + * resolve a file like `require.resolve`, + * and read and cache the file content + */ + +async function read (path) { + const f = await resolve(path) + let promise = cache[f] + if (!promise) { + promise = cache[f] = fs.readFile(f, 'utf8') + } + return promise +} + +module.exports = read + +exports.cache = cache diff --git a/server/render.js b/server/render.js index 28e3743c6a..4d4a33b3c9 100644 --- a/server/render.js +++ b/server/render.js @@ -2,6 +2,8 @@ import { relative, resolve } from 'path' import { createElement } from 'react' import { renderToString, renderToStaticMarkup } from 'react-dom/server' import fs from 'mz/fs' +import requireResolve from './resolve' +import read from './read' import Router from '../lib/router' import Document from '../lib/document' import Head from '../lib/head' @@ -9,7 +11,8 @@ import App from '../lib/app' import { StyleSheetServer } from '../lib/css' export async function render (path, req, res, { dir = process.cwd(), dev = false } = {}) { - const mod = require(resolve(dir, '.next', 'pages', path)) + const p = await requireResolve(resolve(dir, '.next', 'pages', path)) + const mod = require(p) const Component = mod.default || mod let props = {} @@ -17,8 +20,7 @@ export async function render (path, req, res, { dir = process.cwd(), dev = false props = await Component.getInitialProps({ req, res }) } - const bundlePath = resolve(dir, '.next', '_bundles', 'pages', (path || 'index') + '.js') - const component = await fs.readFile(bundlePath, 'utf8') + const component = await read(resolve(dir, '.next', '_bundles', 'pages', path)) const { html, css } = StyleSheetServer.renderStatic(() => { const app = createElement(App, { @@ -45,7 +47,6 @@ export async function render (path, req, res, { dir = process.cwd(), dev = false } export async function renderJSON (path, { dir = process.cwd() }) { - const bundlePath = resolve(dir, '.next', '_bundles', 'pages', (path || 'index') + '.js') - const component = await fs.readFile(bundlePath, 'utf8') + const component = await read(resolve(dir, '.next', '_bundles', 'pages', path)) return { component } } diff --git a/server/resolve.js b/server/resolve.js new file mode 100644 index 0000000000..6b56fed086 --- /dev/null +++ b/server/resolve.js @@ -0,0 +1,15 @@ +import _resolve from 'resolve' + +export default function resolve (id, opts) { + return new Promise((resolve, reject) => { + _resolve(id, opts, (err, path) => { + if (err) { + const e = new Error(err) + e.code = 'ENOENT' + return reject(e) + } + resolve(path) + }) + }) +} +