Skip to content

Commit

Permalink
define rsc tag by loader
Browse files Browse the repository at this point in the history
  • Loading branch information
huozhi committed Jan 13, 2022
1 parent afd9a4e commit 282af9e
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 45 deletions.
4 changes: 2 additions & 2 deletions packages/next/build/entries.ts
Expand Up @@ -79,13 +79,13 @@ export function createPagesMapping(
// allow falling back to the correct source file so
// that HMR can work properly when a file is added/removed
const documentPage = `_document${hasConcurrentFeatures ? '-web' : ''}`
const appPage = `_app${hasServerComponents ? '-server' : ''}`
// const appPage = `_app${hasServerComponents ? '-server' : ''}`
if (isDev) {
pages['/_app'] = `${PAGES_DIR_ALIAS}/_app`
pages['/_error'] = `${PAGES_DIR_ALIAS}/_error`
pages['/_document'] = `${PAGES_DIR_ALIAS}/_document`
} else {
pages['/_app'] = pages['/_app'] || `next/dist/pages/${appPage}`
pages['/_app'] = pages['/_app'] || `next/dist/pages/_app`
pages['/_error'] = pages['/_error'] || 'next/dist/pages/_error'
pages['/_document'] =
pages['/_document'] || `next/dist/pages/${documentPage}`
Expand Down
5 changes: 4 additions & 1 deletion packages/next/build/webpack-config.ts
Expand Up @@ -546,7 +546,7 @@ export default async function getBaseWebpackConfig(
prev.push(path.join(pagesDir, `_app.${ext}`))
return prev
}, [] as string[]),
`next/dist/pages/_app${hasServerComponents ? '-server' : ''}.js`,
`next/dist/pages/_app.js`,
]
customAppAliases[`${PAGES_DIR_ALIAS}/_error`] = [
...config.pageExtensions.reduce((prev, ext) => {
Expand Down Expand Up @@ -953,6 +953,9 @@ export default async function getBaseWebpackConfig(
if (babelIncludeRegexes.some((r) => r.test(excludePath))) {
return false
}
if (/node_modules/.test(excludePath)) {
console.log('exclude', excludePath)
}
return /node_modules/.test(excludePath)
},
}
Expand Down
52 changes: 38 additions & 14 deletions packages/next/build/webpack/loaders/next-flight-server-loader.ts
Expand Up @@ -32,19 +32,23 @@ async function parseImportsInfo(
imports: Array<string>,
isClientCompilation: boolean,
pageExtensions: string[]
): Promise<string> {
): Promise<{
source: string
defaultExportName: string
}> {
const { body } = acorn.parse(source, {
ecmaVersion: 11,
sourceType: 'module',
}) as any

let transformedSource = ''
let lastIndex = 0
let defaultExportName = null

for (let i = 0; i < body.length; i++) {
const node = body[i]
switch (node.type) {
case 'ImportDeclaration':
case 'ImportDeclaration': {
const importSource = node.source.value

if (!isClientCompilation) {
Expand Down Expand Up @@ -83,6 +87,11 @@ async function parseImportsInfo(
lastIndex = node.source.end
imports.push(`require(${JSON.stringify(importSource)})`)
continue
}
case 'ExportDefaultDeclaration': {
defaultExportName = node.declaration.id.name
break
}
default:
break
}
Expand All @@ -92,7 +101,7 @@ async function parseImportsInfo(
transformedSource += source.substr(lastIndex)
}

return transformedSource
return { source: transformedSource, defaultExportName }
}

export default async function transformSource(
Expand All @@ -113,17 +122,32 @@ export default async function transformSource(
}

const imports: string[] = []
const transformed = await parseImportsInfo(
source,
imports,
isClientCompilation,
getRawPageExtensions(pageExtensions)
)

const noop = `\nexport const __rsc_noop__=()=>{${imports.join(';')}}`
const { source: transformedSource, defaultExportName } =
await parseImportsInfo(
source,
imports,
isClientCompilation,
getRawPageExtensions(pageExtensions)
)

/**
* Server side component module output:
*
* export default function ServerComponent() { ... }
* + export const __rsc_noop__=()=>{ ... }
* + ServerComponent.__next_rsc__=1;
*
* Client side component module output:
*
* The function body of ServerComponent will be removed
*/

const noop = `export const __rsc_noop__=()=>{${imports.join(';')}}`
const defaultExportNoop = isClientCompilation
? `\nexport default function Comp(){}\nComp.__next_rsc__=1`
: ''
? `export default function ${defaultExportName}(){}\n${defaultExportName}.__next_rsc__=1;`
: `${defaultExportName}.__next_rsc__=1;`

const transformed = transformedSource + '\n' + noop + '\n' + defaultExportNoop

return transformed + noop + defaultExportNoop
return transformed
}
2 changes: 1 addition & 1 deletion packages/next/client/index.tsx
Expand Up @@ -630,7 +630,7 @@ function AppContainer({
}

function renderApp(App: AppComponent, appProps: AppProps) {
if (process.env.__NEXT_RSC) {
if (process.env.__NEXT_RSC && (App as any).__next_rsc__) {
const { Component, err: _, router: __, ...props } = appProps
return <Component {...props} />
} else {
Expand Down
7 changes: 0 additions & 7 deletions packages/next/pages/_app-server.tsx

This file was deleted.

21 changes: 13 additions & 8 deletions packages/next/server/render.tsx
Expand Up @@ -188,7 +188,7 @@ function renderApp(
router: ServerRouter,
props: any
) {
if (process.env.__NEXT_RSC) {
if (process.env.__NEXT_RSC && (App as any).__next_rsc__) {
return <Component {...props.pageProps} router={router} />
} else {
return <App {...props} Component={Component} router={router} />
Expand Down Expand Up @@ -355,17 +355,20 @@ const useRSCResponse = createRSCHook()
function createServerComponentRenderer(
cachePrefix: string,
transformStream: TransformStream,
App: React.ComponentType,
App: AppType,
OriginalComponent: React.ComponentType,
serverComponentManifest: NonNullable<RenderOpts['serverComponentManifest']>
) {
const writable = transformStream.writable
const ServerComponentWrapper = (props: any) => {
const id = (React as any).useId()
const AppServer = (App as any).__next_rsc__
? (App as React.ComponentType)
: React.Fragment
const reqStream = renderToReadableStream(
<App>
<AppServer>
<OriginalComponent {...props} />
</App>,
</AppServer>,
serverComponentManifest
)

Expand Down Expand Up @@ -458,7 +461,7 @@ export async function renderToHTML(
? createServerComponentRenderer(
cachePrefix,
serverComponentsInlinedTransformStream!,
App as React.ComponentType,
App,
OriginalComponent,
serverComponentManifest
)
Expand Down Expand Up @@ -1095,11 +1098,13 @@ export async function renderToHTML(
if (isResSent(res) && !isSSG) return null

if (renderServerComponentData) {
const AppServerComponent = App as React.ComponentType
const AppServer = (App as any).__next_rsc__
? (App as React.ComponentType)
: React.Fragment
const stream: ReadableStream = renderToReadableStream(
<AppServerComponent>
<AppServer>
<OriginalComponent {...props.pageProps} {...serverComponentProps} />
</AppServerComponent>,
</AppServer>,
serverComponentManifest
)
const reader = stream.getReader()
Expand Down
14 changes: 7 additions & 7 deletions packages/next/taskfile.js
Expand Up @@ -1651,12 +1651,12 @@ export async function pages_app(task, opts) {
.target('dist/pages')
}

export async function pages_app_server(task, opts) {
await task
.source('pages/_app-server.tsx')
.swc('client', { dev: opts.dev })
.target('dist/pages')
}
// export async function pages_app_server(task, opts) {
// await task
// .source('pages/_app-server.tsx')
// .swc('client', { dev: opts.dev })
// .target('dist/pages')
// }

export async function pages_error(task, opts) {
await task
Expand Down Expand Up @@ -1686,7 +1686,7 @@ export async function pages(task, opts) {
'pages_error',
'pages_document',
'pages_document_server',
'pages_app_server',
// 'pages_app_server',
],
opts
)
Expand Down
@@ -1,3 +1,3 @@
export default function Container({ children }) {
return <div className="container.server">{children}</div>
return <div className="container-server">{children}</div>
}
Expand Up @@ -58,8 +58,8 @@ export default function App({children}) {
const appWithGlobalCss = `
import '../styles.css'
function App({ children }) {
return children
function App({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default App
Expand Down Expand Up @@ -188,8 +188,8 @@ const customAppPageSuite = {
it('should render container in app', async () => {
const indexHtml = await renderViaHTTP(context.appPort, '/')
const indexFlight = await renderViaHTTP(context.appPort, '/?__flight__=1')
expect(indexHtml).toContain('container.server')
expect(indexFlight).toContain('container.server')
expect(indexHtml).toContain('container-server')
expect(indexFlight).toContain('container-server')
})
},
before: () => appServerPage.write(rscAppPage),
Expand Down

0 comments on commit 282af9e

Please sign in to comment.