Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Proof of concept: one shot file compilation#8002

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
nojaf wants to merge10 commits intorescript-lang:master
base:master
Choose a base branch
Loading
fromnojaf:one-shot

Conversation

@nojaf
Copy link
Member

Use case: I want to compile a single ReScript file and run it immediately.
With this PR I could dorescript compile-file MyFile.res | bun - and bun automatically runs it.

(Would not be a stretch to create aBun plugin and just be able to runbun run MyFile.res if plugin is configured)

Going to keep this as draft until after v12.

fhammerschmidt reacted with heart emoji
@pkg-pr-new
Copy link

pkg-pr-newbot commentedNov 4, 2025
edited
Loading

Open in StackBlitz

rescript

npm i https://pkg.pr.new/rescript-lang/rescript@8002

@rescript/darwin-arm64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/darwin-arm64@8002

@rescript/darwin-x64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/darwin-x64@8002

@rescript/linux-arm64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/linux-arm64@8002

@rescript/linux-x64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/linux-x64@8002

@rescript/runtime

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/runtime@8002

@rescript/win32-x64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/win32-x64@8002

commit:102f806

@nojaf
Copy link
MemberAuthor

Split bsc module system flags for stdout compilation

Problem

Whenbsc compiles to stdout (no-bs-package-output specified), it hardcoded the Commonjs module system:

(* compiler/core/lam_compile_main.ml:295 - old code*)ifJs_packages_info.is_empty package_info&&!Js_config.js_stdoutthenJs_dump_program.dump_deps_program~output_prefixCommonjs(* <- hardcoded!*)

This meant stdout output was always Commonjs, regardless of project configuration. Since the newcompile-file command outputs to stdout, it could only generate Commonjs, not ES6 modules.

Solution

Split-bs-package-output into three independent flags:

Before (coupled):

-bs-package-output esmodule:lib/es6:.mjs# Format: module_system:path:suffix (all three or none)

After (decoupled):

-bs-module-system esmodule# Controls import/export syntax-bs-suffix .mjs# Controls import path extensions-bs-package-output lib/es6# Output directory (optional)

Implementation

New compiler state (compiler/common/js_config.ml):

let default_module_system=refExt_module_system.Commonjslet default_suffix=refLiterals.suffix_js

New flags (compiler/bsc/rescript_compiler_main.ml):

("-bs-module-system", string_call set_module_system,"Set module system: commonjs, esmodule, es6-global");("-bs-suffix", string_call set_suffix,"Set import file suffix: .js, .mjs, .cjs");

Stdout output now uses configured values (compiler/core/lam_compile_main.ml):

ifJs_packages_info.is_empty package_info&&!Js_config.js_stdoutthen(* Use configured module system instead of hardcoded Commonjs*)Js_dump_program.dump_deps_program~output_prefix!Js_config.default_module_system

Import path generation uses configured suffix (compiler/core/js_name_of_module_id.ml):

(* For Package_script mode (stdout), use configured suffix*)let js_file=Ext_namespace.js_name_of_modulename dep_module_id.id.name case!Js_config.default_suffix

Critical exception: Runtime package imports (@rescript/runtime) always use.js because the runtime is pre-compiled and distributed with.js files:

(* Runtime package is pre-compiled and always uses .js suffix*)let js_file=Ext_namespace.js_name_of_modulename dep_module_id.id.nameUpperLiterals.suffix_js

Build System Updates

Rewatch (rewatch/src/build/compile.rs):

// Old format:"-bs-package-output","esmodule:lib/es6:.mjs"// New format:"-bs-module-system","esmodule","-bs-suffix",".mjs","-bs-package-output","lib/es6"

Legacy bsb (compiler/bsb/bsb_package_specs.ml):

(* Old: single compound flag*)"-bs-package-output esmodule:lib/es6:.mjs"(* New: three separate flags*)"-bs-module-system esmodule -bs-suffix .mjs -bs-package-output lib/es6"

Backward Compatibility

The-bs-package-output parser still accepts the old format:

  • module:path:suffix - all three explicit (old format)
  • module:path - uses configured suffix
  • path - uses configured module system and suffix

This allows gradual migration, though since these are internal flags (users don't callbsc directly), backward compatibility isn't critical.

Result

bsc can now output ES6 modules to stdout:

$ bsc -bs-module-system esmodule -bs-suffix .mjs file.ast// Generated by ReScript, PLEASE EDIT WITH CAREimport* as MyDep from"./MyDep.mjs";import* as Belt_Array from"@rescript/runtime/lib/es6/Belt_Array.js";export { ... }

Notice:

  • User module imports:.mjs (from-bs-suffix)
  • Runtime imports:.js (always, because runtime is pre-compiled)

This enablescompile-file to respect project configuration when outputting to stdout.

//cc@cristianoc ,@zth

zth reacted with thumbs up emoji

The previous implementation used a ninja variable $in_d which doesn't exist,causing files to be written to the wrong location. Now bsc extracts thesource subdirectory directly from the output_prefix parameter.For in-source builds with output_prefix='src/Node', files are written to:  project_root / '.' / 'src' / 'Node.mjs'For out-of-source builds with output_prefix='src/Node', files go to:  project_root / 'lib/es6' / 'src' / 'Node.mjs'This ensures source directory structure is preserved in the output.
bsb passes path='.' and expects source_subdir to be extracted from output_prefix.rewatch passes path=file_path.parent() which already contains the full directory.Now check if path is a base directory (., lib/es6, etc.) and only thenextract source_subdir from output_prefix. Otherwise use path as-is.
…package-outputFor in-source builds, extract source subdirectories from output_prefix and .cmj file locations to generate correct relative import paths.
@nojaf
Copy link
MemberAuthor

Hi@cristianoc , the splitting of the bsc arg turned out quite ugly.
To satisfy bsb, a lot of code was generated while it seems a lot more straightforward in Rewatch.
Any pointers on what could be improved?

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

1 participant

@nojaf

[8]ページ先頭

©2009-2025 Movatter.jp