Skip to content

Commit

Permalink
Refactor next-flight-server-loader (#34902)
Browse files Browse the repository at this point in the history
  • Loading branch information
huozhi committed Mar 1, 2022
1 parent abed2f7 commit 7c1a51a
Showing 1 changed file with 25 additions and 28 deletions.
53 changes: 25 additions & 28 deletions packages/next/build/webpack/loaders/next-flight-server-loader.ts
Expand Up @@ -5,14 +5,20 @@ import { parse } from '../../swc'
import { getBaseSWCOptions } from '../../swc/options'
import { getRawPageExtensions } from '../../utils'

const getIsClientComponent =
const createClientComponentFilter =
(pageExtensions: string[]) => (importSource: string) => {
return new RegExp(`\\.client(\\.(${pageExtensions.join('|')}))?`).test(
importSource
const hasClientExtension = new RegExp(
`\\.client(\\.(${pageExtensions.join('|')}))?`
).test(importSource)
// Special cases for Next.js APIs that are considered as client components:
return (
hasClientExtension ||
isNextComponent(importSource) ||
isImageImport(importSource)
)
}

const getIsServerComponent =
const createServerComponentFilter =
(pageExtensions: string[]) => (importSource: string) => {
return new RegExp(`\\.server(\\.(${pageExtensions.join('|')}))?`).test(
importSource
Expand All @@ -25,7 +31,7 @@ function isNextComponent(importSource: string) {
)
}

export function isImageImport(importSource: string) {
function isImageImport(importSource: string) {
// TODO: share extension with next/image
// TODO: add other static assets, jpeg -> jpg
return ['jpg', 'jpeg', 'png', 'webp', 'avif'].some((imageExt) =>
Expand Down Expand Up @@ -57,7 +63,6 @@ async function parseImportsInfo({
})
const ast = await parse(source, { ...opts.jsc.parser, isModule: true })
const { body } = ast
const beginPos = ast.span.start
let transformedSource = ''
let lastIndex = 0
let defaultExportName
Expand All @@ -74,16 +79,18 @@ async function parseImportsInfo({

const importDeclarations = source.substring(
lastIndex,
node.source.span.start - beginPos
node.source.span.start
)

if (
!(
isClientComponent(importSource) ||
isNextComponent(importSource) ||
isImageImport(importSource)
)
) {
if (isClientComponent(importSource)) {
// A client component. It should be loaded as module reference.
transformedSource += importDeclarations
transformedSource += JSON.stringify(`${importSource}?__sc_client__`)
imports.push(`require(${JSON.stringify(importSource)})`)
} else {
// This is a special case to avoid the Duplicate React error.
// Since we already include React in the SSR runtime,
// here we can't create a new module with the ?__rsc_server__ query.
if (
['react/jsx-runtime', 'react/jsx-dev-runtime'].includes(
importSource
Expand All @@ -96,24 +103,14 @@ async function parseImportsInfo({
// component.
transformedSource += importDeclarations
transformedSource += JSON.stringify(`${importSource}?__sc_server__`)
} else {
// A client component. It should be loaded as module reference.
transformedSource += importDeclarations
transformedSource += JSON.stringify(`${importSource}?__sc_client__`)
imports.push(`require(${JSON.stringify(importSource)})`)
}
} else {
// For the client compilation, we skip all modules imports but
// always keep client components in the bundle. All client components
// have to be imported from either server or client components.
if (
!(
isClientComponent(importSource) ||
isServerComponent(importSource) ||
// Special cases for Next.js APIs that are considered as client
// components:
isNextComponent(importSource) ||
isImageImport(importSource)
isClientComponent(importSource) || isServerComponent(importSource)
)
) {
continue
Expand All @@ -122,7 +119,7 @@ async function parseImportsInfo({
imports.push(`require(${JSON.stringify(importSource)})`)
}

lastIndex = node.source.span.end - beginPos
lastIndex = node.source.span.end
break
}
case 'ExportDefaultDeclaration': {
Expand Down Expand Up @@ -170,8 +167,8 @@ export default async function transformSource(
}

const rawRawPageExtensions = getRawPageExtensions(pageExtensions)
const isServerComponent = getIsServerComponent(rawRawPageExtensions)
const isClientComponent = getIsClientComponent(rawRawPageExtensions)
const isServerComponent = createServerComponentFilter(rawRawPageExtensions)
const isClientComponent = createClientComponentFilter(rawRawPageExtensions)

if (!isClientCompilation) {
// We only apply the loader to server components, or shared components that
Expand Down

0 comments on commit 7c1a51a

Please sign in to comment.