Skip to content

Commit

Permalink
add deno target
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobhellermann committed Jun 1, 2020
1 parent cc36bdc commit 79f96af
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 5 deletions.
51 changes: 48 additions & 3 deletions crates/cli-support/src/js/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ impl<'a> Context<'a> {
| OutputMode::Node {
experimental_modules: true,
}
| OutputMode::Web => {
| OutputMode::Web
| OutputMode::Deno => {
if contents.starts_with("function") {
let body = &contents[8..];
if export_name == definition_name {
Expand Down Expand Up @@ -269,6 +270,40 @@ impl<'a> Context<'a> {
reset_indentation(&shim)
}

// generates somthing like
// ```js
// const imports = {
// __wbindgen_placeholder__: {
// __wbindgen_throw: function(..) { .. },
// ..
// }
// }
// ```
fn generate_deno_imports(&self) -> String {
let mut imports = "const imports = {\n".to_string();
imports.push_str(&format!(" {}: {{\n", crate::PLACEHOLDER_MODULE));

for (id, js) in crate::sorted_iter(&self.wasm_import_definitions) {
let import = self.module.imports.get(*id);
imports.push_str(&format!("{}: {},\n", &import.name, js.trim()));
}

imports.push_str("\t}\n};\n\n");

imports
}

fn generate_deno_wasm_loading(&self, module_name: &str) -> String {
format!(
"const file = new URL(import.meta.url).pathname;
const wasmFile = file.substring(0, file.lastIndexOf(Deno.build.os === 'windows' ? '\\\\' : '/') + 1) + '{}_bg.wasm';
const wasmModule = new WebAssembly.Module(Deno.readFileSync(wasmFile));
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
const wasm = wasmInstance.exports;",
module_name
)
}

/// Performs the task of actually generating the final JS module, be it
/// `--target no-modules`, `--target web`, or for bundlers. This is the very
/// last step performed in `finalize`.
Expand Down Expand Up @@ -331,6 +366,15 @@ impl<'a> Context<'a> {
}
}

OutputMode::Deno => {
footer.push_str(&self.generate_deno_imports());
footer.push_str(&self.generate_deno_wasm_loading(module_name));

if needs_manual_start {
footer.push_str("wasm.__wbindgen_start();\n");
}
}

// With Bundlers and modern ES6 support in Node we can simply import
// the wasm file as if it were an ES module and let the
// bundler/runtime take care of it.
Expand Down Expand Up @@ -443,7 +487,8 @@ impl<'a> Context<'a> {
| OutputMode::Node {
experimental_modules: true,
}
| OutputMode::Web => {
| OutputMode::Web
| OutputMode::Deno => {
for (module, items) in crate::sorted_iter(&self.js_imports) {
imports.push_str("import { ");
for (i, (item, rename)) in items.iter().enumerate() {
Expand Down Expand Up @@ -1247,7 +1292,7 @@ impl<'a> Context<'a> {
fields: Vec::new(),
})?;
self.global(&format!("let cached{} = new {}{};", s, name, args));
} else if !self.config.mode.always_run_in_browser() {
} else if !self.config.mode.always_run_in_browser() && !self.config.mode.deno() {
self.global(&format!(
"
const l{0} = typeof {0} === 'undefined' ? \
Expand Down
19 changes: 18 additions & 1 deletion crates/cli-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ enum OutputMode {
Web,
NoModules { global: String },
Node { experimental_modules: bool },
Deno,
}

enum Input {
Expand Down Expand Up @@ -210,6 +211,14 @@ impl Bindgen {
Ok(self)
}

pub fn deno(&mut self, deno: bool) -> Result<&mut Bindgen, Error> {
if deno {
self.switch_mode(OutputMode::Deno, "--target deno")?;
self.encode_into(EncodeInto::Always);
}
Ok(self)
}

pub fn no_modules_global(&mut self, name: &str) -> Result<&mut Bindgen, Error> {
match &mut self.mode {
OutputMode::NoModules { global } => *global = name.to_string(),
Expand Down Expand Up @@ -526,7 +535,8 @@ impl OutputMode {
| OutputMode::Web
| OutputMode::Node {
experimental_modules: true,
} => true,
}
| OutputMode::Deno => true,
_ => false,
}
}
Expand Down Expand Up @@ -570,6 +580,13 @@ impl OutputMode {
}
}

fn deno(&self) -> bool {
match self {
OutputMode::Deno { .. } => true,
_ => false,
}
}

fn esm_integration(&self) -> bool {
match self {
OutputMode::Bundler { .. }
Expand Down
3 changes: 2 additions & 1 deletion crates/cli/src/bin/wasm-bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Options:
--out-dir DIR Output directory
--out-name VAR Set a custom output filename (Without extension. Defaults to crate name)
--target TARGET What type of output to generate, valid
values are [web, bundler, nodejs, no-modules],
values are [web, bundler, nodejs, no-modules, deno],
and the default is [bundler]
--no-modules-global VAR Name of the global variable to initialize
--browser Hint that JS should only be compatible with a browser
Expand Down Expand Up @@ -98,6 +98,7 @@ fn rmain(args: &Args) -> Result<(), Error> {
"web" => b.web(true)?,
"no-modules" => b.no_modules(true)?,
"nodejs" => b.nodejs(true)?,
"deno" => b.deno(true)?,
s => bail!("invalid encode-into mode: `{}`", s),
};
}
Expand Down

0 comments on commit 79f96af

Please sign in to comment.