Skip to content

Commit 79f96af

Browse files
add deno target
1 parent cc36bdc commit 79f96af

File tree

3 files changed

+68
-5
lines changed

3 files changed

+68
-5
lines changed

crates/cli-support/src/js/mod.rs

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ impl<'a> Context<'a> {
143143
| OutputMode::Node {
144144
experimental_modules: true,
145145
}
146-
| OutputMode::Web => {
146+
| OutputMode::Web
147+
| OutputMode::Deno => {
147148
if contents.starts_with("function") {
148149
let body = &contents[8..];
149150
if export_name == definition_name {
@@ -269,6 +270,40 @@ impl<'a> Context<'a> {
269270
reset_indentation(&shim)
270271
}
271272

273+
// generates somthing like
274+
// ```js
275+
// const imports = {
276+
// __wbindgen_placeholder__: {
277+
// __wbindgen_throw: function(..) { .. },
278+
// ..
279+
// }
280+
// }
281+
// ```
282+
fn generate_deno_imports(&self) -> String {
283+
let mut imports = "const imports = {\n".to_string();
284+
imports.push_str(&format!(" {}: {{\n", crate::PLACEHOLDER_MODULE));
285+
286+
for (id, js) in crate::sorted_iter(&self.wasm_import_definitions) {
287+
let import = self.module.imports.get(*id);
288+
imports.push_str(&format!("{}: {},\n", &import.name, js.trim()));
289+
}
290+
291+
imports.push_str("\t}\n};\n\n");
292+
293+
imports
294+
}
295+
296+
fn generate_deno_wasm_loading(&self, module_name: &str) -> String {
297+
format!(
298+
"const file = new URL(import.meta.url).pathname;
299+
const wasmFile = file.substring(0, file.lastIndexOf(Deno.build.os === 'windows' ? '\\\\' : '/') + 1) + '{}_bg.wasm';
300+
const wasmModule = new WebAssembly.Module(Deno.readFileSync(wasmFile));
301+
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
302+
const wasm = wasmInstance.exports;",
303+
module_name
304+
)
305+
}
306+
272307
/// Performs the task of actually generating the final JS module, be it
273308
/// `--target no-modules`, `--target web`, or for bundlers. This is the very
274309
/// last step performed in `finalize`.
@@ -331,6 +366,15 @@ impl<'a> Context<'a> {
331366
}
332367
}
333368

369+
OutputMode::Deno => {
370+
footer.push_str(&self.generate_deno_imports());
371+
footer.push_str(&self.generate_deno_wasm_loading(module_name));
372+
373+
if needs_manual_start {
374+
footer.push_str("wasm.__wbindgen_start();\n");
375+
}
376+
}
377+
334378
// With Bundlers and modern ES6 support in Node we can simply import
335379
// the wasm file as if it were an ES module and let the
336380
// bundler/runtime take care of it.
@@ -443,7 +487,8 @@ impl<'a> Context<'a> {
443487
| OutputMode::Node {
444488
experimental_modules: true,
445489
}
446-
| OutputMode::Web => {
490+
| OutputMode::Web
491+
| OutputMode::Deno => {
447492
for (module, items) in crate::sorted_iter(&self.js_imports) {
448493
imports.push_str("import { ");
449494
for (i, (item, rename)) in items.iter().enumerate() {
@@ -1247,7 +1292,7 @@ impl<'a> Context<'a> {
12471292
fields: Vec::new(),
12481293
})?;
12491294
self.global(&format!("let cached{} = new {}{};", s, name, args));
1250-
} else if !self.config.mode.always_run_in_browser() {
1295+
} else if !self.config.mode.always_run_in_browser() && !self.config.mode.deno() {
12511296
self.global(&format!(
12521297
"
12531298
const l{0} = typeof {0} === 'undefined' ? \

crates/cli-support/src/lib.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ enum OutputMode {
7474
Web,
7575
NoModules { global: String },
7676
Node { experimental_modules: bool },
77+
Deno,
7778
}
7879

7980
enum Input {
@@ -210,6 +211,14 @@ impl Bindgen {
210211
Ok(self)
211212
}
212213

214+
pub fn deno(&mut self, deno: bool) -> Result<&mut Bindgen, Error> {
215+
if deno {
216+
self.switch_mode(OutputMode::Deno, "--target deno")?;
217+
self.encode_into(EncodeInto::Always);
218+
}
219+
Ok(self)
220+
}
221+
213222
pub fn no_modules_global(&mut self, name: &str) -> Result<&mut Bindgen, Error> {
214223
match &mut self.mode {
215224
OutputMode::NoModules { global } => *global = name.to_string(),
@@ -526,7 +535,8 @@ impl OutputMode {
526535
| OutputMode::Web
527536
| OutputMode::Node {
528537
experimental_modules: true,
529-
} => true,
538+
}
539+
| OutputMode::Deno => true,
530540
_ => false,
531541
}
532542
}
@@ -570,6 +580,13 @@ impl OutputMode {
570580
}
571581
}
572582

583+
fn deno(&self) -> bool {
584+
match self {
585+
OutputMode::Deno { .. } => true,
586+
_ => false,
587+
}
588+
}
589+
573590
fn esm_integration(&self) -> bool {
574591
match self {
575592
OutputMode::Bundler { .. }

crates/cli/src/bin/wasm-bindgen.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Options:
2222
--out-dir DIR Output directory
2323
--out-name VAR Set a custom output filename (Without extension. Defaults to crate name)
2424
--target TARGET What type of output to generate, valid
25-
values are [web, bundler, nodejs, no-modules],
25+
values are [web, bundler, nodejs, no-modules, deno],
2626
and the default is [bundler]
2727
--no-modules-global VAR Name of the global variable to initialize
2828
--browser Hint that JS should only be compatible with a browser
@@ -98,6 +98,7 @@ fn rmain(args: &Args) -> Result<(), Error> {
9898
"web" => b.web(true)?,
9999
"no-modules" => b.no_modules(true)?,
100100
"nodejs" => b.nodejs(true)?,
101+
"deno" => b.deno(true)?,
101102
s => bail!("invalid encode-into mode: `{}`", s),
102103
};
103104
}

0 commit comments

Comments
 (0)