@@ -13,29 +13,33 @@ use crate::specifiers::get_specifiers;
13
13
use crate :: specifiers:: Specifiers ;
14
14
use crate :: MappedSpecifier ;
15
15
16
- use anyhow:: anyhow;
17
16
use anyhow:: bail;
18
- use anyhow:: Context ;
19
17
use anyhow:: Result ;
20
18
use deno_ast:: ModuleSpecifier ;
19
+ use deno_ast:: ParseDiagnostic ;
21
20
use deno_ast:: ParsedSource ;
22
- use deno_error:: JsErrorBox ;
23
- use deno_graph:: source:: CacheSetting ;
24
- use deno_graph:: source:: ResolutionKind ;
25
- use deno_graph:: source:: ResolveError ;
21
+ use deno_config:: workspace:: WorkspaceDirectory ;
26
22
use deno_graph:: CapturingModuleAnalyzer ;
23
+ use deno_graph:: EsParser ;
24
+ use deno_graph:: JsModule ;
27
25
use deno_graph:: Module ;
26
+ use deno_graph:: ParseOptions ;
28
27
use deno_graph:: ParsedSourceStore ;
29
- use deno_graph:: Range ;
30
- use import_map:: ImportMapOptions ;
28
+ use deno_resolver:: factory:: WorkspaceFactorySys ;
29
+ use deno_resolver:: graph:: DefaultDenoResolverRc ;
30
+ use deno_resolver:: npm:: DenoInNpmPackageChecker ;
31
+ use deno_resolver:: workspace:: ScopedJsxImportSourceConfig ;
31
32
use sys_traits:: impls:: RealSys ;
32
33
33
- pub struct ModuleGraphOptions < ' a > {
34
+ pub struct ModuleGraphOptions < ' a , TSys : WorkspaceFactorySys > {
34
35
pub entry_points : Vec < ModuleSpecifier > ,
35
36
pub test_entry_points : Vec < ModuleSpecifier > ,
36
- pub loader : Option < Rc < dyn Loader > > ,
37
+ pub loader : Rc < dyn Loader > ,
38
+ pub resolver : DefaultDenoResolverRc < TSys > ,
37
39
pub specifier_mappings : & ' a HashMap < ModuleSpecifier , MappedSpecifier > ,
38
- pub import_map : Option < ModuleSpecifier > ,
40
+ pub cjs_tracker :
41
+ Rc < deno_resolver:: cjs:: CjsTracker < DenoInNpmPackageChecker , TSys > > ,
42
+ pub workspace_dir : Rc < WorkspaceDirectory > ,
39
43
}
40
44
41
45
/// Wrapper around deno_graph::ModuleGraph.
@@ -45,32 +49,26 @@ pub struct ModuleGraph {
45
49
}
46
50
47
51
impl ModuleGraph {
48
- pub async fn build_with_specifiers (
49
- options : ModuleGraphOptions < ' _ > ,
52
+ pub async fn build_with_specifiers < TSys : WorkspaceFactorySys > (
53
+ options : ModuleGraphOptions < ' _ , TSys > ,
50
54
) -> Result < ( Self , Specifiers ) > {
51
- let loader = options. loader . unwrap_or_else ( || {
52
- #[ cfg( feature = "tokio-loader" ) ]
53
- return Rc :: new ( crate :: loader:: DefaultLoader :: new ( ) ) ;
54
- #[ cfg( not( feature = "tokio-loader" ) ) ]
55
- panic ! ( "You must provide a loader or use the 'tokio-loader' feature." )
56
- } ) ;
57
- let resolver = match options. import_map {
58
- Some ( import_map_url) => Some (
59
- ImportMapResolver :: load ( & import_map_url, & * loader)
60
- . await
61
- . context ( "Error loading import map." ) ?,
62
- ) ,
63
- None => None ,
64
- } ;
55
+ let resolver = options. resolver ;
56
+ let loader = options. loader ;
65
57
let loader = SourceLoader :: new (
66
58
loader,
67
59
get_all_specifier_mappers ( ) ,
68
60
options. specifier_mappings ,
69
61
) ;
62
+ let scoped_jsx_import_source_config =
63
+ ScopedJsxImportSourceConfig :: from_workspace_dir ( & options. workspace_dir ) ?;
70
64
let source_parser = ScopeAnalysisParser ;
71
65
let capturing_analyzer =
72
66
CapturingModuleAnalyzer :: new ( Some ( Box :: new ( source_parser) ) , None ) ;
73
67
let mut graph = deno_graph:: ModuleGraph :: new ( deno_graph:: GraphKind :: All ) ;
68
+ let graph_resolver = resolver. as_graph_resolver (
69
+ & options. cjs_tracker ,
70
+ & scoped_jsx_import_source_config,
71
+ ) ;
74
72
graph
75
73
. build (
76
74
options
@@ -84,7 +82,7 @@ impl ModuleGraph {
84
82
is_dynamic : false ,
85
83
skip_dynamic_deps : false ,
86
84
imports : Default :: default ( ) ,
87
- resolver : resolver . as_ref ( ) . map ( |r| r . as_resolver ( ) ) ,
85
+ resolver : Some ( & graph_resolver ) ,
88
86
locker : None ,
89
87
module_analyzer : & capturing_analyzer,
90
88
reporter : None ,
@@ -181,17 +179,22 @@ impl ModuleGraph {
181
179
} )
182
180
}
183
181
184
- pub fn get_parsed_source ( & self , specifier : & ModuleSpecifier ) -> ParsedSource {
185
- let specifier = self . graph . resolve ( specifier) ;
186
- self
182
+ pub fn get_parsed_source (
183
+ & self ,
184
+ js_module : & JsModule ,
185
+ ) -> Result < ParsedSource , ParseDiagnostic > {
186
+ match self
187
187
. capturing_analyzer
188
- . get_parsed_source ( & specifier)
189
- . unwrap_or_else ( || {
190
- panic ! (
191
- "dnt bug - Did not find parsed source for specifier: {}" ,
192
- specifier
193
- ) ;
194
- } )
188
+ . get_parsed_source ( & js_module. specifier )
189
+ {
190
+ Some ( parsed_source) => Ok ( parsed_source) ,
191
+ None => self . capturing_analyzer . parse_program ( ParseOptions {
192
+ specifier : & js_module. specifier ,
193
+ source : js_module. source . clone ( ) ,
194
+ media_type : js_module. media_type ,
195
+ scope_analysis : false ,
196
+ } ) ,
197
+ }
195
198
}
196
199
197
200
pub fn resolve_dependency (
@@ -202,7 +205,7 @@ impl ModuleGraph {
202
205
self
203
206
. graph
204
207
. resolve_dependency ( value, referrer, /* prefer_types */ false )
205
- . map ( |url| url . clone ( ) )
208
+ . cloned ( )
206
209
. or_else ( || {
207
210
let value_lower = value. to_lowercase ( ) ;
208
211
if value_lower. starts_with ( "https://" )
@@ -236,58 +239,3 @@ fn format_specifiers_for_message(
236
239
. collect :: < Vec < _ > > ( )
237
240
. join ( "\n " )
238
241
}
239
-
240
- #[ derive( Debug ) ]
241
- struct ImportMapResolver ( import_map:: ImportMap ) ;
242
-
243
- impl ImportMapResolver {
244
- pub async fn load (
245
- import_map_url : & ModuleSpecifier ,
246
- loader : & dyn Loader ,
247
- ) -> Result < Self > {
248
- let response = loader
249
- . load ( import_map_url. clone ( ) , CacheSetting :: Use , None )
250
- . await ?
251
- . ok_or_else ( || anyhow ! ( "Could not find {}" , import_map_url) ) ?;
252
- let value = jsonc_parser:: parse_to_serde_value (
253
- & String :: from_utf8 ( response. content ) ?,
254
- & jsonc_parser:: ParseOptions {
255
- allow_comments : true ,
256
- allow_loose_object_property_names : true ,
257
- allow_trailing_commas : true ,
258
- } ,
259
- ) ?
260
- . unwrap_or_else ( || serde_json:: Value :: Object ( Default :: default ( ) ) ) ;
261
- let result = import_map:: parse_from_value_with_options (
262
- import_map_url. clone ( ) ,
263
- value,
264
- ImportMapOptions {
265
- address_hook : None ,
266
- expand_imports : true ,
267
- } ,
268
- ) ?;
269
- // if !result.diagnostics.is_empty() {
270
- // todo: surface diagnostics maybe? It seems like this should not be hard error according to import map spec
271
- // bail!("Import map diagnostics:\n{}", result.diagnostics.into_iter().map(|d| format!(" - {}", d)).collect::<Vec<_>>().join("\n"));
272
- //}
273
- Ok ( ImportMapResolver ( result. import_map ) )
274
- }
275
-
276
- pub fn as_resolver ( & self ) -> & dyn deno_graph:: source:: Resolver {
277
- self
278
- }
279
- }
280
-
281
- impl deno_graph:: source:: Resolver for ImportMapResolver {
282
- fn resolve (
283
- & self ,
284
- specifier : & str ,
285
- referrer_range : & Range ,
286
- _kind : ResolutionKind ,
287
- ) -> Result < ModuleSpecifier , ResolveError > {
288
- self
289
- . 0
290
- . resolve ( specifier, & referrer_range. specifier )
291
- . map_err ( |err| ResolveError :: Other ( JsErrorBox :: from_err ( err) ) )
292
- }
293
- }
0 commit comments