1
- import type { Plugin } from "vite" ;
2
- import dedent from "dedent" ;
3
-
4
1
import type { Babel , NodePath , ParseResult } from "./babel" ;
5
2
import { traverse , t } from "./babel" ;
6
- import * as VirtualModule from "./virtual-module" ;
7
-
8
- const vmod = VirtualModule . create ( "with-props" ) ;
9
-
10
- const NAMED_COMPONENT_EXPORTS = [ "HydrateFallback" , "ErrorBoundary" ] ;
11
-
12
- export const plugin : Plugin = {
13
- name : "react-router-with-props" ,
14
- enforce : "pre" ,
15
- resolveId ( id ) {
16
- if ( id === vmod . id ) return vmod . resolvedId ;
17
- } ,
18
- async load ( id ) {
19
- if ( id !== vmod . resolvedId ) return ;
20
-
21
- // Note: If you make changes to these implementations, please also update
22
- // the corresponding functions in packages/react-router/lib/dom/ssr/routes-test-stub.tsx
23
- return dedent `
24
- import { createElement as h } from "react";
25
- import { useActionData, useLoaderData, useMatches, useParams, useRouteError } from "react-router";
26
-
27
- export function withComponentProps(Component) {
28
- return function Wrapped() {
29
- const props = {
30
- params: useParams(),
31
- loaderData: useLoaderData(),
32
- actionData: useActionData(),
33
- matches: useMatches(),
34
- };
35
- return h(Component, props);
36
- };
37
- }
38
3
39
- export function withHydrateFallbackProps(HydrateFallback) {
40
- return function Wrapped() {
41
- const props = {
42
- params: useParams(),
43
- loaderData: useLoaderData(),
44
- actionData: useActionData(),
45
- };
46
- return h(HydrateFallback, props);
47
- };
48
- }
4
+ const namedComponentExports = [ "HydrateFallback" , "ErrorBoundary" ] as const ;
5
+ type NamedComponentExport = ( typeof namedComponentExports ) [ number ] ;
6
+ function isNamedComponentExport ( name : string ) : name is NamedComponentExport {
7
+ return namedComponentExports . includes ( name as NamedComponentExport ) ;
8
+ }
49
9
50
- export function withErrorBoundaryProps(ErrorBoundary) {
51
- return function Wrapped() {
52
- const props = {
53
- params: useParams(),
54
- loaderData: useLoaderData(),
55
- actionData: useActionData(),
56
- error: useRouteError(),
57
- };
58
- return h(ErrorBoundary, props);
59
- };
60
- }
61
- ` ;
62
- } ,
63
- } ;
10
+ type HocName =
11
+ | "UNSAFE_withComponentProps"
12
+ | "UNSAFE_withHydrateFallbackProps"
13
+ | "UNSAFE_withErrorBoundaryProps" ;
64
14
65
- export const transform = ( ast : ParseResult < Babel . File > ) => {
15
+ export const decorateComponentExportsWithProps = (
16
+ ast : ParseResult < Babel . File >
17
+ ) => {
66
18
const hocs : Array < [ string , Babel . Identifier ] > = [ ] ;
67
- function getHocUid ( path : NodePath , hocName : string ) {
19
+ function getHocUid ( path : NodePath , hocName : HocName ) {
68
20
const uid = path . scope . generateUidIdentifier ( hocName ) ;
69
21
hocs . push ( [ hocName , uid ] ) ;
70
22
return uid ;
@@ -80,7 +32,7 @@ export const transform = (ast: ParseResult<Babel.File>) => {
80
32
declaration . isFunctionDeclaration ( ) ? toFunctionExpression ( declaration . node ) :
81
33
undefined
82
34
if ( expr ) {
83
- const uid = getHocUid ( path , "withComponentProps " ) ;
35
+ const uid = getHocUid ( path , "UNSAFE_withComponentProps " ) ;
84
36
declaration . replaceWith ( t . callExpression ( uid , [ expr ] ) ) ;
85
37
}
86
38
return ;
@@ -97,9 +49,8 @@ export const transform = (ast: ParseResult<Babel.File>) => {
97
49
if ( ! expr ) return ;
98
50
if ( ! id . isIdentifier ( ) ) return ;
99
51
const { name } = id . node ;
100
- if ( ! NAMED_COMPONENT_EXPORTS . includes ( name ) ) return ;
101
-
102
- const uid = getHocUid ( path , `with${ name } Props` ) ;
52
+ if ( ! isNamedComponentExport ( name ) ) return ;
53
+ const uid = getHocUid ( path , `UNSAFE_with${ name } Props` ) ;
103
54
init . replaceWith ( t . callExpression ( uid , [ expr ] ) ) ;
104
55
} ) ;
105
56
return ;
@@ -109,9 +60,9 @@ export const transform = (ast: ParseResult<Babel.File>) => {
109
60
const { id } = decl . node ;
110
61
if ( ! id ) return ;
111
62
const { name } = id ;
112
- if ( ! NAMED_COMPONENT_EXPORTS . includes ( name ) ) return ;
63
+ if ( ! isNamedComponentExport ( name ) ) return ;
113
64
114
- const uid = getHocUid ( path , `with ${ name } Props` ) ;
65
+ const uid = getHocUid ( path , `UNSAFE_with ${ name } Props` ) ;
115
66
decl . replaceWith (
116
67
t . variableDeclaration ( "const" , [
117
68
t . variableDeclarator (
@@ -131,7 +82,7 @@ export const transform = (ast: ParseResult<Babel.File>) => {
131
82
hocs . map ( ( [ name , identifier ] ) =>
132
83
t . importSpecifier ( identifier , t . identifier ( name ) )
133
84
) ,
134
- t . stringLiteral ( vmod . id )
85
+ t . stringLiteral ( "react-router" )
135
86
)
136
87
) ;
137
88
}
0 commit comments