Convert Export to TypeScript (#8965)
This pull request converts Next.js' export CLI command to use TypeScript. This is useful for upcoming changes.
This commit is contained in:
parent
9af587930f
commit
d299811bfa
4 changed files with 63 additions and 53 deletions
|
@ -41,7 +41,7 @@ type AmpStatus = {
|
|||
code: string
|
||||
}
|
||||
|
||||
type AmpPageStatus = {
|
||||
export type AmpPageStatus = {
|
||||
[page: string]: { errors: AmpStatus[]; warnings: AmpStatus[] }
|
||||
}
|
||||
|
||||
|
|
5
packages/next/export/index.d.ts
vendored
5
packages/next/export/index.d.ts
vendored
|
@ -1,5 +0,0 @@
|
|||
export default function(
|
||||
dir: string,
|
||||
options: any,
|
||||
configuration?: any
|
||||
): Promise<void>
|
|
@ -1,36 +1,37 @@
|
|||
import { cpus } from 'os'
|
||||
import chalk from 'chalk'
|
||||
import { copyFile as copyFileOrig, existsSync, readFileSync } from 'fs'
|
||||
import Worker from 'jest-worker'
|
||||
import { promisify } from 'util'
|
||||
import mkdirpModule from 'mkdirp'
|
||||
import { resolve, join, dirname } from 'path'
|
||||
import { cpus } from 'os'
|
||||
import { dirname, join, resolve } from 'path'
|
||||
import { promisify } from 'util'
|
||||
|
||||
import { AmpPageStatus, formatAmpMessages } from '../build/output/index'
|
||||
import createSpinner from '../build/spinner'
|
||||
import { API_ROUTE } from '../lib/constants'
|
||||
import { existsSync, readFileSync, copyFile as copyFileOrig } from 'fs'
|
||||
import { recursiveCopy } from '../lib/recursive-copy'
|
||||
import { recursiveDelete } from '../lib/recursive-delete'
|
||||
import { formatAmpMessages } from '../build/output/index'
|
||||
import { setDistDir as setTelemetryDir } from '../telemetry/storage'
|
||||
import { recordVersion } from '../telemetry/events'
|
||||
import loadConfig, {
|
||||
isTargetLikeServerless
|
||||
} from '../next-server/server/config'
|
||||
import {
|
||||
PHASE_EXPORT,
|
||||
SERVER_DIRECTORY,
|
||||
PAGES_MANIFEST,
|
||||
CONFIG_FILE,
|
||||
BUILD_ID_FILE,
|
||||
PRERENDER_MANIFEST,
|
||||
SERVERLESS_DIRECTORY,
|
||||
CLIENT_PUBLIC_FILES_PATH,
|
||||
CLIENT_STATIC_FILES_PATH
|
||||
CLIENT_STATIC_FILES_PATH,
|
||||
CONFIG_FILE,
|
||||
PAGES_MANIFEST,
|
||||
PHASE_EXPORT,
|
||||
PRERENDER_MANIFEST,
|
||||
SERVER_DIRECTORY,
|
||||
SERVERLESS_DIRECTORY,
|
||||
} from '../next-server/lib/constants'
|
||||
import createSpinner from '../build/spinner'
|
||||
import loadConfig, {
|
||||
isTargetLikeServerless,
|
||||
} from '../next-server/server/config'
|
||||
import { recordVersion } from '../telemetry/events'
|
||||
import { setDistDir as setTelemetryDir } from '../telemetry/storage'
|
||||
|
||||
const mkdirp = promisify(mkdirpModule)
|
||||
const copyFile = promisify(copyFileOrig)
|
||||
|
||||
const createProgress = (total, label = 'Exporting') => {
|
||||
const createProgress = (total: number, label = 'Exporting') => {
|
||||
let curProgress = 0
|
||||
let progressSpinner = createSpinner(`${label} (${curProgress}/${total})`, {
|
||||
spinner: {
|
||||
|
@ -49,10 +50,10 @@ const createProgress = (total, label = 'Exporting') => {
|
|||
'[====]',
|
||||
'[=== ]',
|
||||
'[== ]',
|
||||
'[= ]'
|
||||
'[= ]',
|
||||
],
|
||||
interval: 80
|
||||
}
|
||||
interval: 80,
|
||||
},
|
||||
})
|
||||
|
||||
return () => {
|
||||
|
@ -72,9 +73,19 @@ const createProgress = (total, label = 'Exporting') => {
|
|||
}
|
||||
}
|
||||
|
||||
export default async function (dir, options, configuration) {
|
||||
function log (message) {
|
||||
if (options.silent) return
|
||||
type ExportPathMap = {
|
||||
[page: string]: { page: string; query?: { [key: string]: string } }
|
||||
}
|
||||
|
||||
export default async function(
|
||||
dir: string,
|
||||
options: any,
|
||||
configuration?: any
|
||||
): Promise<void> {
|
||||
function log(message: string) {
|
||||
if (options.silent) {
|
||||
return
|
||||
}
|
||||
console.log(message)
|
||||
}
|
||||
|
||||
|
@ -122,7 +133,7 @@ export default async function (dir, options, configuration) {
|
|||
)
|
||||
|
||||
const pages = options.pages || Object.keys(pagesManifest)
|
||||
const defaultPathMap = {}
|
||||
const defaultPathMap: ExportPathMap = {}
|
||||
|
||||
for (const page of pages) {
|
||||
// _document and _app are not real pages
|
||||
|
@ -165,7 +176,7 @@ export default async function (dir, options, configuration) {
|
|||
console.log(
|
||||
`> No "exportPathMap" found in "${CONFIG_FILE}". Generating map from "./pages"`
|
||||
)
|
||||
nextConfig.exportPathMap = async defaultMap => {
|
||||
nextConfig.exportPathMap = async (defaultMap: ExportPathMap) => {
|
||||
return defaultMap
|
||||
}
|
||||
}
|
||||
|
@ -181,18 +192,18 @@ export default async function (dir, options, configuration) {
|
|||
staticMarkup: false,
|
||||
hotReloader: null,
|
||||
canonicalBase: (nextConfig.amp && nextConfig.amp.canonicalBase) || '',
|
||||
isModern: nextConfig.experimental.modern
|
||||
isModern: nextConfig.experimental.modern,
|
||||
}
|
||||
|
||||
const { serverRuntimeConfig, publicRuntimeConfig } = nextConfig
|
||||
|
||||
if (Object.keys(publicRuntimeConfig).length > 0) {
|
||||
renderOpts.runtimeConfig = publicRuntimeConfig
|
||||
;(renderOpts as any).runtimeConfig = publicRuntimeConfig
|
||||
}
|
||||
|
||||
// We need this for server rendering the Link component.
|
||||
global.__NEXT_DATA__ = {
|
||||
nextExport: true
|
||||
;(global as any).__NEXT_DATA__ = {
|
||||
nextExport: true,
|
||||
}
|
||||
|
||||
log(` launching ${threads} workers`)
|
||||
|
@ -201,11 +212,11 @@ export default async function (dir, options, configuration) {
|
|||
dir,
|
||||
outDir,
|
||||
distDir,
|
||||
buildId
|
||||
buildId,
|
||||
})
|
||||
if (!exportPathMap['/404']) {
|
||||
exportPathMap['/404.html'] = exportPathMap['/404.html'] || {
|
||||
page: '/_error'
|
||||
page: '/_error',
|
||||
}
|
||||
}
|
||||
const exportPaths = Object.keys(exportPathMap)
|
||||
|
@ -227,7 +238,7 @@ export default async function (dir, options, configuration) {
|
|||
const progress = !options.silent && createProgress(filteredPaths.length)
|
||||
const sprDataDir = options.buildExport ? outDir : join(outDir, '_next/data')
|
||||
|
||||
const ampValidations = {}
|
||||
const ampValidations: AmpPageStatus = {}
|
||||
let hadValidationError = false
|
||||
|
||||
const publicDir = join(dir, CLIENT_PUBLIC_FILES_PATH)
|
||||
|
@ -240,19 +251,22 @@ export default async function (dir, options, configuration) {
|
|||
) {
|
||||
log(' copying "public" directory')
|
||||
await recursiveCopy(publicDir, outDir, {
|
||||
filter (path) {
|
||||
filter(path) {
|
||||
// Exclude paths used by pages
|
||||
return !exportPathMap[path]
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const worker = new Worker(require.resolve('./worker'), {
|
||||
maxRetries: 0,
|
||||
numWorkers: threads,
|
||||
enableWorkerThreads: true,
|
||||
exposedMethods: ['default']
|
||||
})
|
||||
const worker: Worker & { default: Function } = new Worker(
|
||||
require.resolve('./worker'),
|
||||
{
|
||||
maxRetries: 0,
|
||||
numWorkers: threads,
|
||||
enableWorkerThreads: true,
|
||||
exposedMethods: ['default'],
|
||||
}
|
||||
) as any
|
||||
|
||||
worker.getStdout().pipe(process.stdout)
|
||||
worker.getStderr().pipe(process.stderr)
|
||||
|
@ -272,16 +286,17 @@ export default async function (dir, options, configuration) {
|
|||
serverRuntimeConfig,
|
||||
subFolders,
|
||||
buildExport: options.buildExport,
|
||||
serverless: isTargetLikeServerless(nextConfig.target)
|
||||
serverless: isTargetLikeServerless(nextConfig.target),
|
||||
})
|
||||
|
||||
for (const validation of result.ampValidations || []) {
|
||||
const { page, result } = validation
|
||||
ampValidations[page] = result
|
||||
hadValidationError |=
|
||||
Array.isArray(result && result.errors) && result.errors.length > 0
|
||||
hadValidationError =
|
||||
hadValidationError ||
|
||||
(Array.isArray(result && result.errors) && result.errors.length > 0)
|
||||
}
|
||||
renderError |= result.error
|
||||
renderError = renderError || !!result.error
|
||||
|
||||
if (
|
||||
options.buildExport &&
|
|
@ -105,7 +105,7 @@ function normalizeConfig(phase: string, config: any) {
|
|||
export default function loadConfig(
|
||||
phase: string,
|
||||
dir: string,
|
||||
customConfig: any
|
||||
customConfig?: object | null
|
||||
) {
|
||||
if (customConfig) {
|
||||
return assignDefaults({ configOrigin: 'server', ...customConfig })
|
||||
|
|
Loading…
Reference in a new issue