Skip to content

Commit

Permalink
Test fixes for Babel mode (#24312)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
timneutkens and divmain committed Apr 28, 2021
1 parent f3d5183 commit 53c19ff
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 28 deletions.
99 changes: 82 additions & 17 deletions packages/next/build/babel/loader/get-config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { readFileSync } from 'fs'

import { createConfigItem, loadOptions } from 'next/dist/compiled/babel/core'
import loadConfig from 'next/dist/compiled/babel/core-lib-config'

import nextBabelPreset from '../preset'
import { NextBabelLoaderOptions, NextJsLoaderContext } from './types'
import { consumeIterator } from './util'

Expand Down Expand Up @@ -31,8 +32,10 @@ interface CharacteristicsGermaneToCaching {
isPageFile: boolean
isNextDist: boolean
hasModuleExports: boolean
fileExt: string
}

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

return {
isServer,
isPageFile,
isNextDist,
hasModuleExports,
fileExt,
}
}

Expand Down Expand Up @@ -134,6 +139,46 @@ function getPlugins(
].filter(Boolean)
}

const isJsonFile = /\.(json|babelrc)$/
const isJsFile = /\.js$/

/**
* While this function does block execution while reading from disk, it
* should not introduce any issues. The function is only invoked when
* generating a fresh config, and only a small handful of configs should
* be generated during compilation.
*/
function getCustomBabelConfig(configFilePath: string) {
if (isJsonFile.exec(configFilePath)) {
const babelConfigRaw = readFileSync(configFilePath, 'utf8')
return JSON.parse(babelConfigRaw)
} else if (isJsFile.exec(configFilePath)) {
return require(configFilePath)
}
throw new Error(
'The Next Babel loader does not support MJS or CJS config files.'
)
}

function getCustomPresets(presets: any[], customConfig: any) {
presets = [...presets, ...customConfig?.presets]

const hasNextBabelPreset = (customConfig?.presets || [])
.filter((preset: any) => {
return (
preset === 'next/babel' ||
(Array.isArray(preset) && preset[0] === 'next/babel')
)
})
.reduce((memo: boolean, presetFound: boolean) => memo || presetFound, false)

if (!hasNextBabelPreset) {
presets.push('next/babel')
}

return presets
}

/**
* Generate a new, flat Babel config, ready to be handed to Babel-traverse.
* This config should have no unresolved overrides, presets, etc.
Expand All @@ -146,19 +191,28 @@ function getFreshConfig(
filename: string,
inputSourceMap?: object | null
) {
const {
let {
presets = [],
isServer,
pagesDir,
development,
hasReactRefresh,
hasJsxRuntime,
babelrc,
configFile,
} = loaderOptions
const nextPresetItem = createConfigItem(nextBabelPreset, { type: 'preset' })

let customPlugins = []
if (configFile) {
const customConfig = getCustomBabelConfig(configFile)
presets = getCustomPresets(presets, customConfig)
if (customConfig.plugins) {
customPlugins = customConfig.plugins
}
} else {
presets = [...presets, 'next/babel']
}

let options = {
babelrc,
babelrc: false,
cloneInputAst: false,
filename,
inputSourceMap: inputSourceMap || undefined,
Expand All @@ -167,17 +221,20 @@ function getFreshConfig(
// but allow users to override if they want.
sourceMaps:
loaderOptions.sourceMaps === undefined
? inputSourceMap
? this.sourceMap
: loaderOptions.sourceMaps,

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

plugins: getPlugins(loaderOptions, cacheCharacteristics),
plugins: [
...getPlugins(loaderOptions, cacheCharacteristics),
...customPlugins,
],

presets: [...presets, nextPresetItem],
presets,

overrides: loaderOptions.overrides,

Expand All @@ -197,8 +254,7 @@ function getFreshConfig(

isServer,
pagesDir,
development,
hasReactRefresh,
isDev: development,
hasJsxRuntime,

...loaderOptions.caller,
Expand Down Expand Up @@ -233,19 +289,21 @@ function getCacheKey(cacheCharacteristics: CharacteristicsGermaneToCaching) {
isPageFile,
isNextDist,
hasModuleExports,
fileExt,
} = cacheCharacteristics

return (
const flags =
0 |
(isServer ? 0b0001 : 0) |
(isPageFile ? 0b0010 : 0) |
(isNextDist ? 0b0100 : 0) |
(hasModuleExports ? 0b1000 : 0)
)

return fileExt + flags
}

type BabelConfig = any
const configCache: Map<number, BabelConfig> = new Map()
const configCache: Map<any, BabelConfig> = new Map()

export default function getConfig(
this: NextJsLoaderContext,
Expand All @@ -271,10 +329,17 @@ export default function getConfig(

const cacheKey = getCacheKey(cacheCharacteristics)
if (configCache.has(cacheKey)) {
const cachedConfig = configCache.get(cacheKey)

return {
...configCache.get(cacheKey),
filename,
sourceFileName: filename,
...cachedConfig,
options: {
...cachedConfig.options,
cwd: loaderOptions.cwd,
root: loaderOptions.cwd,
filename,
sourceFileName: filename,
},
}
}

Expand Down
4 changes: 0 additions & 4 deletions packages/next/build/babel/loader/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { inspect } from 'util'
import { getOptions } from 'next/dist/compiled/loader-utils'
import { trace } from '../../../telemetry/trace'
import { Span } from '../../../telemetry/trace'
Expand Down Expand Up @@ -52,9 +51,6 @@ const nextBabelLoaderOuter = function nextBabelLoaderOuter(
([transformedSource, outputSourceMap]) =>
callback?.(null, transformedSource, outputSourceMap || inputSourceMap),
(err) => {
console.error(
`Problem encountered in next-babel-turbo-loader. \n${inspect(err)}`
)
callback?.(err)
}
)
Expand Down
3 changes: 2 additions & 1 deletion packages/next/build/babel/loader/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ export interface NextBabelLoaderOptions {
sourceMaps?: any[]
overrides: any
caller: any
babelrc: boolean
configFile: string | undefined
cwd: string
}
14 changes: 9 additions & 5 deletions packages/next/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ export default async function getBaseWebpackConfig(
// fixed in rc.1.
semver.gte(reactVersion!, '17.0.0-rc.1')

const babelrc = await [
const babelConfigFile = await [
'.babelrc',
'.babelrc.json',
'.babelrc.js',
Expand All @@ -219,9 +219,13 @@ export default async function getBaseWebpackConfig(
'babel.config.json',
'babel.config.mjs',
'babel.config.cjs',
].reduce(async (memo: boolean | Promise<boolean>, filename) => {
return (await memo) || (await fileExists(path.join(dir, filename)))
}, false)
].reduce(async (memo: Promise<string | undefined>, filename) => {
const configFilePath = path.join(dir, filename)
return (
(await memo) ||
((await fileExists(configFilePath)) ? configFilePath : undefined)
)
}, Promise.resolve(undefined))

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

Expand All @@ -232,7 +236,7 @@ export default async function getBaseWebpackConfig(
babel: {
loader: babelLoader,
options: {
babelrc,
configFile: babelConfigFile,
isServer,
distDir,
pagesDir,
Expand Down
2 changes: 1 addition & 1 deletion test/integration/config-devtool-dev/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jest.setTimeout(1000 * 30)

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

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

Expand Down

0 comments on commit 53c19ff

Please sign in to comment.