Skip to content

Commit 53c19ff

Browse files
timneutkensdivmain
andauthoredApr 28, 2021
Test fixes for Babel mode (#24312)
* Try enabling Babel turbo mode * Pass config file explicitly to babel turbo loader. * Update NextBabelLoaderOptions to use `configFile` instead of `babelrc`. * Re-add support for options passed to next/babel preset with new babel loader. * Load babel config files depending on their file extension. * Include `next/babel` if no Babel config is provided. * Minor cleanup. * Avoid duplicate `next/babel` entries. * No need to pass configFile anymore. * Fix multiple small issues in merging loader opts with cached config. * Remove redundant logging (that also breaks a test). * Include file extension CharacteristicsGermaneToCaching. * bump * Disable turboMode now that tests pass Co-authored-by: Dale Bustad <dale@divmain.com>
1 parent f3d5183 commit 53c19ff

File tree

5 files changed

+94
-28
lines changed

5 files changed

+94
-28
lines changed
 

‎packages/next/build/babel/loader/get-config.ts

+82-17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
import { readFileSync } from 'fs'
2+
13
import { createConfigItem, loadOptions } from 'next/dist/compiled/babel/core'
24
import loadConfig from 'next/dist/compiled/babel/core-lib-config'
35

4-
import nextBabelPreset from '../preset'
56
import { NextBabelLoaderOptions, NextJsLoaderContext } from './types'
67
import { consumeIterator } from './util'
78

@@ -31,8 +32,10 @@ interface CharacteristicsGermaneToCaching {
3132
isPageFile: boolean
3233
isNextDist: boolean
3334
hasModuleExports: boolean
35+
fileExt: string
3436
}
3537

38+
const fileExtensionRegex = /\.([a-z]+)$/
3639
function getCacheCharacteristics(
3740
loaderOptions: NextBabelLoaderOptions,
3841
source: string,
@@ -42,12 +45,14 @@ function getCacheCharacteristics(
4245
const isPageFile = filename.startsWith(pagesDir)
4346
const isNextDist = nextDistPath.test(filename)
4447
const hasModuleExports = source.indexOf('module.exports') !== -1
48+
const fileExt = fileExtensionRegex.exec(filename)?.[1] || 'unknown'
4549

4650
return {
4751
isServer,
4852
isPageFile,
4953
isNextDist,
5054
hasModuleExports,
55+
fileExt,
5156
}
5257
}
5358

@@ -134,6 +139,46 @@ function getPlugins(
134139
].filter(Boolean)
135140
}
136141

142+
const isJsonFile = /\.(json|babelrc)$/
143+
const isJsFile = /\.js$/
144+
145+
/**
146+
* While this function does block execution while reading from disk, it
147+
* should not introduce any issues. The function is only invoked when
148+
* generating a fresh config, and only a small handful of configs should
149+
* be generated during compilation.
150+
*/
151+
function getCustomBabelConfig(configFilePath: string) {
152+
if (isJsonFile.exec(configFilePath)) {
153+
const babelConfigRaw = readFileSync(configFilePath, 'utf8')
154+
return JSON.parse(babelConfigRaw)
155+
} else if (isJsFile.exec(configFilePath)) {
156+
return require(configFilePath)
157+
}
158+
throw new Error(
159+
'The Next Babel loader does not support MJS or CJS config files.'
160+
)
161+
}
162+
163+
function getCustomPresets(presets: any[], customConfig: any) {
164+
presets = [...presets, ...customConfig?.presets]
165+
166+
const hasNextBabelPreset = (customConfig?.presets || [])
167+
.filter((preset: any) => {
168+
return (
169+
preset === 'next/babel' ||
170+
(Array.isArray(preset) && preset[0] === 'next/babel')
171+
)
172+
})
173+
.reduce((memo: boolean, presetFound: boolean) => memo || presetFound, false)
174+
175+
if (!hasNextBabelPreset) {
176+
presets.push('next/babel')
177+
}
178+
179+
return presets
180+
}
181+
137182
/**
138183
* Generate a new, flat Babel config, ready to be handed to Babel-traverse.
139184
* This config should have no unresolved overrides, presets, etc.
@@ -146,19 +191,28 @@ function getFreshConfig(
146191
filename: string,
147192
inputSourceMap?: object | null
148193
) {
149-
const {
194+
let {
150195
presets = [],
151196
isServer,
152197
pagesDir,
153198
development,
154-
hasReactRefresh,
155199
hasJsxRuntime,
156-
babelrc,
200+
configFile,
157201
} = loaderOptions
158-
const nextPresetItem = createConfigItem(nextBabelPreset, { type: 'preset' })
202+
203+
let customPlugins = []
204+
if (configFile) {
205+
const customConfig = getCustomBabelConfig(configFile)
206+
presets = getCustomPresets(presets, customConfig)
207+
if (customConfig.plugins) {
208+
customPlugins = customConfig.plugins
209+
}
210+
} else {
211+
presets = [...presets, 'next/babel']
212+
}
159213

160214
let options = {
161-
babelrc,
215+
babelrc: false,
162216
cloneInputAst: false,
163217
filename,
164218
inputSourceMap: inputSourceMap || undefined,
@@ -167,17 +221,20 @@ function getFreshConfig(
167221
// but allow users to override if they want.
168222
sourceMaps:
169223
loaderOptions.sourceMaps === undefined
170-
? inputSourceMap
224+
? this.sourceMap
171225
: loaderOptions.sourceMaps,
172226

173227
// Ensure that Webpack will get a full absolute path in the sourcemap
174228
// so that it can properly map the module back to its internal cached
175229
// modules.
176230
sourceFileName: filename,
177231

178-
plugins: getPlugins(loaderOptions, cacheCharacteristics),
232+
plugins: [
233+
...getPlugins(loaderOptions, cacheCharacteristics),
234+
...customPlugins,
235+
],
179236

180-
presets: [...presets, nextPresetItem],
237+
presets,
181238

182239
overrides: loaderOptions.overrides,
183240

@@ -197,8 +254,7 @@ function getFreshConfig(
197254

198255
isServer,
199256
pagesDir,
200-
development,
201-
hasReactRefresh,
257+
isDev: development,
202258
hasJsxRuntime,
203259

204260
...loaderOptions.caller,
@@ -233,19 +289,21 @@ function getCacheKey(cacheCharacteristics: CharacteristicsGermaneToCaching) {
233289
isPageFile,
234290
isNextDist,
235291
hasModuleExports,
292+
fileExt,
236293
} = cacheCharacteristics
237294

238-
return (
295+
const flags =
239296
0 |
240297
(isServer ? 0b0001 : 0) |
241298
(isPageFile ? 0b0010 : 0) |
242299
(isNextDist ? 0b0100 : 0) |
243300
(hasModuleExports ? 0b1000 : 0)
244-
)
301+
302+
return fileExt + flags
245303
}
246304

247305
type BabelConfig = any
248-
const configCache: Map<number, BabelConfig> = new Map()
306+
const configCache: Map<any, BabelConfig> = new Map()
249307

250308
export default function getConfig(
251309
this: NextJsLoaderContext,
@@ -271,10 +329,17 @@ export default function getConfig(
271329

272330
const cacheKey = getCacheKey(cacheCharacteristics)
273331
if (configCache.has(cacheKey)) {
332+
const cachedConfig = configCache.get(cacheKey)
333+
274334
return {
275-
...configCache.get(cacheKey),
276-
filename,
277-
sourceFileName: filename,
335+
...cachedConfig,
336+
options: {
337+
...cachedConfig.options,
338+
cwd: loaderOptions.cwd,
339+
root: loaderOptions.cwd,
340+
filename,
341+
sourceFileName: filename,
342+
},
278343
}
279344
}
280345

‎packages/next/build/babel/loader/index.ts

-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { inspect } from 'util'
21
import { getOptions } from 'next/dist/compiled/loader-utils'
32
import { trace } from '../../../telemetry/trace'
43
import { Span } from '../../../telemetry/trace'
@@ -52,9 +51,6 @@ const nextBabelLoaderOuter = function nextBabelLoaderOuter(
5251
([transformedSource, outputSourceMap]) =>
5352
callback?.(null, transformedSource, outputSourceMap || inputSourceMap),
5453
(err) => {
55-
console.error(
56-
`Problem encountered in next-babel-turbo-loader. \n${inspect(err)}`
57-
)
5854
callback?.(err)
5955
}
6056
)

‎packages/next/build/babel/loader/types.d.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ export interface NextBabelLoaderOptions {
1515
sourceMaps?: any[]
1616
overrides: any
1717
caller: any
18-
babelrc: boolean
18+
configFile: string | undefined
19+
cwd: string
1920
}

‎packages/next/build/webpack-config.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ export default async function getBaseWebpackConfig(
209209
// fixed in rc.1.
210210
semver.gte(reactVersion!, '17.0.0-rc.1')
211211

212-
const babelrc = await [
212+
const babelConfigFile = await [
213213
'.babelrc',
214214
'.babelrc.json',
215215
'.babelrc.js',
@@ -219,9 +219,13 @@ export default async function getBaseWebpackConfig(
219219
'babel.config.json',
220220
'babel.config.mjs',
221221
'babel.config.cjs',
222-
].reduce(async (memo: boolean | Promise<boolean>, filename) => {
223-
return (await memo) || (await fileExists(path.join(dir, filename)))
224-
}, false)
222+
].reduce(async (memo: Promise<string | undefined>, filename) => {
223+
const configFilePath = path.join(dir, filename)
224+
return (
225+
(await memo) ||
226+
((await fileExists(configFilePath)) ? configFilePath : undefined)
227+
)
228+
}, Promise.resolve(undefined))
225229

226230
const distDir = path.join(dir, config.distDir)
227231

@@ -232,7 +236,7 @@ export default async function getBaseWebpackConfig(
232236
babel: {
233237
loader: babelLoader,
234238
options: {
235-
babelrc,
239+
configFile: babelConfigFile,
236240
isServer,
237241
distDir,
238242
pagesDir,

‎test/integration/config-devtool-dev/test/index.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jest.setTimeout(1000 * 30)
1515

1616
const appDir = join(__dirname, '../')
1717

18-
describe('devtool set in developmemt mode in next config', () => {
18+
describe('devtool set in development mode in next config', () => {
1919
it('should warn and revert when a devtool is set in development mode', async () => {
2020
let stderr = ''
2121

0 commit comments

Comments
 (0)
Please sign in to comment.