@@ -8,27 +8,32 @@ use markdown::{
8
8
mdast:: { AttributeValueExpression , Code , MdxjsEsm , Node , Text } ,
9
9
message:: { Message , Place } ,
10
10
unist:: Position ,
11
+ Location ,
11
12
} ;
12
13
use mdxjs:: {
13
- hast:: { AttributeContent , AttributeValue , MdxJsxAttribute , PropertyValue } ,
14
- hast_util_to_swc, mdast_util_from_mdx, mdast_util_to_hast, JsxRuntime , Options ,
14
+ hast:: { AttributeContent , AttributeValue , MdxJsxAttribute } ,
15
+ hast_util_to_swc, mdast_util_from_mdx, mdast_util_to_hast, mdx_plugin_recma_document,
16
+ mdx_plugin_recma_jsx_rewrite, Options ,
15
17
} ;
16
18
use parcel_macros:: { Evaluator , JsValue } ;
17
19
use swc_core:: {
20
+ alloc:: collections:: FxHashSet ,
18
21
common:: {
19
22
comments:: { Comments , SingleThreadedComments } ,
20
23
sync:: Lrc ,
21
24
SourceMap , DUMMY_SP ,
22
25
} ,
23
26
ecma:: {
24
27
ast:: {
25
- Decl , ExportDefaultExpr , ExportSpecifier , Expr , JSXElement , JSXElementName ,
26
- JSXOpeningElement , Module , ModuleDecl , ModuleItem , Stmt , VarDeclKind ,
28
+ CallExpr , Callee , Decl , ExportDefaultExpr , ExportSpecifier , Expr , ExprOrSpread , Ident ,
29
+ JSXAttrName , JSXAttrOrSpread , JSXAttrValue , JSXElement , JSXElementName , JSXExpr ,
30
+ JSXExprContainer , JSXOpeningElement , Lit , Module , ModuleDecl , ModuleItem , Stmt , VarDeclKind ,
27
31
} ,
28
32
atoms:: JsWord ,
29
33
codegen:: to_code,
30
34
parser:: { lexer:: Lexer , EsSyntax , Parser , StringInput , Syntax , TsSyntax } ,
31
35
utils:: for_each_binding_ident,
36
+ visit:: { VisitMut , VisitMutWith } ,
32
37
} ,
33
38
} ;
34
39
@@ -51,14 +56,7 @@ pub fn mdx(config: &Config) -> Result<MdxResult, Diagnostic> {
51
56
let mut options: Options = Options {
52
57
filepath : Some ( config. filename . clone ( ) ) ,
53
58
development : config. is_development ,
54
- jsx_import_source : config. jsx_import_source . clone ( ) ,
55
- jsx_runtime : Some ( if config. automatic_jsx_runtime {
56
- JsxRuntime :: Automatic
57
- } else {
58
- JsxRuntime :: Classic
59
- } ) ,
60
- pragma : config. jsx_pragma . clone ( ) ,
61
- pragma_frag : config. jsx_pragma_frag . clone ( ) ,
59
+ jsx : true ,
62
60
..Default :: default ( )
63
61
} ;
64
62
@@ -82,12 +80,17 @@ pub fn mdx(config: &Config) -> Result<MdxResult, Diagnostic> {
82
80
children. extend ( imports) ;
83
81
}
84
82
85
- let mut hast = mdast_util_to_hast ( & ast) ;
86
- collect_deps ( & mut hast ) ;
87
-
88
- let program = hast_util_to_swc ( & hast, code , & options ) ?;
83
+ let hast = mdast_util_to_hast ( & ast) ;
84
+ let location = Location :: new ( code . as_bytes ( ) ) ;
85
+ let mut explicit_jsxs = FxHashSet :: default ( ) ;
86
+ let mut program = hast_util_to_swc ( & hast, & options , Some ( & location ) , & mut explicit_jsxs ) ?;
89
87
let exports = constant_exports ( & program. module ) ;
90
88
89
+ program. module . visit_mut_with ( & mut DependencyVisitor ) ;
90
+
91
+ mdx_plugin_recma_document ( & mut program, & options, Some ( & location) ) ?;
92
+ mdx_plugin_recma_jsx_rewrite ( & mut program, & options, Some ( & location) , & explicit_jsxs) ?;
93
+
91
94
let comments = SingleThreadedComments :: default ( ) ;
92
95
for c in program. comments {
93
96
comments. add_leading ( c. span . lo , c. clone ( ) ) ;
@@ -153,52 +156,49 @@ fn text<'a>(node: &'a Node) -> Cow<'a, str> {
153
156
}
154
157
}
155
158
156
- fn collect_deps ( node : & mut mdxjs:: hast:: Node ) {
157
- use mdxjs:: hast:: Node ;
158
- match node {
159
- Node :: Element ( el) => {
160
- for ( prop, value) in & mut el. properties {
161
- if is_url ( & el. tag_name , prop) {
162
- if let PropertyValue :: String ( specifier) = value {
163
- * value = PropertyValue :: JsxExpression ( format ! (
164
- "__parcel_url_dep__({:?}, {})" ,
165
- specifier,
166
- el. tag_name == "a" || el. tag_name == "iframe"
167
- ) ) ;
168
- }
169
- }
170
- }
159
+ struct DependencyVisitor ;
171
160
172
- for child in & mut el. children {
173
- collect_deps ( child) ;
174
- }
175
- }
176
- Node :: MdxJsxElement ( el) => {
177
- if let Some ( name) = & el. name {
178
- for attr in & mut el. attributes {
179
- if let AttributeContent :: Property ( prop) = attr {
180
- if let Some ( AttributeValue :: Literal ( specifier) ) = & prop. value {
181
- if is_url ( name, & prop. name ) {
182
- prop. value = Some ( AttributeValue :: Expression ( AttributeValueExpression {
183
- value : format ! (
184
- "__parcel_url_dep__({:?}, {})" ,
185
- specifier,
186
- name == "a" || name == "iframe"
187
- ) ,
188
- stops : vec ! [ ] ,
189
- } ) ) ;
190
- }
191
- }
161
+ impl VisitMut for DependencyVisitor {
162
+ fn visit_mut_jsx_opening_element ( & mut self , node : & mut JSXOpeningElement ) {
163
+ node. visit_mut_children_with ( self ) ;
164
+
165
+ let element = match & node. name {
166
+ JSXElementName :: Ident ( id) => id. sym . as_str ( ) ,
167
+ _ => return ,
168
+ } ;
169
+
170
+ for prop in & mut node. attrs {
171
+ if let JSXAttrOrSpread :: JSXAttr ( prop) = prop {
172
+ if let ( JSXAttrName :: Ident ( name) , Some ( JSXAttrValue :: Lit ( specifier @ Lit :: Str ( _) ) ) ) =
173
+ ( & prop. name , & prop. value )
174
+ {
175
+ if is_url ( element, name. sym . as_str ( ) ) {
176
+ prop. value = Some ( JSXAttrValue :: JSXExprContainer ( JSXExprContainer {
177
+ expr : JSXExpr :: Expr ( Box :: new ( Expr :: Call ( CallExpr {
178
+ callee : Callee :: Expr ( Box :: new ( Expr :: Ident ( Ident :: new_no_ctxt (
179
+ "__parcel_url_dep__" . into ( ) ,
180
+ DUMMY_SP ,
181
+ ) ) ) ) ,
182
+ args : vec ! [
183
+ ExprOrSpread {
184
+ expr: Box :: new( Expr :: Lit ( specifier. clone( ) ) ) ,
185
+ spread: None ,
186
+ } ,
187
+ ExprOrSpread {
188
+ expr: Box :: new( Expr :: Lit ( Lit :: Bool (
189
+ ( element == "a" || element == "iframe" ) . into( ) ,
190
+ ) ) ) ,
191
+ spread: None ,
192
+ } ,
193
+ ] ,
194
+ ..Default :: default ( )
195
+ } ) ) ) ,
196
+ span : prop. span ,
197
+ } ) ) ;
192
198
}
193
199
}
194
200
}
195
201
}
196
- Node :: Root ( root) => {
197
- for child in & mut root. children {
198
- collect_deps ( child) ;
199
- }
200
- }
201
- _ => { }
202
202
}
203
203
}
204
204
0 commit comments