1
1
import path from 'path'
2
- import { RSC_CLIENT_ENTRY } from '../../../../shared/lib/constants'
3
- import { checkExports } from '../../../analysis/get-page-static-info'
2
+ import { RSC_MODULE_TYPES } from '../../../../shared/lib/constants'
3
+ import {
4
+ checkExports ,
5
+ getRSCModuleType ,
6
+ } from '../../../analysis/get-page-static-info'
4
7
import { parse } from '../../../swc'
5
8
6
9
function transformClient ( resourcePath : string ) : string {
@@ -31,50 +34,35 @@ const isPageOrLayoutFile = (filePath: string) => {
31
34
32
35
export default async function transformSource (
33
36
this : any ,
34
- source : string
35
- ) : Promise < string > {
37
+ source : string ,
38
+ sourceMap : any
39
+ ) {
36
40
if ( typeof source !== 'string' ) {
37
41
throw new Error ( 'Expected source to have been transformed to a string.' )
38
42
}
39
43
40
44
const { resourcePath } = this
45
+ const callback = this . async ( )
41
46
const buildInfo = ( this as any ) . _module . buildInfo
42
47
43
48
const swcAST = await parse ( source , {
44
49
filename : resourcePath ,
45
50
isModule : 'unknown' ,
46
51
} )
47
- const isModule = swcAST . type === 'Module'
48
- const { body } = swcAST
49
- // TODO-APP: optimize the directive detection
50
- // Assume there're only "use strict" and "<type>-entry" directives at top,
51
- // so pick the 2 nodes
52
- const firstTwoNodes = body . slice ( 0 , 2 )
53
- const appDir = path . join ( this . rootContext , 'app' )
54
- const isUnderAppDir = containsPath ( appDir , this . resourcePath )
55
52
53
+ const rscType = getRSCModuleType ( swcAST )
54
+
55
+ // Assign the RSC meta information to buildInfo.
56
+ buildInfo . rsc = { type : rscType }
57
+
58
+ const isModule = swcAST . type === 'Module'
56
59
const createError = ( name : string ) =>
57
60
new Error (
58
61
`${ name } is not supported in client components.\nFrom: ${ this . resourcePath } `
59
62
)
60
-
63
+ const appDir = path . join ( this . rootContext , 'app' )
64
+ const isUnderAppDir = containsPath ( appDir , this . resourcePath )
61
65
const isResourcePageOrLayoutFile = isPageOrLayoutFile ( this . resourcePath )
62
-
63
- // Assign the RSC meta information to buildInfo.
64
- buildInfo . rsc = { }
65
- for ( const node of firstTwoNodes ) {
66
- if (
67
- node . type === 'ExpressionStatement' &&
68
- node . expression . type === 'StringLiteral'
69
- ) {
70
- if ( node . expression . value === RSC_CLIENT_ENTRY ) {
71
- // Detect client entry
72
- buildInfo . rsc . type = RSC_CLIENT_ENTRY
73
- break
74
- }
75
- }
76
- }
77
-
78
66
// If client entry has any gSSP/gSP data fetching methods, error
79
67
function errorForInvalidDataFetching ( onError : ( error : any ) => void ) {
80
68
if ( isUnderAppDir && isResourcePageOrLayoutFile ) {
@@ -88,12 +76,12 @@ export default async function transformSource(
88
76
}
89
77
}
90
78
91
- if ( buildInfo . rsc . type === RSC_CLIENT_ENTRY ) {
79
+ if ( buildInfo . rsc . type === RSC_MODULE_TYPES . client ) {
92
80
errorForInvalidDataFetching ( this . emitError )
93
81
const code = transformClient ( this . resourcePath )
94
- return code
82
+ return callback ( null , code , sourceMap )
95
83
}
96
84
97
85
const code = transformServer ( source , isModule )
98
- return code
86
+ return callback ( null , code , sourceMap )
99
87
}
0 commit comments