rsnext/packages/next/build/webpack/loaders/next-serverless-loader/index.ts
Tim Neutkens 9316dc0a8e
Add default trace format that is exported automatically (#28461)
Co-authored-by: Steven <steven@ceriously.com>
2021-08-25 10:47:16 +02:00

209 lines
7.2 KiB
TypeScript

import devalue from 'next/dist/compiled/devalue'
import escapeRegexp from 'next/dist/compiled/escape-string-regexp'
import { join } from 'path'
import { parse } from 'querystring'
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { API_ROUTE } from '../../../../lib/constants'
import { isDynamicRoute } from '../../../../shared/lib/router/utils'
import { __ApiPreviewProps } from '../../../../server/api-utils'
import {
BUILD_MANIFEST,
ROUTES_MANIFEST,
REACT_LOADABLE_MANIFEST,
} from '../../../../shared/lib/constants'
export type ServerlessLoaderQuery = {
page: string
distDir: string
absolutePagePath: string
absoluteAppPath: string
absoluteDocumentPath: string
absoluteErrorPath: string
absolute404Path: string
buildId: string
assetPrefix: string
generateEtags: string
poweredByHeader: string
canonicalBase: string
basePath: string
runtimeConfig: string
previewProps: string
loadedEnvFiles: string
i18n: string
}
const nextServerlessLoader: webpack.loader.Loader = function () {
const {
distDir,
absolutePagePath,
page,
buildId,
canonicalBase,
assetPrefix,
absoluteAppPath,
absoluteDocumentPath,
absoluteErrorPath,
absolute404Path,
generateEtags,
poweredByHeader,
basePath,
runtimeConfig,
previewProps,
loadedEnvFiles,
i18n,
}: 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,
'/'
)
const routesManifest = join(distDir, ROUTES_MANIFEST).replace(/\\/g, '/')
const escapedBuildId = escapeRegexp(buildId)
const pageIsDynamicRoute = isDynamicRoute(page)
const encodedPreviewProps = devalue(
JSON.parse(previewProps) as __ApiPreviewProps
)
const envLoading = `
const { processEnv } = require('@next/env')
processEnv(${Buffer.from(loadedEnvFiles, 'base64').toString()})
`
const runtimeConfigImports = runtimeConfig
? `
const { setConfig } = require('next/config')
`
: ''
const runtimeConfigSetter = runtimeConfig
? `
const runtimeConfig = ${runtimeConfig}
setConfig(runtimeConfig)
`
: 'const runtimeConfig = {}'
if (page.match(API_ROUTE)) {
return `
${envLoading}
${runtimeConfigImports}
${
/*
this needs to be called first so its available for any other imports
*/
runtimeConfigSetter
}
import 'next/dist/server/node-polyfill-fetch'
import routesManifest from '${routesManifest}'
import { getApiHandler } from 'next/dist/build/webpack/loaders/next-serverless-loader/api-handler'
const combinedRewrites = Array.isArray(routesManifest.rewrites)
? routesManifest.rewrites
: []
if (!Array.isArray(routesManifest.rewrites)) {
combinedRewrites.push(...routesManifest.rewrites.beforeFiles)
combinedRewrites.push(...routesManifest.rewrites.afterFiles)
combinedRewrites.push(...routesManifest.rewrites.fallback)
}
const apiHandler = getApiHandler({
pageModule: require("${absolutePagePath}"),
rewrites: combinedRewrites,
i18n: ${i18n || 'undefined'},
page: "${page}",
basePath: "${basePath}",
pageIsDynamic: ${pageIsDynamicRoute},
encodedPreviewProps: ${encodedPreviewProps}
})
export default apiHandler
`
} else {
return `
import 'next/dist/server/node-polyfill-fetch'
import routesManifest from '${routesManifest}'
import buildManifest from '${buildManifest}'
import reactLoadableManifest from '${reactLoadableManifest}'
${envLoading}
${runtimeConfigImports}
${
// this needs to be called first so its available for any other imports
runtimeConfigSetter
}
import { getPageHandler } from 'next/dist/build/webpack/loaders/next-serverless-loader/page-handler'
const documentModule = require("${absoluteDocumentPath}")
const appMod = require('${absoluteAppPath}')
let App = appMod.default || appMod.then && appMod.then(mod => mod.default);
const compMod = require('${absolutePagePath}')
const Component = compMod.default || compMod.then && compMod.then(mod => mod.default)
export default Component
export const getStaticProps = compMod['getStaticProp' + 's'] || compMod.then && compMod.then(mod => mod['getStaticProp' + 's'])
export const getStaticPaths = compMod['getStaticPath' + 's'] || compMod.then && compMod.then(mod => mod['getStaticPath' + 's'])
export const getServerSideProps = compMod['getServerSideProp' + 's'] || compMod.then && compMod.then(mod => mod['getServerSideProp' + 's'])
// kept for detecting legacy exports
export const unstable_getStaticParams = compMod['unstable_getStaticParam' + 's'] || compMod.then && compMod.then(mod => mod['unstable_getStaticParam' + 's'])
export const unstable_getStaticProps = compMod['unstable_getStaticProp' + 's'] || compMod.then && compMod.then(mod => mod['unstable_getStaticProp' + 's'])
export const unstable_getStaticPaths = compMod['unstable_getStaticPath' + 's'] || compMod.then && compMod.then(mod => mod['unstable_getStaticPath' + 's'])
export const unstable_getServerProps = compMod['unstable_getServerProp' + 's'] || compMod.then && compMod.then(mod => mod['unstable_getServerProp' + 's'])
export let config = compMod['confi' + 'g'] || (compMod.then && compMod.then(mod => mod['confi' + 'g'])) || {}
export const _app = App
const combinedRewrites = Array.isArray(routesManifest.rewrites)
? routesManifest.rewrites
: []
if (!Array.isArray(routesManifest.rewrites)) {
combinedRewrites.push(...routesManifest.rewrites.beforeFiles)
combinedRewrites.push(...routesManifest.rewrites.afterFiles)
combinedRewrites.push(...routesManifest.rewrites.fallback)
}
const { renderReqToHTML, render } = getPageHandler({
pageModule: compMod,
pageComponent: Component,
pageConfig: config,
appModule: App,
documentModule: documentModule,
errorModule: require("${absoluteErrorPath}"),
notFoundModule: ${
absolute404Path ? `require("${absolute404Path}")` : undefined
},
pageGetStaticProps: getStaticProps,
pageGetStaticPaths: getStaticPaths,
pageGetServerSideProps: getServerSideProps,
assetPrefix: "${assetPrefix}",
canonicalBase: "${canonicalBase}",
generateEtags: ${generateEtags || 'false'},
poweredByHeader: ${poweredByHeader || 'false'},
runtimeConfig,
buildManifest,
reactLoadableManifest,
rewrites: combinedRewrites,
i18n: ${i18n || 'undefined'},
page: "${page}",
buildId: "${buildId}",
escapedBuildId: "${escapedBuildId}",
basePath: "${basePath}",
pageIsDynamic: ${pageIsDynamicRoute},
encodedPreviewProps: ${encodedPreviewProps}
})
export { renderReqToHTML, render }
`
}
}
export default nextServerlessLoader