diff --git a/packages/next-server/package.json b/packages/next-server/package.json index 520adf9c..00b1872e 100644 --- a/packages/next-server/package.json +++ b/packages/next-server/package.json @@ -18,7 +18,8 @@ "scripts": { "build": "taskr", "release": "taskr release", - "prepublish": "npm run release" + "prepublish": "npm run release", + "typescript": "tsc --noEmit" }, "taskr": { "requires": [ diff --git a/packages/next-server/server/get-page-files.ts b/packages/next-server/server/get-page-files.ts new file mode 100644 index 00000000..ae2df6ce --- /dev/null +++ b/packages/next-server/server/get-page-files.ts @@ -0,0 +1,19 @@ +import {normalizePagePath} from './require' + +type BuildManifest = { + pages: { + [page: string]: string[] + } +} + +export function getPageFiles (buildManifest: BuildManifest, page: string): string[] { + const normalizedPage = normalizePagePath(page) + const files = buildManifest.pages[normalizedPage] + + if (!files) { + console.warn(`Could not find files for ${normalizedPage} in .next/build-manifest.json`) + return [] + } + + return files +} diff --git a/packages/next-server/server/render.js b/packages/next-server/server/render.js index 17a076e0..ef068cd2 100644 --- a/packages/next-server/server/render.js +++ b/packages/next-server/server/render.js @@ -3,7 +3,7 @@ import React from 'react' import { renderToString, renderToStaticMarkup } from 'react-dom/server' import generateETag from 'etag' import fresh from 'fresh' -import requirePage, {normalizePagePath} from './require' +import {requirePage} from './require' import Router from '../lib/router/router' import { loadGetInitialProps, isResSent } from '../lib/utils' import Head, { defaultHead } from '../lib/head' @@ -11,6 +11,7 @@ import Loadable from '../lib/loadable' import LoadableCapture from '../lib/loadable-capture' import { BUILD_MANIFEST, REACT_LOADABLE_MANIFEST, SERVER_DIRECTORY, CLIENT_STATIC_FILES_PATH } from 'next-server/constants' import {getDynamicImportBundles} from './get-dynamic-import-bundles' +import {getPageFiles} from './get-page-files' export function renderToHTML (req, res, pathname, query, opts) { return doRender(req, res, pathname, query, opts) @@ -21,18 +22,6 @@ export function renderErrorToHTML (err, req, res, _pathname, query, opts = {}) { return doRender(req, res, '/_error', query, { ...opts, err }) } -function getPageFiles (buildManifest, page) { - const normalizedPage = normalizePagePath(page) - const files = buildManifest.pages[normalizedPage] - - if (!files) { - console.warn(`Could not find files for ${normalizedPage} in .next/build-manifest.json`) - return [] - } - - return files -} - async function doRender (req, res, pathname, query, { err, buildId, @@ -48,7 +37,7 @@ async function doRender (req, res, pathname, query, { let [buildManifest, reactLoadableManifest, Component, Document, App] = await Promise.all([ require(join(distDir, BUILD_MANIFEST)), require(join(distDir, REACT_LOADABLE_MANIFEST)), - requirePage(pathname, {distDir}), + requirePage(pathname, distDir), require(documentPath), require(appPath) ]) diff --git a/packages/next-server/server/require.js b/packages/next-server/server/require.ts similarity index 72% rename from packages/next-server/server/require.js rename to packages/next-server/server/require.ts index d5643472..ab60f74e 100644 --- a/packages/next-server/server/require.js +++ b/packages/next-server/server/require.ts @@ -1,13 +1,13 @@ import {join, posix} from 'path' import {PAGES_MANIFEST, SERVER_DIRECTORY} from 'next-server/constants' -export function pageNotFoundError (page) { - const err = new Error(`Cannot find module for page: ${page}`) +export function pageNotFoundError (page: string): Error { + const err: any = new Error(`Cannot find module for page: ${page}`) err.code = 'ENOENT' return err } -export function normalizePagePath (page) { +export function normalizePagePath (page: string): string { // If the page is `/` we need to append `/index`, otherwise the returned directory root will be bundles instead of pages if (page === '/') { page = '/index' @@ -27,7 +27,7 @@ export function normalizePagePath (page) { return page } -export function getPagePath (page, {distDir}) { +export function getPagePath (page: string, distDir: string): string { const serverBuildPath = join(distDir, SERVER_DIRECTORY) const pagesManifest = require(join(serverBuildPath, PAGES_MANIFEST)) @@ -45,7 +45,7 @@ export function getPagePath (page, {distDir}) { return join(serverBuildPath, pagesManifest[page]) } -export default async function requirePage (page, {distDir}) { - const pagePath = getPagePath(page, {distDir}) +export async function requirePage (page: string, distDir: string): Promise { + const pagePath = getPagePath(page, distDir) return require(pagePath) } diff --git a/test/isolated/require-page.test.js b/test/isolated/require-page.test.js index f665144e..09430639 100644 --- a/test/isolated/require-page.test.js +++ b/test/isolated/require-page.test.js @@ -2,7 +2,7 @@ import { join } from 'path' import {SERVER_DIRECTORY, CLIENT_STATIC_FILES_PATH} from 'next-server/constants' -import requirePage, {getPagePath, normalizePagePath, pageNotFoundError} from 'next-server/dist/server/require' +import {requirePage, getPagePath, normalizePagePath, pageNotFoundError} from 'next-server/dist/server/require' const sep = '/' const distDir = join(__dirname, '_resolvedata') @@ -42,39 +42,39 @@ describe('normalizePagePath', () => { describe('getPagePath', () => { it('Should append /index to the / page', () => { - const pagePath = getPagePath('/', {distDir}) + const pagePath = getPagePath('/', distDir) expect(pagePath).toBe(join(pathToBundles, `${sep}index.js`)) }) it('Should prepend / when a page does not have it', () => { - const pagePath = getPagePath('_error', {distDir}) + const pagePath = getPagePath('_error', distDir) expect(pagePath).toBe(join(pathToBundles, `${sep}_error.js`)) }) it('Should throw with paths containing ../', () => { - expect(() => getPagePath('/../../package.json', {distDir})).toThrow() + expect(() => getPagePath('/../../package.json', distDir)).toThrow() }) }) describe('requirePage', () => { it('Should require /index.js when using /', async () => { - const page = await requirePage('/', {distDir}) + const page = await requirePage('/', distDir) expect(page.test).toBe('hello') }) it('Should require /index.js when using /index', async () => { - const page = await requirePage('/index', {distDir}) + const page = await requirePage('/index', distDir) expect(page.test).toBe('hello') }) it('Should require /world.js when using /world', async () => { - const page = await requirePage('/world', {distDir}) + const page = await requirePage('/world', distDir) expect(page.test).toBe('world') }) it('Should throw when using /../../test.js', async () => { try { - await requirePage('/../../test', {distDir}) + await requirePage('/../../test', distDir) } catch (err) { expect(err.code).toBe('ENOENT') } @@ -82,7 +82,7 @@ describe('requirePage', () => { it('Should throw when using non existent pages like /non-existent.js', async () => { try { - await requirePage('/non-existent', {distDir}) + await requirePage('/non-existent', distDir) } catch (err) { expect(err.code).toBe('ENOENT') } @@ -90,7 +90,7 @@ describe('requirePage', () => { it('Should bubble up errors in the child component', async () => { try { - await requirePage('/non-existent-child', {distDir}) + await requirePage('/non-existent-child', distDir) } catch (err) { expect(err.code).toBe('MODULE_NOT_FOUND') }