@@ -579,6 +579,7 @@ pub fn compile_one(
579579 project_root : & Path ,
580580 plain_output : bool ,
581581 warn_error : Option < String > ,
582+ module_format : Option < String > ,
582583) -> Result < String > {
583584 use std:: fs;
584585
@@ -593,6 +594,12 @@ pub fn compile_one(
593594 warn_error,
594595 ) ?;
595596
597+ // Determine which package spec to use for output
598+ let root_config = build_state. get_root_config ( ) ;
599+ let package_specs = root_config. get_package_specs ( ) ;
600+
601+ let selected_spec_index = select_package_spec ( & package_specs, & module_format) ?;
602+
596603 // Step 2: Find target module from file path
597604 let target_module_name = find_module_for_file ( & build_state, target_file)
598605 . ok_or_else ( || anyhow ! ( "File not found in project: {}" , target_file. display( ) ) ) ?;
@@ -633,13 +640,57 @@ pub fn compile_one(
633640 . map_err ( |e| anyhow ! ( "Compilation failed: {}" , e) ) ?;
634641
635642 // Step 7: Find and read the generated JavaScript file
636- let js_path = get_js_output_path ( & build_state, & target_module_name, target_file ) ?;
643+ let js_path = get_js_output_path ( & build_state, & target_module_name, selected_spec_index ) ?;
637644 let js_content = fs:: read_to_string ( & js_path)
638645 . map_err ( |e| anyhow ! ( "Failed to read generated JS file {}: {}" , js_path. display( ) , e) ) ?;
639646
640647 Ok ( js_content)
641648}
642649
650+ /// Select the appropriate package spec based on the module_format argument.
651+ ///
652+ /// If module_format is specified, find the matching spec.
653+ /// If not specified and there are multiple specs, warn and use the first one.
654+ /// Returns the index of the selected package spec.
655+ fn select_package_spec (
656+ package_specs : & [ config:: PackageSpec ] ,
657+ module_format : & Option < String > ,
658+ ) -> Result < usize > {
659+ if package_specs. is_empty ( ) {
660+ return Err ( anyhow ! ( "No package-specs configured in rescript.json" ) ) ;
661+ }
662+
663+ match module_format {
664+ Some ( format) => {
665+ // Find the package spec matching the requested format
666+ package_specs
667+ . iter ( )
668+ . position ( |spec| spec. module == * format)
669+ . ok_or_else ( || {
670+ let available: Vec < & str > = package_specs. iter ( ) . map ( |s| s. module . as_str ( ) ) . collect ( ) ;
671+ anyhow ! (
672+ "Module format '{}' not found in package-specs. Available: {}" ,
673+ format,
674+ available. join( ", " )
675+ )
676+ } )
677+ }
678+ None => {
679+ // No format specified - use first, but warn if multiple exist
680+ if package_specs. len ( ) > 1 {
681+ let available: Vec < & str > = package_specs. iter ( ) . map ( |s| s. module . as_str ( ) ) . collect ( ) ;
682+ eprintln ! (
683+ "Warning: Multiple package-specs configured ({}). Using '{}'. \
684+ Specify --module-format to choose a different one.",
685+ available. join( ", " ) ,
686+ package_specs[ 0 ] . module
687+ ) ;
688+ }
689+ Ok ( 0 )
690+ }
691+ }
692+ }
693+
643694/// Find the module name for a given file path by searching through all modules.
644695///
645696/// This performs a linear search through the build state's modules to match
@@ -705,11 +756,11 @@ fn get_dependency_closure(module_name: &str, build_state: &BuildState) -> AHashS
705756/// Respects the package's configuration for output location and format:
706757/// - in-source: JS file next to the .res file
707758/// - out-of-source: JS file in lib/js or lib/es6
708- /// - Uses first package spec to determine .js vs .mjs extension
759+ /// - Uses the selected package spec to determine .js vs .mjs extension
709760fn get_js_output_path (
710761 build_state : & BuildCommandState ,
711762 module_name : & str ,
712- _original_file : & Path ,
763+ spec_index : usize ,
713764) -> Result < PathBuf > {
714765 let module = build_state
715766 . get_module ( module_name)
@@ -722,8 +773,8 @@ fn get_js_output_path(
722773 let root_config = build_state. get_root_config ( ) ;
723774 let package_specs = root_config. get_package_specs ( ) ;
724775 let package_spec = package_specs
725- . first ( )
726- . ok_or_else ( || anyhow ! ( "No package specs configured" ) ) ?;
776+ . get ( spec_index )
777+ . ok_or_else ( || anyhow ! ( "Package spec index {} out of bounds" , spec_index ) ) ?;
727778
728779 let suffix = root_config. get_suffix ( package_spec) ;
729780
0 commit comments