1- use std:: { env, path:: PathBuf } ;
1+ use std:: {
2+ env, fs,
3+ io:: { self , Write } ,
4+ path:: { Path , PathBuf } ,
5+ } ;
26
37use criterion:: { criterion_group, criterion_main, BenchmarkId , Criterion } ;
48use rayon:: prelude:: * ;
@@ -53,12 +57,47 @@ fn data() -> Vec<(PathBuf, &'static str)> {
5357 ]
5458}
5559
60+ fn symlink < P : AsRef < Path > , Q : AsRef < Path > > ( original : P , link : Q ) -> io:: Result < ( ) > {
61+ #[ cfg( target_family = "unix" ) ]
62+ {
63+ std:: os:: unix:: fs:: symlink ( original, link)
64+ }
65+
66+ #[ cfg( target_family = "windows" ) ]
67+ {
68+ std:: os:: windows:: fs:: symlink_file ( original, link)
69+ }
70+ }
71+
72+ fn create_symlinks ( ) -> io:: Result < PathBuf > {
73+ let root = env:: current_dir ( ) ?. join ( "fixtures/enhanced_resolve" ) ;
74+ let dirname = root. join ( "test" ) ;
75+ let temp_path = dirname. join ( "temp_symlinks" ) ;
76+ let create_symlink_fixtures = || -> io:: Result < ( ) > {
77+ fs:: create_dir ( & temp_path) ?;
78+ let mut index = fs:: File :: create ( temp_path. join ( "index.js" ) ) ?;
79+ index. write_all ( b"console.log('Hello, World!')" ) ?;
80+ // create 10000 symlink files pointing to the index.js
81+ for i in 0 ..10000 {
82+ symlink ( temp_path. join ( "index.js" ) , temp_path. join ( format ! ( "file{i}.js" ) ) ) ?;
83+ }
84+ Ok ( ( ) )
85+ } ;
86+ if !temp_path. exists ( ) {
87+ if let Err ( err) = create_symlink_fixtures ( ) {
88+ let _ = fs:: remove_dir_all ( & temp_path) ;
89+ return Err ( err) ;
90+ }
91+ }
92+ Ok ( temp_path)
93+ }
94+
5695fn oxc_resolver ( ) -> oxc_resolver:: Resolver {
5796 use oxc_resolver:: { AliasValue , ResolveOptions , Resolver } ;
5897 let alias_value = AliasValue :: from ( "./" ) ;
5998 Resolver :: new ( ResolveOptions {
6099 extensions : vec ! [ ".ts" . into( ) , ".js" . into( ) ] ,
61- condition_names : vec ! [ "webpack" . into( ) ] ,
100+ condition_names : vec ! [ "webpack" . into( ) , "require" . into ( ) ] ,
62101 alias_fields : vec ! [ vec![ "browser" . into( ) ] ] ,
63102 extension_alias : vec ! [
64103 ( ".js" . into( ) , vec![ ".ts" . into( ) , ".js" . into( ) ] ) ,
@@ -103,6 +142,17 @@ fn bench_resolver(c: &mut Criterion) {
103142 assert ! ( oxc_resolver( ) . resolve( path, request) . is_ok( ) , "{path:?} {request}" ) ;
104143 }
105144
145+ let symlink_test_dir = create_symlinks ( ) . expect ( "Create symlink fixtures failed" ) ;
146+
147+ let symlinks_range = 0u32 ..10000 ;
148+
149+ for i in symlinks_range. clone ( ) {
150+ assert ! (
151+ oxc_resolver( ) . resolve( & symlink_test_dir, & format!( "./file{i}" ) ) . is_ok( ) ,
152+ "file{i}.js"
153+ ) ;
154+ }
155+
106156 let mut group = c. benchmark_group ( "resolver" ) ;
107157
108158 group. bench_with_input ( BenchmarkId :: from_parameter ( "single-thread" ) , & data, |b, data| {
@@ -122,6 +172,22 @@ fn bench_resolver(c: &mut Criterion) {
122172 } ) ;
123173 } ) ;
124174 } ) ;
175+
176+ group. bench_with_input (
177+ BenchmarkId :: from_parameter ( "resolve from symlinks" ) ,
178+ & symlinks_range,
179+ |b, data| {
180+ let oxc_resolver = oxc_resolver ( ) ;
181+ b. iter ( || {
182+ for i in data. clone ( ) {
183+ assert ! (
184+ oxc_resolver. resolve( & symlink_test_dir, & format!( "./file{i}" ) ) . is_ok( ) ,
185+ "file{i}.js"
186+ ) ;
187+ }
188+ } ) ;
189+ } ,
190+ ) ;
125191}
126192
127193criterion_group ! ( resolver, bench_resolver) ;
0 commit comments