diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 614a5d12278..aafb1c2fe26 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -339,7 +339,7 @@ impl<'a> Context<'a> { module_name: &str, needs_manual_start: bool, ) -> Result<(String, String, Option), Error> { - let mut ts = self.typescript.clone(); + let mut ts; let mut js = String::new(); let mut start = None; @@ -441,6 +441,16 @@ impl<'a> Context<'a> { } } + // Before putting the static init code declaration info, put all existing typescript into a `wasm_bindgen` namespace declaration. + // Not sure if this should happen in all cases, so just adding it to NoModules for now... + if self.config.mode.no_modules() { + ts = String::from("declare namespace wasm_bindgen {\n\t"); + ts.push_str(&self.typescript.replace("\n", "\n\t")); + ts.push_str("\n}\n"); + } else { + ts = self.typescript.clone(); + } + let (init_js, init_ts) = init; ts.push_str(&init_ts); @@ -556,11 +566,23 @@ impl<'a> Context<'a> { ("", "") }; let arg_optional = if has_module_or_path_optional { "?" } else { "" }; + // With TypeScript 3.8.3, I'm seeing that any "export"s at the root level cause TypeScript to ignore all "declare" statements. + // So using "declare" everywhere for at least the NoModules option. + // Also in (at least) the NoModules, the `init()` method is renamed to `wasm_bindgen()`. + let setup_function_declaration; + let declare_or_export; + if self.config.mode.no_modules() { + declare_or_export = "declare"; + setup_function_declaration = "declare function wasm_bindgen"; + } else { + declare_or_export = "export"; + setup_function_declaration = "export default function init"; + } Ok(format!( "\n\ - export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;\n\ + {declare_or_export} type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;\n\ \n\ - export interface InitOutput {{\n\ + {declare_or_export} interface InitOutput {{\n\ {output}}}\n\ \n\ /**\n\ @@ -572,11 +594,12 @@ impl<'a> Context<'a> { *\n\ * @returns {{Promise}}\n\ */\n\ - export default function init \ - (module_or_path{}: InitInput | Promise{}): Promise; - ", + {setup_function_declaration} \ + (module_or_path{}: InitInput | Promise{}): Promise;\n", memory_doc, arg_optional, memory_param, output = output, + declare_or_export = declare_or_export, + setup_function_declaration = setup_function_declaration, )) } diff --git a/crates/typescript-tests/.gitignore b/crates/typescript-tests/.gitignore index 2dfbe6f5bc4..834c04dd11a 100644 --- a/crates/typescript-tests/.gitignore +++ b/crates/typescript-tests/.gitignore @@ -1,2 +1,4 @@ pkg dist +src_no_modules +dist_no_modules diff --git a/crates/typescript-tests/no_modules.tsconfig.json b/crates/typescript-tests/no_modules.tsconfig.json new file mode 100644 index 00000000000..e3688b7d156 --- /dev/null +++ b/crates/typescript-tests/no_modules.tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "es6", + "noImplicitAny": true, + "sourceMap": true, + "outDir": "dist_no_modules", + }, + "include": [ + "pkg/no_modules/*.d.ts", + "src_no_modules/*.ts", + ] +} diff --git a/crates/typescript-tests/run.sh b/crates/typescript-tests/run.sh index 95a868a58e6..f971f251bf2 100755 --- a/crates/typescript-tests/run.sh +++ b/crates/typescript-tests/run.sh @@ -23,3 +23,37 @@ if [ ! -d node_modules ]; then fi npm run tsc + +# Build using no-modules. +mkdir pkg/no_modules +cargo run -p wasm-bindgen-cli --bin wasm-bindgen -- \ + ../../target/wasm32-unknown-unknown/debug/typescript_tests.wasm \ + --out-dir pkg/no_modules \ + --target no-modules \ + --typescript + +# Then create copies of the TypeScript tests used on "--target web" (i.e. those in ./src) but adjust them to work with "--target no-modules". +# Store the new generated test files under "src_no_modules". +rm -rf src_no_modules +mkdir src_no_modules +cd src +for filename in *.ts; do + if grep -q "_bg.wasm" "$filename" + then + # I am unsure how to import or test the "*_bg.wasm" file. + # So any test file that includes those is currently being skipped. + echo "Ignoring $filename as it uses the *.wasm.d.ts file." + else + path="../src_no_modules/$filename" + # Copy over every line EXCEPT for the import statements (since "no-modules" has no modules to import). + grep -v -w "import" "$filename" > "$path" + # Then replace all of the instances of "wbg" (the namespace all the tests use to import the *.d.ts files from "--target web") with "wasm_bindgen" (the namespace the `no-modules` *.d.ts files use). + sed -i "s/wbg\./wasm_bindgen./g" "$path" + sed -i "s/wbg /wasm_bindgen /g" "$path" + sed -i "s/wbg\[/wasm_bindgen[/g" "$path" + fi +done +cd .. + +# Then try to build the typescript in the src_no_modules folder against the pkg/no_modules build. +npm run tsc -- -p no_modules.tsconfig.json