render.js 1.7 KB
Newer Older
D
Dan Zajdband 已提交
1
import { resolve } from 'path'
N
nkzawa 已提交
2
import { parse } from 'url'
N
nkzawa 已提交
3 4
import { createElement } from 'react'
import { renderToString, renderToStaticMarkup } from 'react-dom/server'
N
nkzawa 已提交
5 6
import requireResolve from './resolve'
import read from './read'
N
nkzawa 已提交
7
import Router from '../lib/router'
N
nkzawa 已提交
8
import Document from '../lib/document'
N
nkzawa 已提交
9
import Head from '../lib/head'
N
nkzawa 已提交
10
import App from '../lib/app'
D
Dan Zajdband 已提交
11
import { StyleSheetServer } from '../lib/css'
N
nkzawa 已提交
12

N
nkzawa 已提交
13 14 15 16 17 18
export async function render (url, ctx = {}, {
  dir = process.cwd(),
  dev = false,
  staticMarkup = false
} = {}) {
  const path = getPath(url)
N
nkzawa 已提交
19 20
  const p = await requireResolve(resolve(dir, '.next', 'pages', path))
  const mod = require(p)
N
nkzawa 已提交
21
  const Component = mod.default || mod
N
nkzawa 已提交
22

23
  const props = await (Component.getInitialProps ? Component.getInitialProps(ctx) : {})
N
nkzawa 已提交
24
  const component = await read(resolve(dir, '.next', '_bundles', 'pages', path))
N
nkzawa 已提交
25

D
Dan Zajdband 已提交
26 27 28 29
  const { html, css } = StyleSheetServer.renderStatic(() => {
    const app = createElement(App, {
      Component,
      props,
N
nkzawa 已提交
30
      router: new Router(ctx.req ? ctx.req.url : url)
D
Dan Zajdband 已提交
31 32
    })

N
nkzawa 已提交
33
    return (staticMarkup ? renderToStaticMarkup : renderToString)(app)
N
nkzawa 已提交
34 35
  })

N
nkzawa 已提交
36 37
  const head = Head.rewind() || []

N
nkzawa 已提交
38
  const doc = createElement(Document, {
N
nkzawa 已提交
39 40 41
    html,
    head,
    css,
N
nkzawa 已提交
42 43 44 45 46
    data: {
      component,
      props,
      classNames: css.renderedClassNames
    },
N
nkzawa 已提交
47
    hotReload: false,
N
nkzawa 已提交
48 49
    dev,
    staticMarkup
N
nkzawa 已提交
50 51 52 53 54
  })

  return '<!DOCTYPE html>' + renderToStaticMarkup(doc)
}

N
nkzawa 已提交
55 56
export async function renderJSON (url, { dir = process.cwd() } = {}) {
  const path = getPath(url)
N
nkzawa 已提交
57
  const component = await read(resolve(dir, '.next', '_bundles', 'pages', path))
N
nkzawa 已提交
58
  return { component }
N
nkzawa 已提交
59
}
N
nkzawa 已提交
60 61 62 63

function getPath (url) {
  return parse(url || '/').pathname.slice(1).replace(/\.json$/, '')
}