2021-11-11 01:16:15 +01:00
|
|
|
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'
|
2022-08-23 20:16:47 +02:00
|
|
|
import { hasNecessaryDependencies } from '../lib/has-necessary-dependencies'
|
2021-11-11 01:16:15 +01:00
|
|
|
|
|
|
|
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
|
2022-06-03 20:47:16 +02:00
|
|
|
const { codeFrameColumns } = require('next/dist/compiled/babel/code-frame')
|
2021-11-11 01:16:15 +01:00
|
|
|
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 {
|
2022-08-23 20:16:47 +02:00
|
|
|
const deps = await hasNecessaryDependencies(dir, [
|
|
|
|
{
|
|
|
|
pkg: 'typescript',
|
|
|
|
file: 'typescript/lib/typescript.js',
|
|
|
|
exportsRestrict: true,
|
|
|
|
},
|
|
|
|
])
|
|
|
|
typeScriptPath = deps.resolved.get('typescript')
|
2021-11-11 01:16:15 +01:00
|
|
|
} catch (_) {}
|
|
|
|
const tsConfigPath = path.join(dir, config.typescript.tsconfigPath)
|
|
|
|
const useTypeScript = Boolean(
|
|
|
|
typeScriptPath && (await fileExists(tsConfigPath))
|
|
|
|
)
|
|
|
|
|
2022-08-15 15:33:25 +02:00
|
|
|
let implicitBaseurl
|
2021-11-11 01:16:15 +01:00
|
|
|
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 }
|
2022-08-15 15:33:25 +02:00
|
|
|
implicitBaseurl = path.dirname(tsConfigPath)
|
2021-11-11 01:16:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const jsConfigPath = path.join(dir, 'jsconfig.json')
|
|
|
|
if (!useTypeScript && (await fileExists(jsConfigPath))) {
|
|
|
|
jsConfig = parseJsonFile(jsConfigPath)
|
2022-08-15 15:33:25 +02:00
|
|
|
implicitBaseurl = path.dirname(jsConfigPath)
|
2021-11-11 01:16:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
let resolvedBaseUrl
|
2022-08-15 15:33:25 +02:00
|
|
|
if (jsConfig) {
|
|
|
|
if (jsConfig.compilerOptions?.baseUrl) {
|
|
|
|
resolvedBaseUrl = path.resolve(dir, jsConfig.compilerOptions.baseUrl)
|
|
|
|
} else {
|
|
|
|
resolvedBaseUrl = implicitBaseurl
|
|
|
|
}
|
2021-11-11 01:16:15 +01:00
|
|
|
}
|
2022-08-15 15:33:25 +02:00
|
|
|
|
2021-11-11 01:16:15 +01:00
|
|
|
return {
|
|
|
|
useTypeScript,
|
|
|
|
jsConfig,
|
|
|
|
resolvedBaseUrl,
|
|
|
|
}
|
|
|
|
}
|