Skip to content

Commit

Permalink
RSC: Refactor node-loader and some vite plugins (#10046)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobbe authored Feb 21, 2024
1 parent d012c60 commit a59205c
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 61 deletions.
98 changes: 46 additions & 52 deletions packages/vite/src/react-server-dom-webpack/node-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ function transformServerModule(
newSrc += '$$bound: { value: null }'
newSrc += '});\n'
})

return newSrc
}

Expand Down Expand Up @@ -272,7 +273,6 @@ function resolveClientImport(
// This resolution algorithm will not necessarily have the same configuration
// as the actual client loader. It should mostly work and if it doesn't you can
// always convert to explicit exported names instead.
const conditions = ['node', 'import']

if (stashedResolve === null) {
throw new Error(
Expand All @@ -283,14 +283,17 @@ function resolveClientImport(
return stashedResolve(
specifier,
{
conditions,
conditions: ['node', 'import'],
parentURL,
},
stashedResolve
)
}

async function parseExportNamesInto(
/**
* Parses `body` for exports and stores them in `names` (the second argument)
*/
async function parseExportNamesIntoNames(
body: any,
names: Array<string>,
parentURL: string,
Expand All @@ -305,31 +308,26 @@ async function parseExportNamesInto(
addExportNames(names, node.exported)
continue
} else {
const _await$resolveClientI = await resolveClientImport(
node.source.value,
parentURL
),
url = _await$resolveClientI.url

const _await$loader = await loader(
url,
{
format: 'module',
conditions: [],
importAssertions: {},
},
loader
),
source = _await$loader.source

if (typeof source !== 'string') {
const clientImport = await resolveClientImport(
node.source.value,
parentURL
)
const url = clientImport.url
const loadContext = {
format: 'module',
conditions: [],
importAssertions: {},
}
const mod = await loader(url, loadContext, loader)

if (typeof mod.source !== 'string') {
throw new Error('Expected the transformed source to be a string.')
}

let childBody

try {
childBody = acorn.parse(source, {
childBody = acorn.parse(mod.source, {
ecmaVersion: '2024',
sourceType: 'module',
}).body
Expand All @@ -338,7 +336,8 @@ async function parseExportNamesInto(
continue
}

await parseExportNamesInto(childBody, names, url, loader)
await parseExportNamesIntoNames(childBody, names, url, loader)

continue
}

Expand Down Expand Up @@ -378,7 +377,10 @@ async function transformClientModule(
loader: LoadFunction
): Promise<string> {
const names: Array<string> = []
await parseExportNamesInto(body, names, url, loader)

// This will insert the names into the `names` array
await parseExportNamesIntoNames(body, names, url, loader)

let newSrc =
"const CLIENT_REFERENCE = Symbol.for('react.client.reference');\n"

Expand Down Expand Up @@ -433,29 +435,27 @@ async function loadClientImport(
throw new Error(
'Expected getSource to have been called before transformSource'
)
} // TODO: Validate that this is another module by calling getFormat.
}

const _await$stashedGetSour = await stashedGetSource(
url,
{
format: 'module',
},
stashedGetSource
),
source = _await$stashedGetSour.source

const result = await defaultTransformSource(
source,
{
format: 'module',
url,
},
defaultTransformSource
// TODO: Validate that this is another module by calling getFormat.

const getSourceContext = { format: 'module' }
const { source } = await stashedGetSource(
url,
getSourceContext,
stashedGetSource
)
return {
const transformContext = {
format: 'module',
source: result.source,
url,
}
const { source: transformedSource } = await defaultTransformSource(
source,
transformContext,
defaultTransformSource
)

return { format: 'module', source: transformedSource }
}

async function transformModuleIfNeeded(
Expand All @@ -465,10 +465,7 @@ async function transformModuleIfNeeded(
): Promise<string> {
// Do a quick check for the exact string. If it doesn't exist, don't
// bother parsing.
if (
source.indexOf('use client') === -1 &&
source.indexOf('use server') === -1
) {
if (!source.includes('use client') && !source.includes('use server')) {
return source
}

Expand Down Expand Up @@ -545,9 +542,8 @@ export async function transformSource(
return loadClientImport(url, defaultTransformSource)
}
)
return {
source: newSrc,
}

return { source: newSrc }
}

return transformed
Expand Down Expand Up @@ -579,5 +575,3 @@ export async function load(

return result
}

// export { getSource, load, resolve, transformSource }
32 changes: 23 additions & 9 deletions packages/vite/src/rsc/rscVitePlugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@ export function rscIndexPlugin(): Plugin {
export function rscTransformPlugin(): Plugin {
return {
name: 'rsc-transform-plugin',
// TODO(RSC): Seems like resolveId() is never called. Can we remove it?
async resolveId(id, importer, options) {
console.log(
'rscVitePlugins - rscTransformPlugin::resolveId()',
id,
options
)
if (!id.endsWith('.js')) {
return id
}
Expand Down Expand Up @@ -80,8 +86,21 @@ export function rscTransformPlugin(): Plugin {
return { url }
}

const context = {
conditions: ['react-server'],
parentURL: '',
}

// Calling `resolve` here stashes the resolve function for use with
// `RSDWNodeLoader.load()` below
RSDWNodeLoader.resolve('', context, resolve)

const load = async (url: string) => {
let source = url === id ? code : (await this.load({ id: url })).code
let source: string | null = code

if (url !== id) {
source = (await this.load({ id: url })).code
}

if (!source) {
throw new Error(`Failed to load ${url}`)
Expand All @@ -92,18 +111,13 @@ export function rscTransformPlugin(): Plugin {
/^(import {.*?} from ".*?";)\s*"use (client|server)";/,
'"use $2";$1'
)

return { format: 'module', source }
}

RSDWNodeLoader.resolve(
'',
{ conditions: ['react-server'], parentURL: '' },
resolve
)

const source = (await RSDWNodeLoader.load(id, null, load)).source
const mod = await RSDWNodeLoader.load(id, null, load)

return source
return mod.source
},
}
}
Expand Down

0 comments on commit a59205c

Please sign in to comment.