Skip to content

Build and test portable JavaScript/rustwasm πŸ¦€ modules

License

Notifications You must be signed in to change notification settings

w3reality/es-pack-js

Repository files navigation

es-pack-js

NPM MIT licensed CI

Build and test portable JavaScript/rustwasm modules

Getting started

In this section, we demonstrate how to generate standalone umd/esm modules starting with a minimal NPM project.

Setting up in a new NPM project

$ mkdir add
$ cd add
$ npm init

$ npm config set script-shell bash  # (required if using Windows)

$ npm i -D es-pack-js  # ⬇️

Invoking the es-pack command

$ npx es-pack  # invokes ./node_modules/es-pack-js/bin/es-pack
es-pack 0.3.5
usage: es-pack <Command> [Options]

Commands:
  es-pack build  Build modules
  es-pack test   Test modules
  es-pack help   Show help

Options:
  --help, -h  Show help                                                [boolean]

Building an UMD module

$ mkdir src
$ echo 'export default function add(x, y) { return x + y; }' > src/index.js
$ npx es-pack build
es-pack 0.3.5

task-bundle: πŸŒ€ spinning...
6/10/2020, 2:51:00 PM (1115ms) | output path: /Users/foo/add/target
✨ add.min.js (1276 bytes) [emitted]
task-bundle: βœ… done

Exercising the UMD module with NodeJS

$ node
Welcome to Node.js v12.16.1.
Type ".help" for more information.
> f = require('./target/add.min')
[Function: r]
> f(1, 2)
3

Building modules with the -m option

$ npx es-pack build -m umd esm esm-compat
es-pack 0.3.5

task-bundle: πŸŒ€ spinning...
6/10/2020, 2:57:08 PM (1021ms) | output path: /Users/foo/add/target
✨ add.min.js (1276 bytes) [emitted]
task-bundle: βœ… done

task-bundle: πŸŒ€ spinning...
6/10/2020, 2:57:08 PM (278ms) | output path: /Users/foo/add/target
✨ add.esm.js (1062 bytes) [emitted]
task-bundle: βœ… done

task-bundle: πŸŒ€ spinning...
6/10/2020, 2:57:08 PM (252ms) | output path: /Users/foo/add/target
✨ add.esm.compat.js (1419 bytes) [emitted]
task-bundle: βœ… done

More options

$ npx es-pack build -h
es-pack 0.5.0
usage: es-pack build [<path>=.] [Options]

Options:
  -h, -h, --help               Show help                               [boolean]
  -m, --module                 Set output module type (`umd`, `esm`,
                               `esm-compat`)            [array] [default: "umd"]
      --dev                    Toggle behavior as `webpack --mode development
                               --watch`               [boolean] [default: false]
      --dev-with-tts           `--dev` with audio feedback
                                                      [boolean] [default: false]
  -d, --out-dir                Set output directory (`<path>/target`, otherwise)
      --lib-name               Set output module file name (e.g. "foo-bar-js")
      --libobj-name            Set library object name (e.g. "FooBarJs")
      --bundle-analyzer, --ba  Enable `webpack-bundle-analyzer` plugin
                                                      [boolean] [default: false]
      --verify                 Verify basic assumptions against built modules
                                                      [boolean] [default: false]
      --rustwasm               Toggle `rustwasm` mode [boolean] [default: false]
      --debug                  Print debug log and keep intermediate output
                                                      [boolean] [default: false]

Windows

Requirement

Before installing es-pack-js, it is required to run:

$ npm config set script-shell bash

Limitations

The following command invocations do nothing:

  • es-pack build subcommand with --verify option
  • es-pack test subcommand

The --rustwasm mode

We can transform artifacts generated by wasm-pack into a standalone umd/esm module that is loadable via browser/Node.js as follows:

$ wasm-pack build --target no-modules
$ es-pack build --rustwasm

To illustrate in detail, we use this minimal Rust crate: examples/rustwasm-add

wasm-pack build --target no-modules
$ wasm-pack build --target no-modules
[INFO]: 🎯  Checking for the Wasm target...
[INFO]: πŸŒ€  Compiling to Wasm...
   Compiling proc-macro2 v1.0.24
   Compiling unicode-xid v0.2.1
   Compiling log v0.4.11
   Compiling syn v1.0.58
   Compiling wasm-bindgen-shared v0.2.69
   Compiling cfg-if v0.1.10
   Compiling bumpalo v3.4.0
   Compiling lazy_static v1.4.0
   Compiling wasm-bindgen v0.2.69
   Compiling cfg-if v1.0.0
   Compiling quote v1.0.8
   Compiling wasm-bindgen-backend v0.2.69
   Compiling wasm-bindgen-macro-support v0.2.69
   Compiling wasm-bindgen-macro v0.2.69
   Compiling add v0.1.0 (/Users/foo/es-pack-js/examples/rustwasm-add)
    Finished release [optimized] target(s) in 22.59s
⚠️   [WARN]: origin crate has no README
[INFO]: ⬇️  Installing wasm-bindgen...
[INFO]: Optimizing wasm binaries with `wasm-opt`...
[INFO]: Optional fields missing from Cargo.toml: 'description', 'repository', and 'license'. These are not necessary, but recommended
[INFO]: ✨   Done in 23.24s
[INFO]: πŸ“¦   Your wasm pkg is ready to publish at /Users/foo/es-pack-js/examples/rustwasm-add/pkg.

es-pack build --rustwasm
$ es-pack build --rustwasm
es-pack 0.5.1-dev.0

task-bundle: πŸŒ€ spinning...
2/8/2021, 11:38:49 AM (2,948 ms) | output path: /Users/foo/es-pack-js/examples/rustwasm-add/pkg-es-pack
✨ add.min.js (13,282 bytes) [emitted]
task-bundle: βœ… done

Let's exercise the generated 'add.min.js' (an 'umd' module) in Node.js:

$ node
Welcome to Node.js v14.15.4.
Type ".help" for more information.
> Mod = require('./pkg-es-pack/add.min.js')
[Function: t] { ffi: {} }
> Mod.create({nodejs: true}).then(mod => console.log(mod.add(2, 2)))
Promise { <pending> }
> 4

Similarly, like in this demo project, we can also generate an 'esm' module with:

$ es-pack build --rustwasm -m esm

πŸ’‘ As a more advanced example using the rustwasm mode, we have examples/rustwasm-ffi, where we show how to call JavaScript FFI from within Rust code.