#[js(module)]
Use #[js(module)]
to embed an ECMAScript module in the program.
use ferrosaur::js;
#[js(module("../examples/js/mod.js"))]
pub struct Module;
The path is relative to the current file (it has the same usage as the include_str!
macro).
Call the
main_module_init
or
side_module_init
method to initialize it as a main module or side module in the given JsRuntime
.
#[path = "../../../crates/ferrosaur/tests/fixture/mod.rs"]
mod fixture;
use fixture::items::modules::Main as MainModule;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let rt = &mut fixture::deno()?;
// let rt: &mut JsRuntime;
let main = MainModule::main_module_init(rt).await?;
Ok(())
}
note
For the difference between a main module and a side module, see documentation for the
corresponding JsRuntime
methods:
After this, you can use #[js(interface)]
to further derive access to
items exported from your module. For example, if you have:
export const answer = "42";
Then you can write:
use ferrosaur::js;
#[path = "../../../crates/ferrosaur/tests/fixture/mod.rs"]
mod fixture;
use fixture::items::modules::{Main as MainModule};
#[js(interface)]
impl MainModule {
#[js(prop)]
fn answer(&self) -> String {}
}
Ok::<_, anyhow::Error>(())
Sections
Option fast
use ferrosaur::js;
#[js(module("../examples/js/mod.js", fast))]
pub struct Module;
Without the fast
option, JavaScript source code is embedded using include_str!
.
With the fast
option, JavaScript source code is embedded using
deno_core::ascii_str_include!
instead.
The JS source file must be in 7-bit ASCII. It is a compile-time error if this does not hold.
note
For what it means for the string to be "fast," from deno_core::FastStaticString
:
A static string that is compile-time checked to be ASCII and is stored in the most efficient possible way to create V8 strings.
fast(unsafe_debug)
use ferrosaur::js;
#[js(module("../examples/js/mod.js", fast(unsafe_debug)))]
pub struct Module;
Like fast
, except for debug builds, at compile time, unsafely embed
JS code as FastStaticString
s without checking it is in 7-bit ASCII.
For release builds, this behaves the same as fast
. Under the hood, this uses the
#[cfg(debug_assertions)]
condition.
The behavior is undefined if the file is not actually in ASCII.
This could be useful if the source file you are trying to embed is very large, in which case the compile-time checking could take a very long time.
Option url(...)
Control the value of import.meta.url
within the module:
url(preserve)
use ferrosaur::js;
#[js(module("../examples/js/mod.js", url(preserve)))]
pub struct Module;
import.meta.url
will be file:///
followed by the relative path from
CARGO_MANIFEST_DIR
to the embedded JS file. This is the default behavior
if the url(...)
option is not specified.
Example | |
---|---|
JavaScript file | <CARGO_MANIFEST_DIR>/src/js/index.js |
import.meta.url | "file:///src/js/index.js" |
url(cwd)
use ferrosaur::js;
#[js(module("../examples/js/mod.js", url(cwd)))]
pub struct Module;
import.meta.url
will be file://
+ std::env::current_dir()
at runtime + a name
generated from the file's relative path.
This essentially gives import.meta.url
the same real working directory as the program
itself.
Example | |
---|---|
JavaScript file | <CARGO_MANIFEST_DIR>/src/js/index.js |
current_dir() | /path/to/cwd |
import.meta.url | "file:///path/to/cwd/-src-js-index.js" |
url("...")
use ferrosaur::js;
#[js(module("../examples/js/mod.js", url("...")))]
pub struct Module;
Use a custom import.meta.url
.
The string must be parsable by url::Url
. It is a runtime error if the URL is not
parsable. Notably, this means you cannot use a bare identifier like "package"
as you
would with Node.
For example, url("npm:lodash")
sets import.meta.url
to "npm:lodash"
. Other modules
in the same JsRuntime
will then be able to import this module using
import ... from "npm:lodash"
.
Derived APIs
Methods
pub async fn main_module_init(rt: &mut JsRuntime) -> anyhow::Result<Self>
Initialize the embedded ES module as a main
module in the given JsRuntime
.
pub async fn side_module_init(rt: &mut JsRuntime) -> anyhow::Result<Self>
Initialize the embedded ES module as a side
module in the given JsRuntime
.
pub fn module_url() -> anyhow::Result<ModuleSpecifier>
Get the import.meta.url
within the module (controllable through the
url(...)
option).
Associated items
pub const MODULE_SRC: &str or FastStaticString
The embedded JS source code as a constant.