Description
Background
Imagine a class statement written from external JS.
// rescript_error.mjs
export class RescriptError extends Error {
constructor(exnId, payload) {
super();
}
}
// and in rescript_error.cjs
module.exports = {
RescriptError,
};
This is a pretty common situation because ReScript doesn't support ES classes.
However, ReScript's current FFI approach cannot select the appropriate resolution by its syntax.
type t
@module("./rescript_error.mjs") @new external makeErrorEsm: unit => t = "RescriptError"
@module("./rescript_error.cjs") @new external makeErrorCjs: unit => t = "RescriptError"
// and it might need a runtime like UMD
This can be solved today using bundlers' module alias or Node.js' conditional exports/imports resolution, but these are all platform-dependent features.
{
"imports": {
"#error": {
"import": "./rescript_error.mjs",
"require": "./rescript_error.cjs"
}
}
}
The toolchain must be able to produce output that is appropriate for its target. That's true even for FFIs.
Suggested Solution
There are currently two module specs: esmoudle
and commonjs
(a composite of the two, dual
, will be added in the future #6209).
Users can specify either of these two as target
in the @module
statement.
type t
@module({ target: "esmodule", from: "./rescript_error.mjs" })
@module({ target: "commonjs", from: "./rescript_error.cjs" })
@new external makeError: unit => t = "RescriptError"
The library may not support all conditions. The compiler should raise an error if it cannot find a target that matches a module in the project.
If target
omitted, the *
pattern is implicitly used.
@module("./rescript_error.ts")
// is equivalent
@module({ target: "*", from: "./rescript_error.ts" })
Metadata
Metadata
Assignees
Type
Projects
Status
Status