mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-17 23:11:23 +00:00
Dramatically improving the build time of web-sys (#2012)
* Pre-generating web-sys * Fixing build errors * Minor refactor for the unit tests * Changing to generate #[wasm_bindgen} annotations * Fixing code generation * Adding in main bin to wasm-bindgen-webidl * Fixing more problems * Adding in support for unstable APIs * Fixing bug with code generation * More code generation fixes * Improving the webidl program * Removing unnecessary cfg from the generated code * Splitting doc comments onto separate lines * Improving the generation for unstable features * Adding in support for string values in enums * Now runs rustfmt on the mod.rs file * Fixing codegen for constructors * Fixing webidl-tests * Fixing build errors * Another fix for build errors * Renaming typescript_name to typescript_type * Adding in docs for typescript_type * Adding in CI script to verify that web-sys is up to date * Fixing CI script * Fixing CI script * Don't suppress git diff output * Remove duplicate definitions of `Location` Looks to be a preexisting bug in wasm-bindgen? * Regenerate webidl * Try to get the git diff command right * Handle named constructors in WebIDL * Remove stray rustfmt.toml * Add back NamedConstructorBar definition in tests * Run stable rustfmt over everything * Don't run Cargo in a build script Instead refactor things so webidl-tests can use the Rust-code-generation as a library in a build script. Also fixes `cargo fmt` in the repository. * Fixup generated code * Running web-sys checks on stable * Improving the code generation a little * Running rustfmt Co-authored-by: Alex Crichton <alex@alexcrichton.com>
This commit is contained in:
@ -4,7 +4,7 @@ use crate::wit::{Adapter, AdapterId, AdapterJsImportKind, AuxValue};
|
||||
use crate::wit::{AdapterKind, Instruction, InstructionData};
|
||||
use crate::wit::{AuxEnum, AuxExport, AuxExportKind, AuxImport, AuxStruct};
|
||||
use crate::wit::{JsImport, JsImportName, NonstandardWitSection, WasmBindgenAux};
|
||||
use crate::{Bindgen, EncodeInto, OutputMode};
|
||||
use crate::{reset_indentation, Bindgen, EncodeInto, OutputMode, PLACEHOLDER_MODULE};
|
||||
use anyhow::{anyhow, bail, Context as _, Error};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
@ -188,6 +188,85 @@ impl<'a> Context<'a> {
|
||||
self.finalize_js(module_name, needs_manual_start)
|
||||
}
|
||||
|
||||
fn generate_node_imports(&self) -> String {
|
||||
let mut imports = BTreeSet::new();
|
||||
for import in self.module.imports.iter() {
|
||||
imports.insert(&import.module);
|
||||
}
|
||||
|
||||
let mut shim = String::new();
|
||||
|
||||
shim.push_str("let imports = {};\n");
|
||||
|
||||
if self.config.mode.nodejs_experimental_modules() {
|
||||
for (i, module) in imports.iter().enumerate() {
|
||||
if module.as_str() != PLACEHOLDER_MODULE {
|
||||
shim.push_str(&format!("import * as import{} from '{}';\n", i, module));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i, module) in imports.iter().enumerate() {
|
||||
if module.as_str() == PLACEHOLDER_MODULE {
|
||||
shim.push_str(&format!(
|
||||
"imports['{0}'] = module.exports;\n",
|
||||
PLACEHOLDER_MODULE
|
||||
));
|
||||
} else {
|
||||
if self.config.mode.nodejs_experimental_modules() {
|
||||
shim.push_str(&format!("imports['{}'] = import{};\n", module, i));
|
||||
} else {
|
||||
shim.push_str(&format!("imports['{0}'] = require('{0}');\n", module));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset_indentation(&shim)
|
||||
}
|
||||
|
||||
fn generate_node_wasm_loading(&self, path: &Path) -> String {
|
||||
let mut shim = String::new();
|
||||
|
||||
if self.config.mode.nodejs_experimental_modules() {
|
||||
// On windows skip the leading `/` which comes out when we parse a
|
||||
// url to use `C:\...` instead of `\C:\...`
|
||||
shim.push_str(&format!(
|
||||
"
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as url from 'url';
|
||||
import * as process from 'process';
|
||||
|
||||
let file = path.dirname(url.parse(import.meta.url).pathname);
|
||||
if (process.platform === 'win32') {{
|
||||
file = file.substring(1);
|
||||
}}
|
||||
const bytes = fs.readFileSync(path.join(file, '{}'));
|
||||
",
|
||||
path.file_name().unwrap().to_str().unwrap()
|
||||
));
|
||||
} else {
|
||||
shim.push_str(&format!(
|
||||
"
|
||||
const path = require('path').join(__dirname, '{}');
|
||||
const bytes = require('fs').readFileSync(path);
|
||||
",
|
||||
path.file_name().unwrap().to_str().unwrap()
|
||||
));
|
||||
}
|
||||
|
||||
shim.push_str(
|
||||
"
|
||||
const wasmModule = new WebAssembly.Module(bytes);
|
||||
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
|
||||
wasm = wasmInstance.exports;
|
||||
module.exports.__wasm = wasm;
|
||||
",
|
||||
);
|
||||
|
||||
reset_indentation(&shim)
|
||||
}
|
||||
|
||||
/// 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`.
|
||||
@ -224,11 +303,12 @@ impl<'a> Context<'a> {
|
||||
OutputMode::Node {
|
||||
experimental_modules: false,
|
||||
} => {
|
||||
js.push_str(&self.generate_node_imports());
|
||||
|
||||
js.push_str("let wasm;\n");
|
||||
|
||||
for (id, js) in crate::sorted_iter(&self.wasm_import_definitions) {
|
||||
let import = self.module.imports.get_mut(*id);
|
||||
import.module = format!("./{}.js", module_name);
|
||||
footer.push_str("\nmodule.exports.");
|
||||
footer.push_str(&import.name);
|
||||
footer.push_str(" = ");
|
||||
@ -236,7 +316,13 @@ impl<'a> Context<'a> {
|
||||
footer.push_str(";\n");
|
||||
}
|
||||
|
||||
footer.push_str(&format!("wasm = require('./{}_bg');\n", module_name));
|
||||
footer.push_str(
|
||||
&self.generate_node_wasm_loading(&Path::new(&format!(
|
||||
"./{}_bg.wasm",
|
||||
module_name
|
||||
))),
|
||||
);
|
||||
|
||||
if needs_manual_start {
|
||||
footer.push_str("wasm.__wbindgen_start();\n");
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![doc(html_root_url = "https://docs.rs/wasm-bindgen-cli-support/0.2")]
|
||||
|
||||
use anyhow::{bail, Context, Error};
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::mem;
|
||||
@ -9,6 +9,8 @@ use std::path::{Path, PathBuf};
|
||||
use std::str;
|
||||
use walrus::Module;
|
||||
|
||||
pub(crate) const PLACEHOLDER_MODULE: &str = "__wbindgen_placeholder__";
|
||||
|
||||
mod anyref;
|
||||
mod decode;
|
||||
mod descriptor;
|
||||
@ -667,13 +669,6 @@ impl Output {
|
||||
.with_context(|| format!("failed to write `{}`", ts_path.display()))?;
|
||||
}
|
||||
|
||||
if gen.mode.nodejs() {
|
||||
let js_path = wasm_path.with_extension(extension);
|
||||
let shim = gen.generate_node_wasm_import(&self.module, &wasm_path);
|
||||
fs::write(&js_path, shim)
|
||||
.with_context(|| format!("failed to write `{}`", js_path.display()))?;
|
||||
}
|
||||
|
||||
if gen.typescript {
|
||||
let ts_path = wasm_path.with_extension("d.ts");
|
||||
let ts = wasm2es6js::typescript(&self.module)?;
|
||||
@ -685,77 +680,6 @@ impl Output {
|
||||
}
|
||||
}
|
||||
|
||||
impl JsGenerated {
|
||||
fn generate_node_wasm_import(&self, m: &Module, path: &Path) -> String {
|
||||
let mut imports = BTreeSet::new();
|
||||
for import in m.imports.iter() {
|
||||
imports.insert(&import.module);
|
||||
}
|
||||
|
||||
let mut shim = String::new();
|
||||
|
||||
if self.mode.nodejs_experimental_modules() {
|
||||
for (i, module) in imports.iter().enumerate() {
|
||||
shim.push_str(&format!("import * as import{} from '{}';\n", i, module));
|
||||
}
|
||||
// On windows skip the leading `/` which comes out when we parse a
|
||||
// url to use `C:\...` instead of `\C:\...`
|
||||
shim.push_str(&format!(
|
||||
"
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as url from 'url';
|
||||
import * as process from 'process';
|
||||
|
||||
let file = path.dirname(url.parse(import.meta.url).pathname);
|
||||
if (process.platform === 'win32') {{
|
||||
file = file.substring(1);
|
||||
}}
|
||||
const bytes = fs.readFileSync(path.join(file, '{}'));
|
||||
",
|
||||
path.file_name().unwrap().to_str().unwrap()
|
||||
));
|
||||
} else {
|
||||
shim.push_str(&format!(
|
||||
"
|
||||
const path = require('path').join(__dirname, '{}');
|
||||
const bytes = require('fs').readFileSync(path);
|
||||
",
|
||||
path.file_name().unwrap().to_str().unwrap()
|
||||
));
|
||||
}
|
||||
shim.push_str("let imports = {};\n");
|
||||
for (i, module) in imports.iter().enumerate() {
|
||||
if self.mode.nodejs_experimental_modules() {
|
||||
shim.push_str(&format!("imports['{}'] = import{};\n", module, i));
|
||||
} else {
|
||||
shim.push_str(&format!("imports['{0}'] = require('{0}');\n", module));
|
||||
}
|
||||
}
|
||||
|
||||
shim.push_str(&format!(
|
||||
"
|
||||
const wasmModule = new WebAssembly.Module(bytes);
|
||||
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
|
||||
",
|
||||
));
|
||||
|
||||
if self.mode.nodejs_experimental_modules() {
|
||||
for entry in m.exports.iter() {
|
||||
shim.push_str("export const ");
|
||||
shim.push_str(&entry.name);
|
||||
shim.push_str(" = wasmInstance.exports.");
|
||||
shim.push_str(&entry.name);
|
||||
shim.push_str(";\n");
|
||||
}
|
||||
} else {
|
||||
shim.push_str("module.exports = wasmInstance.exports;\n");
|
||||
}
|
||||
|
||||
reset_indentation(&shim)
|
||||
}
|
||||
}
|
||||
|
||||
fn gc_module_and_adapters(module: &mut Module) {
|
||||
loop {
|
||||
// Fist up, cleanup the native wasm module. Note that roots can come
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::decode;
|
||||
use crate::descriptor::{Descriptor, Function};
|
||||
use crate::descriptors::WasmBindgenDescriptorsSection;
|
||||
use crate::intrinsic::Intrinsic;
|
||||
use crate::{decode, PLACEHOLDER_MODULE};
|
||||
use anyhow::{anyhow, bail, Error};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::str;
|
||||
@ -9,8 +9,6 @@ use walrus::MemoryId;
|
||||
use walrus::{ExportId, FunctionId, ImportId, Module};
|
||||
use wasm_bindgen_shared::struct_function_export_name;
|
||||
|
||||
const PLACEHOLDER_MODULE: &str = "__wbindgen_placeholder__";
|
||||
|
||||
mod incoming;
|
||||
mod nonstandard;
|
||||
mod outgoing;
|
||||
|
Reference in New Issue
Block a user