mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
da3c3aded1
Fixes https://github.com/zeit/now-builders/issues/168 For some reason with a certain mix of deps `...` is not supported in webpack's parsing. By default it is supported as all our tests passed before and we have deployed Next.js apps on v2 already.
90 lines
2.8 KiB
TypeScript
90 lines
2.8 KiB
TypeScript
import {loader} from 'webpack'
|
|
import {join} from 'path'
|
|
import {parse} from 'querystring'
|
|
import { BUILD_MANIFEST, REACT_LOADABLE_MANIFEST } from 'next-server/constants'
|
|
|
|
export type ServerlessLoaderQuery = {
|
|
page: string,
|
|
distDir: string,
|
|
absolutePagePath: string,
|
|
absoluteAppPath: string,
|
|
absoluteDocumentPath: string,
|
|
absoluteErrorPath: string,
|
|
buildId: string,
|
|
assetPrefix: string,
|
|
generateEtags: string
|
|
}
|
|
|
|
const nextServerlessLoader: loader.Loader = function () {
|
|
const {
|
|
distDir,
|
|
absolutePagePath,
|
|
page,
|
|
buildId,
|
|
assetPrefix,
|
|
absoluteAppPath,
|
|
absoluteDocumentPath,
|
|
absoluteErrorPath,
|
|
generateEtags
|
|
}: ServerlessLoaderQuery = typeof this.query === 'string' ? parse(this.query.substr(1)) : this.query
|
|
const buildManifest = join(distDir, BUILD_MANIFEST).replace(/\\/g, '/')
|
|
const reactLoadableManifest = join(distDir, REACT_LOADABLE_MANIFEST).replace(/\\/g, '/')
|
|
return `
|
|
import {parse} from 'url'
|
|
import {renderToHTML} from 'next-server/dist/server/render';
|
|
import {sendHTML} from 'next-server/dist/server/send-html';
|
|
import buildManifest from '${buildManifest}';
|
|
import reactLoadableManifest from '${reactLoadableManifest}';
|
|
import Document from '${absoluteDocumentPath}';
|
|
import Error from '${absoluteErrorPath}';
|
|
import App from '${absoluteAppPath}';
|
|
import Component from '${absolutePagePath}';
|
|
async function renderReqToHTML(req, res) {
|
|
const options = {
|
|
App,
|
|
Document,
|
|
buildManifest,
|
|
reactLoadableManifest,
|
|
buildId: "${buildId}",
|
|
assetPrefix: "${assetPrefix}"
|
|
}
|
|
const parsedUrl = parse(req.url, true)
|
|
try {
|
|
${page === '/_error' ? `res.statusCode = 404` : ''}
|
|
const result = await renderToHTML(req, res, "${page}", parsedUrl.query, Object.assign({}, options, {
|
|
Component
|
|
}))
|
|
return result
|
|
} catch (err) {
|
|
if (err.code === 'ENOENT') {
|
|
res.statusCode = 404
|
|
const result = await renderToHTML(req, res, "/_error", parsedUrl.query, Object.assign({}, options, {
|
|
Component: Error
|
|
}))
|
|
return result
|
|
} else {
|
|
console.error(err)
|
|
res.statusCode = 500
|
|
const result = await renderToHTML(req, res, "/_error", parsedUrl.query, Object.assign({}, options, {
|
|
Component: Error,
|
|
err
|
|
}))
|
|
return result
|
|
}
|
|
}
|
|
}
|
|
export async function render (req, res) {
|
|
try {
|
|
const html = await renderReqToHTML(req, res)
|
|
sendHTML(req, res, html, {generateEtags: ${generateEtags}})
|
|
} catch(err) {
|
|
console.error(err)
|
|
res.statusCode = 500
|
|
res.end('Internal Server Error')
|
|
}
|
|
}
|
|
`
|
|
}
|
|
|
|
export default nextServerlessLoader
|