Skip to content

Commit

Permalink
Fix missing SWC transforms for optimized barrel files (#57474)
Browse files Browse the repository at this point in the history
With Barrel Optimization, we are trying to "shortcut" the import to be
directly pointing to the final target, as barrel files shouldn't have
any side effects. However, there could be `"use client"` and `"use
server"` directives which we can't ignore. Hence we must apply the
`serverComponents` transform of SWC to these barrel files too.

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
shuding and kodiakhq[bot] authored Oct 26, 2023
1 parent df0fb70 commit 3e34167
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 1 deletion.
6 changes: 6 additions & 0 deletions packages/next/src/build/webpack/loaders/next-barrel-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ import type webpack from 'webpack'

import path from 'path'
import { transform } from '../../swc'
import { WEBPACK_LAYERS } from '../../../lib/constants'

// This is a in-memory cache for the mapping of barrel exports. This only applies
// to the packages that we optimize. It will never change (e.g. upgrading packages)
Expand All @@ -103,6 +104,7 @@ const barrelTransformMappingCache = new Map<
>()

async function getBarrelMapping(
layer: string | null | undefined,
resourcePath: string,
swcCacheDir: string,
resolve: (context: string, request: string) => Promise<string>,
Expand Down Expand Up @@ -133,6 +135,9 @@ async function getBarrelMapping(
optimizeBarrelExports: {
wildcard: isWildcard,
},
serverComponents: {
isReactServerLayer: layer === WEBPACK_LAYERS.reactServerComponents,
},
jsc: {
parser: {
syntax: isTypeScript ? 'typescript' : 'ecmascript',
Expand Down Expand Up @@ -244,6 +249,7 @@ const NextBarrelLoader = async function (
})

const mapping = await getBarrelMapping(
this._module?.layer,
this.resourcePath,
swcCacheDir,
resolve,
Expand Down
5 changes: 5 additions & 0 deletions test/development/basic/barrel-optimization.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,9 @@ describe('optimizePackageImports', () => {
const html = await next.render('/client')
expect(html).toContain('this is a client component')
})

it('should support "use client" directive in barrel file', async () => {
const html = await next.render('/client-boundary')
expect(html).toContain('<button>0</button>')
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Button } from 'my-client-lib'

export default function Page() {
return <Button />
}
3 changes: 2 additions & 1 deletion test/development/basic/barrel-optimization/next.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = {
transpilePackages: ['my-client-lib'],
experimental: {
optimizePackageImports: ['my-lib', 'recursive-barrel'],
optimizePackageImports: ['my-lib', 'recursive-barrel', 'my-client-lib'],
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { useState } from 'react'

export function Button() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(count + 1)}>{count}</button>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use client'

export { Button } from './button'

0 comments on commit 3e34167

Please sign in to comment.