Skip to content

Commit

Permalink
Switch the --browser argument to --web
Browse files Browse the repository at this point in the history
This commit reverts part of the implementation of [RFC 6]. That RFC
specified that the `--browser` flag was going to be repurposed for the
new "natively loadable as ES module output", but unfortunately the
breakage is far broader than initially expected. It turns out that
`wasm-pack` passes `--browser` by default which means that a change to
break `--browser` would break all historical versions of `wasm-pack`
which is a bit much for now.

To solve this the `--browser` flag is going back to what it represents
on the current released version of `wasm-bindgen` (optimize away some
node.js checks in a few places for bundler-style output) and a new
`--web` flag is being introduced as the new deployment strategy.

[RFC 6]: rustwasm/rfcs#6

Closes rustwasm#1318
  • Loading branch information
alexcrichton committed Mar 7, 2019
1 parent 79a8c5d commit cd3781c
Show file tree
Hide file tree
Showing 12 changed files with 70 additions and 45 deletions.
20 changes: 10 additions & 10 deletions crates/cli-support/src/js/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ impl<'a> Context<'a> {
format!("__exports.{} = {};\n", name, contents)
}
}
OutputMode::Bundler
OutputMode::Bundler { .. }
| OutputMode::Node {
experimental_modules: true,
} => {
Expand All @@ -178,7 +178,7 @@ impl<'a> Context<'a> {
format!("export const {} = {};\n", name, contents)
}
}
OutputMode::Browser => {
OutputMode::Web => {
// In browser mode there's no need to export the internals of
// wasm-bindgen as we're not using the module itself as the
// import object but rather the `__exports` map we'll be
Expand All @@ -202,7 +202,7 @@ impl<'a> Context<'a> {
};
self.global(&global);

if self.config.mode.browser() {
if self.config.mode.web() {
self.global(&format!("__exports.{} = {0};", name));
}
}
Expand Down Expand Up @@ -300,7 +300,7 @@ impl<'a> Context<'a> {
}

/// Performs the task of actually generating the final JS module, be it
/// `--no-modules`, `--browser`, or for bundlers. This is the very last step
/// `--no-modules`, `--web`, or for bundlers. This is the very last step
/// performed in `finalize`.
fn finalize_js(&mut self, module_name: &str, needs_manual_start: bool) -> (String, String) {
let mut js = String::new();
Expand Down Expand Up @@ -340,7 +340,7 @@ impl<'a> Context<'a> {
// 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.
OutputMode::Bundler
OutputMode::Bundler { .. }
| OutputMode::Node {
experimental_modules: true,
} => {
Expand All @@ -354,7 +354,7 @@ impl<'a> Context<'a> {
// browsers don't support natively importing wasm right now so we
// expose the same initialization function as `--no-modules` as the
// default export of the module.
OutputMode::Browser => {
OutputMode::Web => {
js.push_str("const __exports = {};\n");
self.imports_post.push_str("let wasm;\n");
init = self.gen_init(&module_name, needs_manual_start);
Expand Down Expand Up @@ -752,10 +752,10 @@ impl<'a> Context<'a> {
})?;

self.bind("__wbindgen_module", &|me| {
if !me.config.mode.no_modules() && !me.config.mode.browser() {
if !me.config.mode.no_modules() && !me.config.mode.web() {
bail!(
"`wasm_bindgen::module` is currently only supported with \
--no-modules"
--no-modules and --web"
);
}
Ok(format!(
Expand Down Expand Up @@ -2843,13 +2843,13 @@ impl<'a, 'b> SubContext<'a, 'b> {
if is_local_snippet {
bail!(
"local JS snippets are not supported with `--no-modules`; \
use `--browser` or no flag instead",
use `--web` or no flag instead",
);
}
if let decode::ImportModule::Named(module) = &import.module {
bail!(
"import from `{}` module not allowed with `--no-modules`; \
use `--nodejs`, `--browser`, or no flag instead",
use `--nodejs`, `--web`, or no flag instead",
module
);
}
Expand Down
31 changes: 21 additions & 10 deletions crates/cli-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ pub struct Bindgen {
}

enum OutputMode {
Bundler,
Browser,
Bundler { browser_only: bool },
Web,
NoModules { global: String },
Node { experimental_modules: bool },
}
Expand All @@ -59,7 +59,7 @@ impl Bindgen {
Bindgen {
input: Input::None,
out_name: None,
mode: OutputMode::Bundler,
mode: OutputMode::Bundler { browser_only: false },
debug: false,
typescript: false,
demangle: true,
Expand Down Expand Up @@ -93,7 +93,7 @@ impl Bindgen {

fn switch_mode(&mut self, mode: OutputMode, flag: &str) -> Result<(), Error> {
match self.mode {
OutputMode::Bundler => self.mode = mode,
OutputMode::Bundler { .. } => self.mode = mode,
_ => bail!(
"cannot specify `{}` with another output mode already specified",
flag
Expand Down Expand Up @@ -126,9 +126,9 @@ impl Bindgen {
Ok(self)
}

pub fn browser(&mut self, browser: bool) -> Result<&mut Bindgen, Error> {
if browser {
self.switch_mode(OutputMode::Browser, "--browser")?;
pub fn web(&mut self, web: bool) -> Result<&mut Bindgen, Error> {
if web {
self.switch_mode(OutputMode::Web, "--web")?;
}
Ok(self)
}
Expand All @@ -145,6 +145,16 @@ impl Bindgen {
Ok(self)
}

pub fn browser(&mut self, browser: bool) -> Result<&mut Bindgen, Error> {
if browser {
match &mut self.mode {
OutputMode::Bundler { browser_only } => *browser_only = true,
_ => bail!("cannot specify `--browser` with other output types"),
}
}
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 @@ -660,15 +670,16 @@ impl OutputMode {

fn always_run_in_browser(&self) -> bool {
match self {
OutputMode::Browser => true,
OutputMode::Web => true,
OutputMode::NoModules { .. } => true,
OutputMode::Bundler { browser_only } => *browser_only,
_ => false,
}
}

fn browser(&self) -> bool {
fn web(&self) -> bool {
match self {
OutputMode::Browser => true,
OutputMode::Web => true,
_ => false,
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/src/bin/wasm-bindgen-test-runner/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ fn rmain() -> Result<(), Error> {
let mut b = Bindgen::new();
b.debug(debug)
.nodejs(node)?
.browser(!node)?
.web(!node)?
.input_module(module, wasm)
.keep_debug(false)
.emit_start(false)
Expand Down
5 changes: 4 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,8 @@ Options:
--out-dir DIR Output directory
--out-name VAR Set a custom output filename (Without extension. Defaults to crate name)
--nodejs Generate output that only works in node.js
--browser Generate output that only works in a browser
--web Generate output that only works in a browser
--browser Hint that JS should only be compatible with a browser
--no-modules Generate output that only works in a browser (without modules)
--no-modules-global VAR Name of the global variable to initialize
--typescript Output a TypeScript definition file (on by default)
Expand All @@ -41,6 +42,7 @@ Options:
struct Args {
flag_nodejs: bool,
flag_browser: bool,
flag_web: bool,
flag_no_modules: bool,
flag_typescript: bool,
flag_no_typescript: bool,
Expand Down Expand Up @@ -89,6 +91,7 @@ fn rmain(args: &Args) -> Result<(), Error> {
let mut b = Bindgen::new();
b.input_path(input)
.nodejs(args.flag_nodejs)?
.web(args.flag_web)?
.browser(args.flag_browser)?
.no_modules(args.flag_no_modules)?
.debug(args.flag_debug)
Expand Down
4 changes: 2 additions & 2 deletions examples/without-a-bundler-no-modules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ and then opening `index.html` in a browser should run the example!

Note that this example is in contrast to the [without a bundler][wab] example
which performs a similar purpose except it uses `--no-modules` instead of
`--browser`. The main difference here is how the shim JS and module are loaded,
where this example uses old-school `script` tags while `--browser` uses ES
`--web`. The main difference here is how the shim JS and module are loaded,
where this example uses old-school `script` tags while `--web` uses ES
modules.

[wab]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/without-a-bundler
4 changes: 2 additions & 2 deletions examples/without-a-bundler-no-modules/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<script src='pkg/without_a_bundler_no_modules.js'></script>

<script type=module>
// Like with the `--browser` output the exports are immediately available
// but they won't work until we initialize the module. Unlike `--browser`,
// Like with the `--web` output the exports are immediately available
// but they won't work until we initialize the module. Unlike `--web`,
// however, the globals are all stored on a `wasm_bindgen` global. The
// global itself is the initialization function and then the properties of
// the global are all the exported functions.
Expand Down
2 changes: 1 addition & 1 deletion examples/without-a-bundler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ $ cargo build --target wasm32-unknown-unknown --release
$ cargo run -p wasm-bindgen-cli --bin wasm-bindgen -- \
../../target/wasm32-unknown-unknown/release/without_a_bundler.wasm \
--out-dir pkg \
--browser
--web
```

and then opening `index.html` in a browser should run the example!
4 changes: 2 additions & 2 deletions examples/without-a-bundler/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
set -ex

# Note that typically we'd use `wasm-pack` to build the crate, but the
# `--browser` flag is very new to `wasm-bindgen` and as such doesn't have
# `--web` flag is very new to `wasm-bindgen` and as such doesn't have
# support in `wasm-pack` yet. Support will be added soon though!

cargo build --target wasm32-unknown-unknown --release
cargo run --manifest-path ../../crates/cli/Cargo.toml \
--bin wasm-bindgen -- \
../../target/wasm32-unknown-unknown/release/without_a_bundler.wasm --out-dir pkg \
--browser
--web

python3 -m http.server
8 changes: 4 additions & 4 deletions guide/src/examples/without-a-bundler.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/without-a-bundler

This example shows how the `--browser` flag can be used load code in a
This example shows how the `--web` flag can be used load code in a
browser directly. For this deployment strategy bundlers like Webpack are not
required. For more information on deployment see the [dedicated
documentation][deployment].

> **Note**: the `--browser` flag is quite new to `wasm-bindgen`, and does not
> **Note**: the `--web` flag is quite new to `wasm-bindgen`, and does not
> currently have support in `wasm-pack` yet. Support will be added soon though!
First let's take a look at the code and see how when we're using `--browser`
First let's take a look at the code and see how when we're using `--web`
we're not actually losing any functionality!

```rust
Expand Down Expand Up @@ -40,7 +40,7 @@ The older version of using `wasm-bindgen` without a bundler is to use the
`--no-modules` flag to the `wasm-bindgen` CLI. This corresponds to `--target
no-modules` in `wasm-pack`.

While similar to the newer `--browser`, the `--no-modules` flag has a few
While similar to the newer `--web`, the `--no-modules` flag has a few
caveats:

* It does not support [local JS snippets][snippets]
Expand Down
23 changes: 17 additions & 6 deletions guide/src/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,17 @@ usage of `require` of the generated JS and internally using `require` instead of
ECMAScript modules. When using this flag no further postprocessing (aka a
bundler) should be necessary to work with the wasm.

### `--browser`
For more information about this see the section on [deployment]

[deployment]: deployment.html

### `--web`

This flag will generate output suitable for loading natively in browsers today.
The generated JS shims are an ES module which export a `default` instantiation
function, like `--no-modules` below.

This flag will tailor the output specifically for browsers, making it
incompatible with Node. This will basically make the generated JS a tiny bit
smaller as runtime checks for Node won't be necessary.
For more information about this see the section on [deployment]

### `--no-modules` and `--no-modules-global VAR`

Expand All @@ -44,8 +50,7 @@ tailored for a properties on the JavaScript global object (e.g. `window`).
The `--no-modules-global VAR` option makes `VAR` the global property that the
JavaScript bindings are attached to.

More information can be found in the [documentation for building without
ECMAScript modules](./no-esm.html).
For more information about this see the section on [deployment]

### `--typescript`

Expand All @@ -71,3 +76,9 @@ When post-processing the `.wasm` binary, do not demangle Rust symbols in the

When post-processing the `.wasm` binary, do not strip DWARF debug info custom
sections.

### `--browser`

When generating bundler-compatible code (see the section on [deployment]) this
indicates that the bundled code is always intended to go into a browser so a few
checks for Node.js can be elided.
10 changes: 5 additions & 5 deletions guide/src/reference/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ necessary.

If you're not using a bundler but you're still running code in a web browser,
`wasm-bindgen` still supports this! For this use case you'll want to use the
`--browser` flag. You can check out a [full example][nomex] in the
`--web` flag. You can check out a [full example][nomex] in the
documentation, but the highlights of this output are:

* When using `wasm-bindgen` directly you'll pass `--browser`.
* When using `wasm-bindgen` directly you'll pass `--web`.
* The output can natively be included on a web page, and doesn't require any
further postprocessing. The output is included as an ES module.
* The `--browser` mode is not able to use NPM dependencies.
* The `--web` mode is not able to use NPM dependencies.
* You'll want to review the [browser requirements] for `wasm-bindgen` because
no polyfills will be available.

> **Note**: currently `--browser` is not supported in `wasm-pack` because it is
> **Note**: currently `--web` is not supported in `wasm-pack` because it is
> a very recent addition to `wasm-bindgen`, but support will be added soon!
[nomex]: ../examples/without-a-bundler.html
Expand All @@ -48,7 +48,7 @@ documentation, but the highlights of this output are:
[browser requirements]: browser-support.html

The `wasm-bindgen` CLI also supports an output mode called `--no-modules` which
is similar to `--browser` in that it requires manual initialization of the wasm
is similar to `--web` in that it requires manual initialization of the wasm
and is intended to be included in web pages without any further postprocessing.
See the [without a bundler example][nomex] for some more information about
`--no-modules`, which corresponds to `--target no-modules` in `wasm-pack`.
Expand Down
2 changes: 1 addition & 1 deletion guide/src/reference/js-snippets.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ are important to be aware of. Many of these are temporary though!
this. For now, though, js snippets must be standalone modules and can't import
from anything else.

* Only `--browser` and the default bundler output mode are supported. To support
* Only `--web` and the default bundler output mode are supported. To support
`--nodejs` we'd need to translate ES module syntax to CommonJS (this is
planned to be done, just hasn't been done yet). Additionally to support
`--no-modules` we'd have to similarly translate from ES modules to something
Expand Down

0 comments on commit cd3781c

Please sign in to comment.