Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WEB-1135: Update examples and schema for Turbopack loaders config change #54584

Merged
merged 4 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/02-app/02-api-reference/05-next-config-js/turbo.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ To configure loaders, add the names of the loaders you've installed and any opti
module.exports = {
experimental: {
turbo: {
loaders: {
rules: {
// Option format
'.md': [
'*.md': [
{
loader: '@mdx-js/loader',
options: {
Expand All @@ -29,7 +29,7 @@ module.exports = {
},
],
// Option-less format
'.mdx': ['@mdx-js/loader'],
'*.mdx': ['@mdx-js/loader'],
},
},
},
Expand Down
11 changes: 9 additions & 2 deletions examples/with-turbopack-loaders/next.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
module.exports = {
experimental: {
turbo: {
loaders: {
'.svg': ['@svgr/webpack'],
rules: {
'*.react.svg': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
'*.styl': {
loaders: ['stylus-loader'],
as: '*.css',
},
},
},
},
Expand Down
2 changes: 2 additions & 0 deletions examples/with-turbopack-loaders/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"@types/node": "^18.11.9",
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.9",
"stylus": "0.59.0",
"stylus-loader": "7.1.3",
"typescript": "^4.9.3"
}
}
3 changes: 2 additions & 1 deletion examples/with-turbopack-loaders/pages/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Vercel from '../vercel.svg'
import Vercel from '../vercel.react.svg'
import '../styles.styl'

export default function Home() {
return <Vercel />
Expand Down
2 changes: 2 additions & 0 deletions examples/with-turbopack-loaders/styles.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
body
background-color: blue
2 changes: 1 addition & 1 deletion packages/next-swc/crates/next-core/src/next_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ pub enum RemotePatternProtocal {
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, TraceRawVcs)]
#[serde(rename_all = "camelCase")]
pub struct ExperimentalTurboConfig {
/// This option has been replace by `rules`.
/// This option has been replaced by `rules`.
pub loaders: Option<JsonValue>,
pub rules: Option<IndexMap<String, RuleConfigItem>>,
pub resolve_alias: Option<IndexMap<String, JsonValue>>,
Expand Down
15 changes: 7 additions & 8 deletions packages/next/src/build/swc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { getParserOptions } from './options'
import { eventSwcLoadFailure } from '../../telemetry/events/swc-load-failure'
import { patchIncorrectLockfile } from '../../lib/patch-incorrect-lockfile'
import { downloadWasmSwc, downloadNativeNextSwc } from '../../lib/download-swc'
import { NextConfigComplete, TurboLoaderItem } from '../../server/config-shared'
import { NextConfigComplete, TurboRule } from '../../server/config-shared'
import { isDeepStrictEqual } from 'util'

const nextVersion = process.env.__NEXT_VERSION as string
Expand Down Expand Up @@ -948,10 +948,8 @@ function bindingToApi(binding: any, _wasm: boolean) {
nextConfigSerializable.exportPathMap = {}
nextConfigSerializable.webpack = nextConfig.webpack && {}

if (nextConfig.experimental?.turbo?.loaders) {
ensureLoadersHaveSerializableOptions(
nextConfig.experimental.turbo.loaders
)
if (nextConfig.experimental?.turbo?.rules) {
ensureLoadersHaveSerializableOptions(nextConfig.experimental.turbo?.rules)
}

nextConfigSerializable.modularizeImports =
Expand Down Expand Up @@ -979,16 +977,17 @@ function bindingToApi(binding: any, _wasm: boolean) {
}

function ensureLoadersHaveSerializableOptions(
turbopackLoaders: Record<string, TurboLoaderItem[]>
turbopackRules: Record<string, TurboRule>
) {
for (const [ext, loaderItems] of Object.entries(turbopackLoaders)) {
for (const [glob, rule] of Object.entries(turbopackRules)) {
const loaderItems = Array.isArray(rule) ? rule : rule.loaders
for (const loaderItem of loaderItems) {
if (
typeof loaderItem !== 'string' &&
!isDeepStrictEqual(loaderItem, JSON.parse(JSON.stringify(loaderItem)))
) {
throw new Error(
`loader ${loaderItem.loader} for match "${ext}" does not have serializable options. Ensure that options passed are plain JavaScript objects and values.`
`loader ${loaderItem.loader} for match "${glob}" does not have serializable options. Ensure that options passed are plain JavaScript objects and values.`
)
}
}
Expand Down
3 changes: 3 additions & 0 deletions packages/next/src/server/config-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,9 @@ const configSchema = {
loaders: {
type: 'object',
},
rules: {
type: 'object',
},
resolveAlias: {
type: 'object',
},
Expand Down
14 changes: 14 additions & 0 deletions packages/next/src/server/config-shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ export type TurboLoaderItem =
options: Record<string, JSONValue>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TurboLoaderItem can be removed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used in TurboRule below

}

export type TurboRule =
| TurboLoaderItem[]
| {
loaders: TurboLoaderItem[]
as: string
}

export interface ExperimentalTurboOptions {
/**
* (`next --turbo` only) A mapping of aliased imports to modules to load in their place.
Expand All @@ -110,6 +117,13 @@ export interface ExperimentalTurboOptions {
* @see [Turbopack Loaders](https://nextjs.org/docs/app/api-reference/next-config-js/turbo#webpack-loaders)
*/
loaders?: Record<string, TurboLoaderItem[]>

/**
* (`next --turbo` only) A list of webpack loaders to apply when running with Turbopack.
*
* @see [Turbopack Loaders](https://nextjs.org/docs/app/api-reference/next-config-js/turbo#webpack-loaders)
*/
rules?: Record<string, TurboRule>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to warn/gracefully handle previous naming so we don't just break the old config?

}

export interface WebpackConfigContext {
Expand Down
22 changes: 22 additions & 0 deletions packages/next/src/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
NextConfigComplete,
validateConfig,
NextConfig,
TurboLoaderItem,
} from './config-shared'
import { loadWebpackHook } from './config-utils'
import { ImageConfig, imageConfigDefault } from '../shared/lib/image-config'
Expand Down Expand Up @@ -852,6 +853,27 @@ export default async function loadConfig(
: canonicalBase) || ''
}

if (
userConfig.experimental?.turbo?.loaders &&
!userConfig.experimental?.turbo?.rules
) {
curLog.warn(
'experimental.turbo.loaders is now deprecated. Please update next.config.js to use experimental.turbo.rules as soon as possible.\n' +
'The new option is similar, but the key should be a glob instead of an extension.\n' +
'Example: loaders: { ".mdx": ["mdx-loader"] } -> rules: { "*.mdx": ["mdx-loader"] }" }\n' +
'See more info here https://nextjs.org/docs/app/api-reference/next-config-js/turbo'
)

const rules: Record<string, TurboLoaderItem[]> = {}
for (const [ext, loaders] of Object.entries(
userConfig.experimental.turbo.loaders
)) {
rules['*' + ext] = loaders as TurboLoaderItem[]
}

userConfig.experimental.turbo.rules = rules
}

onLoadUserConfig?.(userConfig)
const completeConfig = assignDefaults(
dir,
Expand Down