Skip to content

Commit

Permalink
Add electron support via --omit-imports and --preloads
Browse files Browse the repository at this point in the history
  • Loading branch information
darinmorrison committed Jan 16, 2020
1 parent 580daab commit 50b8a12
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 5 deletions.
61 changes: 58 additions & 3 deletions crates/cli-support/src/js/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ pub struct ExportedClass {
typescript_fields: HashMap<String, (String, bool)>,
}

pub struct Finalized {
/// Finalized JavaScript code
pub js: String,
/// Finalized TypeScript declarations
pub ts: String,
/// Finalized Electron preloads
pub ps: String,
}

const INITIAL_HEAP_VALUES: &[&str] = &["undefined", "null", "true", "false"];
// Must be kept in sync with `src/lib.rs` of the `wasm-bindgen` crate
const INITIAL_HEAP_OFFSET: usize = 32;
Expand Down Expand Up @@ -167,7 +176,7 @@ impl<'a> Context<'a> {
Ok(())
}

pub fn finalize(&mut self, module_name: &str) -> Result<(String, String), Error> {
pub fn finalize(&mut self, module_name: &str) -> Result<Finalized, Error> {
// Finalize all bindings for JS classes. This is where we'll generate JS
// glue for all classes as well as finish up a few final imports like
// `__wrap` and such.
Expand All @@ -194,7 +203,7 @@ impl<'a> Context<'a> {
&mut self,
module_name: &str,
needs_manual_start: bool,
) -> Result<(String, String), Error> {
) -> Result<Finalized, Error> {
let mut ts = self.typescript.clone();
let mut js = String::new();
if self.config.mode.no_modules() {
Expand Down Expand Up @@ -310,11 +319,18 @@ impl<'a> Context<'a> {
js = js.replace("\n\n\n", "\n\n");
}

Ok((js, ts))
let ps = self.generate_preloads();

Ok(Finalized { js, ts, ps })
}

fn js_import_header(&self) -> Result<String, Error> {
let mut imports = String::new();

if self.config.omit_imports {
return Ok(imports)
}

match &self.config.mode {
OutputMode::NoModules { .. } => {
for (module, _items) in self.js_imports.iter() {
Expand Down Expand Up @@ -369,9 +385,48 @@ impl<'a> Context<'a> {
}
}
}

Ok(imports)
}

fn generate_preloads(&self) -> String {
let mut ps = String::new();
if self.config.preloads {
for (module, items) in crate::sorted_iter(&self.js_imports) {
ps.push_str("const { ");
for (i, (item, rename)) in items.iter().enumerate() {
if i > 0 {
ps.push_str(", ");
}
ps.push_str(item);
if let Some(other) = rename {
ps.push_str(": ");
ps.push_str(other)
}
}
ps.push_str(" } = require(String.raw`");
ps.push_str(module);
ps.push_str("`);\n");
}
ps.push_str("\nprocess.once('loaded', () => {\n");
for (_module, items) in crate::sorted_iter(&self.js_imports) {
for (_i, (item, rename)) in items.iter().enumerate() {
let mut name: &str = item;
if let Some(other) = rename {
name = other;
}
ps.push_str(" global.");
ps.push_str(name);
ps.push_str(" = ");
ps.push_str(name);
ps.push_str(";\n");
}
}
ps.push_str("});");
}
ps
}

fn ts_for_init_fn(has_memory: bool, has_module_or_path_optional: bool) -> String {
let (memory_doc, memory_param) = if has_memory {
(
Expand Down
26 changes: 25 additions & 1 deletion crates/cli-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub struct Bindgen {
mode: OutputMode,
debug: bool,
typescript: bool,
omit_imports: bool,
preloads: bool,
demangle: bool,
keep_debug: bool,
remove_name_section: bool,
Expand Down Expand Up @@ -58,10 +60,12 @@ struct JsGenerated {
mode: OutputMode,
js: String,
ts: String,
ps: String,
snippets: HashMap<String, Vec<String>>,
local_modules: HashMap<String, String>,
npm_dependencies: HashMap<String, (PathBuf, String)>,
typescript: bool,
preloads: bool,
}

#[derive(Clone)]
Expand Down Expand Up @@ -97,6 +101,8 @@ impl Bindgen {
},
debug: false,
typescript: false,
omit_imports: false,
preloads: false,
demangle: true,
keep_debug: false,
remove_name_section: false,
Expand Down Expand Up @@ -222,6 +228,16 @@ impl Bindgen {
self
}

pub fn omit_imports(&mut self, omit_imports: bool) -> &mut Bindgen {
self.omit_imports = omit_imports;
self
}

pub fn preloads(&mut self, preloads: bool) -> &mut Bindgen {
self.preloads = preloads;
self
}

pub fn demangle(&mut self, demangle: bool) -> &mut Bindgen {
self.demangle = demangle;
self
Expand Down Expand Up @@ -412,15 +428,17 @@ impl Bindgen {
.unwrap();
let mut cx = js::Context::new(&mut module, self, &adapters, &aux)?;
cx.generate()?;
let (js, ts) = cx.finalize(stem)?;
let js::Finalized { js, ts, ps } = cx.finalize(stem)?;
Generated::Js(JsGenerated {
snippets: aux.snippets.clone(),
local_modules: aux.local_modules.clone(),
mode: self.mode.clone(),
typescript: self.typescript,
preloads: self.preloads,
npm_dependencies: cx.npm_dependencies.clone(),
js,
ts,
ps,
})
};

Expand Down Expand Up @@ -674,6 +692,12 @@ impl Output {
.with_context(|| format!("failed to write `{}`", ts_path.display()))?;
}

if gen.preloads {
let ps_path = out_dir.join("preloads").with_extension(extension);
fs::write(&ps_path, &gen.ps)
.with_context(|| format!("failed to write `{}`", ps_path.display()))?;
}

Ok(())
}
}
Expand Down
8 changes: 7 additions & 1 deletion crates/cli/src/bin/wasm-bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ Options:
--browser Hint that JS should only be compatible with a browser
--typescript Output a TypeScript definition file (on by default)
--no-typescript Don't emit a *.d.ts file
--omit-imports Don't emit imports in generated JavaScript
--preloads Output an Electron preloads file
--debug Include otherwise-extraneous debug checks in output
--no-demangle Don't demangle Rust symbol names
--keep-debug Keep debug sections in wasm files
Expand All @@ -49,6 +51,8 @@ struct Args {
flag_no_modules: bool,
flag_typescript: bool,
flag_no_typescript: bool,
flag_omit_imports: bool,
flag_preloads: bool,
flag_out_dir: Option<PathBuf>,
flag_out_name: Option<String>,
flag_debug: bool,
Expand Down Expand Up @@ -109,7 +113,9 @@ fn rmain(args: &Args) -> Result<(), Error> {
.keep_debug(args.flag_keep_debug)
.remove_name_section(args.flag_remove_name_section)
.remove_producers_section(args.flag_remove_producers_section)
.typescript(typescript);
.typescript(typescript)
.omit_imports(args.flag_omit_imports)
.preloads(args.flag_preloads);
if let Some(ref name) = args.flag_no_modules_global {
b.no_modules_global(name)?;
}
Expand Down
11 changes: 11 additions & 0 deletions guide/src/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ is on by default.
By default, a `*.d.ts` TypeScript declaration file is generated for the
generated JavaScript bindings, but this flag will disable that.

### `--omit-imports`

Omit the imports header section from the generated JavaScript.

### `--preloads`

Output an Electron preloads file corresponding to the imports from the generated
JavaScript. This, in conjunction with `--omit-imports`, is intended to be used
for Electron renderer process scripts when node integration is disabled. This
feature is EXPERIMENTAL and may be subject to change or removal in the future.

### `--debug`

Generates a bit more JS and wasm in "debug mode" to help catch programmer
Expand Down

0 comments on commit 50b8a12

Please sign in to comment.