rsnext/packages/next/build/load-jsconfig.ts
Tim Neutkens 0196b03621
Experimental next/jest config helper (#31246)
* Experimental next/jest config helper

Co-Authored-By: Maia Teegarden <dev@padmaia.rocks>

* Ensure useTypescript is provided

* Move experimental warning to next/jest

* Remove unused code

* Remove unused imports

Co-authored-by: Maia Teegarden <dev@padmaia.rocks>
2021-11-10 16:16:15 -08:00

84 lines
2.4 KiB
TypeScript

import path from 'path'
import { fileExists } from '../lib/file-exists'
import { NextConfigComplete } from '../server/config-shared'
import * as Log from './output/log'
import { getTypeScriptConfiguration } from '../lib/typescript/getTypeScriptConfiguration'
import { readFileSync } from 'fs'
import isError from '../lib/is-error'
import { codeFrameColumns } from 'next/dist/compiled/babel/code-frame'
let TSCONFIG_WARNED = false
function parseJsonFile(filePath: string) {
const JSON5 = require('next/dist/compiled/json5')
const contents = readFileSync(filePath, 'utf8')
// Special case an empty file
if (contents.trim() === '') {
return {}
}
try {
return JSON5.parse(contents)
} catch (err) {
if (!isError(err)) throw err
const codeFrame = codeFrameColumns(
String(contents),
{
start: {
line: (err as Error & { lineNumber?: number }).lineNumber || 0,
column: (err as Error & { columnNumber?: number }).columnNumber || 0,
},
},
{ message: err.message, highlightCode: true }
)
throw new Error(`Failed to parse "${filePath}":\n${codeFrame}`)
}
}
export default async function loadJsConfig(
dir: string,
config: NextConfigComplete
) {
let typeScriptPath: string | undefined
try {
typeScriptPath = require.resolve('typescript', { paths: [dir] })
} catch (_) {}
const tsConfigPath = path.join(dir, config.typescript.tsconfigPath)
const useTypeScript = Boolean(
typeScriptPath && (await fileExists(tsConfigPath))
)
let jsConfig
// jsconfig is a subset of tsconfig
if (useTypeScript) {
if (
config.typescript.tsconfigPath !== 'tsconfig.json' &&
TSCONFIG_WARNED === false
) {
TSCONFIG_WARNED = true
Log.info(`Using tsconfig file: ${config.typescript.tsconfigPath}`)
}
const ts = (await Promise.resolve(
require(typeScriptPath!)
)) as typeof import('typescript')
const tsConfig = await getTypeScriptConfiguration(ts, tsConfigPath, true)
jsConfig = { compilerOptions: tsConfig.options }
}
const jsConfigPath = path.join(dir, 'jsconfig.json')
if (!useTypeScript && (await fileExists(jsConfigPath))) {
jsConfig = parseJsonFile(jsConfigPath)
}
let resolvedBaseUrl
if (jsConfig?.compilerOptions?.baseUrl) {
resolvedBaseUrl = path.resolve(dir, jsConfig.compilerOptions.baseUrl)
}
return {
useTypeScript,
jsConfig,
resolvedBaseUrl,
}
}