#[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 FastStaticStrings 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.

Trait implementations

impl AsRef<v8::Global<v8::Object>> for Module

impl<'a> ToV8<'a> for Module

impl<'a> ToV8<'a> for &'_ Module