forked from vercel/next.js
/
version.ts
144 lines (133 loc) · 4.06 KB
/
version.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import findUp from 'next/dist/compiled/find-up'
import path from 'path'
import {
CONFIG_FILE,
PHASE_DEVELOPMENT_SERVER,
PHASE_EXPORT,
PHASE_PRODUCTION_BUILD,
} from '../../next-server/lib/constants'
import { normalizeConfig } from '../../next-server/server/config'
const EVENT_VERSION = 'NEXT_CLI_SESSION_STARTED'
type EventCliSessionStarted = {
nextVersion: string
nodeVersion: string
cliCommand: string
isSrcDir: boolean | null
hasNowJson: boolean
isCustomServer: boolean | null
hasNextConfig: boolean
buildTarget: string
hasWebpackConfig: boolean
hasBabelConfig: boolean
basePathEnabled: boolean
i18nEnabled: boolean
imageEnabled: boolean
locales: string | null
localeDomainsCount: number | null
localeDetectionEnabled: boolean | null
imageDomainsCount: number | null
imageSizes: string | null
imageLoader: string | null
trailingSlashEnabled: boolean
reactStrictMode: boolean
}
function hasBabelConfig(dir: string): boolean {
try {
const noopFile = path.join(dir, 'noop.js')
const res = require('@babel/core').loadPartialConfig({
cwd: dir,
filename: noopFile,
sourceFileName: noopFile,
}) as any
const isForTooling =
res.options?.presets?.every(
(e: any) => e?.file?.request === 'next/babel'
) && res.options?.plugins?.length === 0
return res.hasFilesystemConfig() && !isForTooling
} catch {
return false
}
}
type NextConfigurationPhase =
| typeof PHASE_DEVELOPMENT_SERVER
| typeof PHASE_PRODUCTION_BUILD
| typeof PHASE_EXPORT
function getNextConfig(
phase: NextConfigurationPhase,
dir: string
): { [key: string]: any } | null {
try {
const configurationPath = findUp.sync(CONFIG_FILE, {
cwd: dir,
})
if (configurationPath) {
// This should've already been loaded, and thus should be cached / won't
// be re-evaluated.
const configurationModule = require(configurationPath)
// Re-normalize the configuration.
return normalizeConfig(
phase,
configurationModule.default || configurationModule
)
}
} catch {
// ignored
}
return null
}
export function eventCliSession(
phase: NextConfigurationPhase,
dir: string,
event: Omit<
EventCliSessionStarted,
| 'nextVersion'
| 'nodeVersion'
| 'hasNextConfig'
| 'buildTarget'
| 'hasWebpackConfig'
| 'hasBabelConfig'
| 'basePathEnabled'
| 'i18nEnabled'
| 'imageEnabled'
| 'locales'
| 'localeDomainsCount'
| 'localeDetectionEnabled'
| 'imageDomainsCount'
| 'imageSizes'
| 'imageLoader'
| 'trailingSlashEnabled'
| 'reactStrictMode'
>
): { eventName: string; payload: EventCliSessionStarted }[] {
// This should be an invariant, if it fails our build tooling is broken.
if (typeof process.env.__NEXT_VERSION !== 'string') {
return []
}
const userConfiguration = getNextConfig(phase, dir)
const { images, experimental } = userConfiguration || {}
const { i18n } = experimental || {}
const payload: EventCliSessionStarted = {
nextVersion: process.env.__NEXT_VERSION,
nodeVersion: process.version,
cliCommand: event.cliCommand,
isSrcDir: event.isSrcDir,
hasNowJson: event.hasNowJson,
isCustomServer: event.isCustomServer,
hasNextConfig: !!userConfiguration,
buildTarget: userConfiguration?.target ?? 'default',
hasWebpackConfig: typeof userConfiguration?.webpack === 'function',
hasBabelConfig: hasBabelConfig(dir),
imageEnabled: !!images,
basePathEnabled: !!userConfiguration?.basePath,
i18nEnabled: !!i18n,
locales: i18n?.locales ? i18n.locales.join(',') : null,
localeDomainsCount: i18n?.domains ? i18n.domains.length : null,
localeDetectionEnabled: !i18n ? null : i18n.localeDetection !== false,
imageDomainsCount: images?.domains ? images.domains.length : null,
imageSizes: images?.sizes ? images.sizes.join(',') : null,
imageLoader: images?.loader,
trailingSlashEnabled: !!userConfiguration?.trailingSlash,
reactStrictMode: !!userConfiguration?.reactStrictMode,
}
return [{ eventName: EVENT_VERSION, payload }]
}