From 4755d4ab2bba55ceffdc2e556a7ee9b6eb09e61f Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Wed, 8 Nov 2023 09:26:47 +0100 Subject: [PATCH] Freely configurable suffix for generated .js files (#6472) * Freely configurable suffix for generated .js files * Better error message * Update description in schema, too --- CHANGELOG.md | 5 +++ docs/docson/build-schema.json | 4 +-- jscomp/bsb/bsb_exception.ml | 2 +- jscomp/bsb/bsb_package_specs.ml | 44 ++++++++++++------------ jscomp/bsb/bsb_spec_set.ml | 2 +- jscomp/bsb/bsb_spec_set.mli | 2 +- jscomp/core/js_name_of_module_id.ml | 4 +-- jscomp/core/js_packages_info.ml | 16 ++++----- jscomp/core/js_packages_info.mli | 4 +-- jscomp/core/lam_compile_main.ml | 5 +-- jscomp/ext/ext_js_file_kind.ml | 4 +-- jscomp/ext/ext_js_suffix.ml | 28 --------------- jscomp/ext/ext_namespace.ml | 2 +- jscomp/ext/ext_namespace.mli | 2 +- jscomp/ext/literals.ml | 10 ------ jscomp/ounit_tests/ounit_string_tests.ml | 9 ++--- 16 files changed, 51 insertions(+), 92 deletions(-) delete mode 100644 jscomp/ext/ext_js_suffix.ml diff --git a/CHANGELOG.md b/CHANGELOG.md index 8aec6c7a5d..4112d82667 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,12 @@ # 11.0.0-rc.6 (Unreleased) +#### :rocket: New Feature + +- Freely configurable suffix for generated .js files. https://github.com/rescript-lang/rescript-compiler/pull/6472 + #### :bug: Bug Fix + - Fix issue with GenType and `result` introduced in rc.5. https://github.com/rescript-lang/rescript-compiler/pull/6464 - Fix compiler crash when inlining complex constants in pattern matching. https://github.com/rescript-lang/rescript-compiler/pull/6471 diff --git a/docs/docson/build-schema.json b/docs/docson/build-schema.json index d5e6adbe8b..cc930c2bde 100644 --- a/docs/docson/build-schema.json +++ b/docs/docson/build-schema.json @@ -6,8 +6,8 @@ "description": "es6-global generate relative `require` paths instead of relying on NodeJS' module resolution. Default: commonjs." }, "suffix-spec": { - "enum": [".js", ".mjs", ".cjs", ".bs.js", ".bs.mjs", ".bs.cjs"], - "description": "suffix of generated js files, default to [.js] " + "type": "string", + "description": "Suffix of generated js files. Default: .js. May contain letters, digits, \"-\", \"_\" and \".\" and must end with .js, .mjs or .cjs." }, "module-format-object": { "type": "object", diff --git a/jscomp/bsb/bsb_exception.ml b/jscomp/bsb/bsb_exception.ml index ed3bc22134..007221c966 100644 --- a/jscomp/bsb/bsb_exception.ml +++ b/jscomp/bsb/bsb_exception.ml @@ -71,7 +71,7 @@ let print (fmt : Format.formatter) (x : error) = Format.fprintf fmt "File %S, line %d:\n\ @{Error:@} %s \n\ - For more details, please checkout the schema \ + For more details, please check out the schema at \ https://rescript-lang.org/docs/manual/latest/build-configuration-schema" pos.pos_fname pos.pos_lnum s | Invalid_spec s -> diff --git a/jscomp/bsb/bsb_package_specs.ml b/jscomp/bsb/bsb_package_specs.ml index 92c909a866..69b43accf8 100644 --- a/jscomp/bsb/bsb_package_specs.ml +++ b/jscomp/bsb/bsb_package_specs.ml @@ -55,6 +55,10 @@ let string_of_format (x : Ext_module_system.t) = | Es6 -> Literals.es6 | Es6_global -> Literals.es6_global +let js_suffix_regexp = Str.regexp "[A-Za-z0-9-_.]*\\.[cm]?js" + +let validate_js_suffix suffix = Str.string_match js_suffix_regexp suffix 0 + let rec from_array suffix (arr : Ext_json_types.t array) : Spec_set.t = let spec = ref Spec_set.empty in let has_in_source = ref false in @@ -83,15 +87,14 @@ and from_json_single suffix (x : Ext_json_types.t) : Bsb_spec_set.spec = | Some _ | None -> false in let suffix = - match map.?("suffix") with - | Some (Str { str = suffix; loc }) -> - let s = Ext_js_suffix.of_string suffix in - if s = Unknown_extension then - Bsb_exception.errorf ~loc "expected .js, .mjs, .cjs or .bs.js, .bs.mjs, .bs.cjs" - else s + match map.?(Bsb_build_schemas.suffix) with + | Some (Str { str = suffix; _ }) when validate_js_suffix suffix -> suffix + | Some (Str {str; loc}) -> + Bsb_exception.errorf ~loc + ("invalid suffix \"%s\". The suffix and may contain letters, digits, \"-\", \"_\" and \".\" and must end with .js, .mjs or .cjs.") str | Some _ -> - Bsb_exception.errorf ~loc:(Ext_json.loc_of x) - "expected a string field" + Bsb_exception.errorf ~loc:(Ext_json.loc_of x) + "expected a string extension like \".js\"" | None -> suffix in { format = supported_format format loc; in_source; suffix } @@ -128,7 +131,7 @@ let package_flag ({ format; in_source; suffix } : Bsb_spec_set.spec) dir = (if in_source then dir else Bsb_config.top_prefix_of_format format // dir) Ext_string.single_colon - (Ext_js_suffix.to_string suffix)) + suffix) (* FIXME: we should adapt it *) let package_flag_of_package_specs (package_specs : t) ~(dirname : string) : @@ -166,8 +169,7 @@ let get_list_of_output_js (package_specs : t) Spec_set.fold (fun (spec : Bsb_spec_set.spec) acc -> let basename = - Ext_namespace.change_ext_ns_suffix output_file_sans_extension - (Ext_js_suffix.to_string spec.suffix) + Ext_namespace.change_ext_ns_suffix output_file_sans_extension spec.suffix in (if spec.in_source then Bsb_config.rev_lib_bs_prefix basename else Bsb_config.lib_bs_prefix_of_format spec.format // basename) @@ -182,21 +184,19 @@ let list_dirs_by (package_specs : t) (f : string -> unit) = type json_map = Ext_json_types.t Map_string.t -let extract_bs_suffix_exn (map : json_map) : Ext_js_suffix.t = +let extract_js_suffix_exn (map : json_map) : string = match map.?(Bsb_build_schemas.suffix) with - | None -> Js - | Some (Str { str; loc }) -> - let s = Ext_js_suffix.of_string str in - if s = Unknown_extension then - Bsb_exception.errorf ~loc - "expected .js, .mjs, .cjs or .bs.js, .bs.mjs, .bs.cjs" - else s + | None -> Literals.suffix_js + | Some (Str { str = suffix; _ }) when validate_js_suffix suffix -> suffix + | Some ((Str {str; _}) as config) -> + Bsb_exception.config_error config + ("invalid suffix \"" ^ str ^ "\". The suffix and may contain letters, digits, \"-\", \"_\" and \".\" and must end with .js, .mjs or .cjs.") | Some config -> - Bsb_exception.config_error config - "expected a string extension like \".js\"" + Bsb_exception.config_error config + "expected a string extension like \".js\"" let from_map ~(cwd : string) map = - let suffix = extract_bs_suffix_exn map in + let suffix = extract_js_suffix_exn map in let modules = match map.?(Bsb_build_schemas.package_specs) with | Some x -> from_json suffix x diff --git a/jscomp/bsb/bsb_spec_set.ml b/jscomp/bsb/bsb_spec_set.ml index 829d46a793..6934bc1913 100644 --- a/jscomp/bsb/bsb_spec_set.ml +++ b/jscomp/bsb/bsb_spec_set.ml @@ -27,7 +27,7 @@ (* TODO: sync up with {!Js_packages_info.module_system} *) type format = Ext_module_system.t = NodeJS | Es6 | Es6_global -type spec = { format : format; in_source : bool; suffix : Ext_js_suffix.t } +type spec = { format : format; in_source : bool; suffix : string } type t = spec list diff --git a/jscomp/bsb/bsb_spec_set.mli b/jscomp/bsb/bsb_spec_set.mli index c59ebb87f5..996475c207 100644 --- a/jscomp/bsb/bsb_spec_set.mli +++ b/jscomp/bsb/bsb_spec_set.mli @@ -23,7 +23,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) type format = Ext_module_system.t -type spec = { format : format; in_source : bool; suffix : Ext_js_suffix.t } +type spec = { format : format; in_source : bool; suffix : string } type t = private spec list diff --git a/jscomp/core/js_name_of_module_id.ml b/jscomp/core/js_name_of_module_id.ml index 96e889a78d..d1cee4333a 100644 --- a/jscomp/core/js_name_of_module_id.ml +++ b/jscomp/core/js_name_of_module_id.ml @@ -59,7 +59,7 @@ let get_runtime_module_path module_system in let js_file = Ext_namespace.js_name_of_modulename dep_module_id.id.name - Little Js in + Little Literals.suffix_js in match current_info_query with | Package_not_found -> assert false | Package_script -> @@ -183,7 +183,7 @@ let string_of_module_id | Package_script, Package_script -> let js_file = - Ext_namespace.js_name_of_modulename dep_module_id.id.name case Js in + Ext_namespace.js_name_of_modulename dep_module_id.id.name case Literals.suffix_js in match Config_util.find_opt js_file with | Some file -> let basename = Filename.basename file in diff --git a/jscomp/core/js_packages_info.ml b/jscomp/core/js_packages_info.ml index eb37cfcce0..1f189a9e5c 100644 --- a/jscomp/core/js_packages_info.ml +++ b/jscomp/core/js_packages_info.ml @@ -38,7 +38,7 @@ let compatible (dep : module_system) (query : module_system) = type package_info = { module_system : module_system; path : string; - suffix : Ext_js_suffix.t; + suffix : string; } type package_name = Pkg_empty | Pkg_runtime | Pkg_normal of string @@ -61,8 +61,8 @@ let runtime_package_specs : t = name = Pkg_runtime; module_systems = [ - { module_system = Es6; path = "lib/es6"; suffix = Js }; - { module_system = NodeJS; path = "lib/js"; suffix = Js }; + { module_system = Es6; path = "lib/es6"; suffix = Literals.suffix_js }; + { module_system = NodeJS; path = "lib/js"; suffix = Literals.suffix_js }; ]; } @@ -121,7 +121,7 @@ let dump_package_info (fmt : Format.formatter) Format.fprintf fmt "@[%s@ %s@ %s@]" (string_of_module_system ms) name - (Ext_js_suffix.to_string suffix) + suffix let dump_package_name fmt (x : package_name) = match x with @@ -140,7 +140,7 @@ let dump_packages_info (fmt : Format.formatter) type package_found_info = { rel_path : string; pkg_rel_path : string; - suffix : Ext_js_suffix.t; + suffix : string; } type info_query = @@ -201,18 +201,18 @@ let add_npm_package_path (packages_info : t) (s : string) : t = in let m = match Ext_string.split ~keep_empty:true s ':' with - | [ path ] -> { module_system = NodeJS; path; suffix = Js } + | [ path ] -> { module_system = NodeJS; path; suffix = Literals.suffix_js } | [ module_system; path ] -> { module_system = handle_module_system module_system; path; - suffix = Js; + suffix = Literals.suffix_js; } | [ module_system; path; suffix ] -> { module_system = handle_module_system module_system; path; - suffix = Ext_js_suffix.of_string suffix; + suffix; } | _ -> Bsc_args.bad_arg ("invalid npm package path: " ^ s) in diff --git a/jscomp/core/js_packages_info.mli b/jscomp/core/js_packages_info.mli index 943c231bae..bf099f5d6c 100644 --- a/jscomp/core/js_packages_info.mli +++ b/jscomp/core/js_packages_info.mli @@ -31,7 +31,7 @@ val runtime_package_path : module_system -> string -> string type package_info = { module_system : module_system; path : string; - suffix : Ext_js_suffix.t; + suffix : string; } type t @@ -64,7 +64,7 @@ val add_npm_package_path : t -> string -> t type package_found_info = { rel_path : string; pkg_rel_path : string; - suffix : Ext_js_suffix.t; + suffix : string; } type info_query = diff --git a/jscomp/core/lam_compile_main.ml b/jscomp/core/lam_compile_main.ml index ec7153b380..e70c6dc260 100644 --- a/jscomp/core/lam_compile_main.ml +++ b/jscomp/core/lam_compile_main.ml @@ -301,10 +301,7 @@ let lambda_as_module (lambda_output) chan in let basename = - Ext_namespace.change_ext_ns_suffix - (Filename.basename - output_prefix) - (Ext_js_suffix.to_string suffix) + Ext_namespace.change_ext_ns_suffix (Filename.basename output_prefix) suffix in let target_file = (Lazy.force Ext_path.package_dir // diff --git a/jscomp/ext/ext_js_file_kind.ml b/jscomp/ext/ext_js_file_kind.ml index 1688b39622..196ba32462 100644 --- a/jscomp/ext/ext_js_file_kind.ml +++ b/jscomp/ext/ext_js_file_kind.ml @@ -23,6 +23,4 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) type case = Upper | Little -type [@warning "-69"] t = { case : case; suffix : Ext_js_suffix.t } - -let any_runtime_kind = { case = Little; suffix = Ext_js_suffix.Js } +type [@warning "-69"] t = { case : case; suffix : string } diff --git a/jscomp/ext/ext_js_suffix.ml b/jscomp/ext/ext_js_suffix.ml deleted file mode 100644 index ab09d7ec79..0000000000 --- a/jscomp/ext/ext_js_suffix.ml +++ /dev/null @@ -1,28 +0,0 @@ -type t = - | Js - | Mjs - | Cjs - | Bs_js - | Bs_mjs - | Bs_cjs - | Unknown_extension - -let to_string (x : t) = - match x with - | Js -> Literals.suffix_js - | Mjs -> Literals.suffix_mjs - | Cjs -> Literals.suffix_cjs - | Bs_js -> Literals.suffix_bs_js - | Bs_mjs -> Literals.suffix_bs_mjs - | Bs_cjs -> Literals.suffix_bs_cjs - | Unknown_extension -> assert false - -let of_string (x : string) : t = - match () with - | () when x = Literals.suffix_js -> Js - | () when x = Literals.suffix_mjs -> Mjs - | () when x = Literals.suffix_cjs -> Cjs - | () when x = Literals.suffix_bs_js -> Bs_js - | () when x = Literals.suffix_bs_mjs -> Bs_mjs - | () when x = Literals.suffix_bs_cjs -> Bs_cjs - | _ -> Unknown_extension diff --git a/jscomp/ext/ext_namespace.ml b/jscomp/ext/ext_namespace.ml index 7781b80c99..deccf1f961 100644 --- a/jscomp/ext/ext_namespace.ml +++ b/jscomp/ext/ext_namespace.ml @@ -45,7 +45,7 @@ let js_name_of_modulename s (case : Ext_js_file_kind.case) suffix : string = let s = match case with Little -> Ext_string.uncapitalize_ascii s | Upper -> s in - change_ext_ns_suffix s (Ext_js_suffix.to_string suffix) + change_ext_ns_suffix s suffix (* https://docs.npmjs.com/files/package.json Some rules: diff --git a/jscomp/ext/ext_namespace.mli b/jscomp/ext/ext_namespace.mli index 830e74cba3..f562729d7b 100644 --- a/jscomp/ext/ext_namespace.mli +++ b/jscomp/ext/ext_namespace.mli @@ -34,7 +34,7 @@ val try_split_module_name : string -> (string * string) option val change_ext_ns_suffix : string -> string -> string val js_name_of_modulename : - string -> Ext_js_file_kind.case -> Ext_js_suffix.t -> string + string -> Ext_js_file_kind.case -> string -> string (** [js_name_of_modulename ~little A-Ns] *) diff --git a/jscomp/ext/literals.ml b/jscomp/ext/literals.ml index ed410ee8d7..b8345e3c5f 100644 --- a/jscomp/ext/literals.ml +++ b/jscomp/ext/literals.ml @@ -121,16 +121,6 @@ let suffix_d = ".d" let suffix_js = ".js" -let suffix_bs_js = ".bs.js" - -let suffix_mjs = ".mjs" - -let suffix_bs_mjs = ".bs.mjs" - -let suffix_cjs = ".cjs" - -let suffix_bs_cjs = ".bs.cjs" - let suffix_gen_js = ".gen.js" let suffix_gen_tsx = ".gen.tsx" diff --git a/jscomp/ounit_tests/ounit_string_tests.ml b/jscomp/ounit_tests/ounit_string_tests.ml index 854eae5383..4b7a64fece 100644 --- a/jscomp/ounit_tests/ounit_string_tests.ml +++ b/jscomp/ounit_tests/ounit_string_tests.ml @@ -386,14 +386,11 @@ let suites = =~ "a-.js"; Ext_namespace.change_ext_ns_suffix "AA-b" Literals.suffix_js =~ "AA.js"; - Ext_namespace.js_name_of_modulename - "AA-b" Little Js + Ext_namespace.js_name_of_modulename "AA-b" Little Literals.suffix_js =~ "aA.js"; - Ext_namespace.js_name_of_modulename - "AA-b" Upper Js + Ext_namespace.js_name_of_modulename "AA-b" Upper Literals.suffix_js =~ "AA.js"; - Ext_namespace.js_name_of_modulename - "AA-b" Upper Bs_js + Ext_namespace.js_name_of_modulename "AA-b" Upper ".bs.js" =~ "AA.bs.js"; end; __LOC__ >:: begin fun _ ->