Skip to content

Commit 4702a06

Browse files
committed
Remove the necessity of installing binaryen separately
Building of the RxPlayer's WebAssembly file previously required: 1. that the Rust compiler toolchain is installed (most likely through `rustup`) and that `cargo` is consequently available as a command globally. 2. that the `wasm32-unknown-unknown` Rust compiler target is added (this is generally just basically a `rustup target add wasm32-unknown-unknown` call once rustup is installed). 3. that the `binaryen` tool is installed and that `wasm-opt` is consequently available as a command globally. It bothered me that we added Rust compiler toolchains requirements for building what is a JavaScript project, even more now that we're considering making it a requirement for the `npm run build` script. To simplify, I try here to remove the need for the third step, which might be the more complex to set up (`binaryen` seems to be available through `brew` for MacOS and it is in the `extra` repository for Arch, but I would guess that many other linux distributions wouldn't have an easy access to it, leading to installing and updating difficulties). To remove it, I rely on a WebAssembly build of binaryen with a JS API on the front, through the `binaryen` npm module. It is quite voluminous (25MB in my `node_modules` directory, making it second after TypeScript) yet it save the need to separately have to install and maintain a separate binary. I then added the `script/wasm-optimize.mjs` script to interface with that npm module and called it through the `npm run build:wasm:release` script, which should completely replace the need for binaryen.
1 parent 761c50b commit 4702a06

File tree

5 files changed

+106
-15
lines changed

5 files changed

+106
-15
lines changed

package-lock.json

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@
122122
"build:all": "npm run build:rxp:all && npm run build:wasm:release",
123123
"build:rxp:all": "npm run bundle && npm run bundle:min && npm run build",
124124
"build:wasm:debug": "cd ./src/parsers/manifest/dash/wasm-parser && cargo build --target wasm32-unknown-unknown && cp target/wasm32-unknown-unknown/debug/mpd_node_parser.wasm ../../../../../dist/mpd-parser.wasm",
125-
"build:wasm:release": "cd ./src/parsers/manifest/dash/wasm-parser && cargo build --target wasm32-unknown-unknown --release && wasm-opt -O3 -o ../../../../../dist/mpd-parser.wasm target/wasm32-unknown-unknown/release/mpd_node_parser.wasm && cd ../../../../../ && npm run wasm-strip",
125+
"build:wasm:release": "cd ./src/parsers/manifest/dash/wasm-parser && cargo build --target wasm32-unknown-unknown --release && node ../../../../../scripts/wasm-optimize.mjs target/wasm32-unknown-unknown/release/mpd_node_parser.wasm ../../../../../dist/mpd-parser.wasm && cd ../../../../../ && npm run wasm-strip",
126126
"bundle": "webpack --progress --config webpack.config.mjs --env production",
127127
"bundle:min": "webpack --progress --config webpack.config.mjs --env minify --env production",
128128
"bundle:min:watch": "webpack --progress --config webpack.config.mjs -w --env production --env minify",
@@ -185,6 +185,7 @@
185185
"@typescript-eslint/parser": "6.7.3",
186186
"arraybuffer-loader": "1.0.8",
187187
"babel-loader": "9.1.3",
188+
"binaryen": "116.0.0",
188189
"chai": "4.3.8",
189190
"core-js": "3.32.2",
190191
"esbuild": "0.19.3",

scripts/wasm-optimize.mjs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* ============= wasm-optimize util =============
3+
*
4+
* == What is this?
5+
*
6+
* This file allows to optimize a WebAssembly binary file (`.wasm`) by running
7+
* binaryen's wasm-opt tool on it, through its JavaScript API.
8+
*
9+
* To run it, provide the source WebAssembly file as first argument and the
10+
* output as second:
11+
* ```
12+
* node wasm-optimize.mjs source.wasm dest.wasm
13+
* ```
14+
*
15+
* == Why?
16+
*
17+
* As the WebAssembly file produced by the RxPlayer is mostly for performance
18+
* enhancement, it is important that we squeeze the most performance out of it
19+
* at compile-time.
20+
*
21+
* The wasm-opt tool specically optimizes WebAssembly files, it is different
22+
* from performance improvements made by the initial source compiler (e.g. the
23+
* Rust compiler) which may not have the same constraints. Whether this script
24+
* brings or not an improvement in comparison to the source WebAssembly file
25+
* still should probably be regularly checked in real-life scenarios.
26+
*/
27+
28+
import binaryen from "binaryen";
29+
import * as fs from "fs";
30+
31+
run();
32+
function run() {
33+
let inputFileName;
34+
let outputFileName;
35+
36+
if (process.argv.length < 3) {
37+
console.error("Error: missing input file as first argument");
38+
process.exit(1);
39+
}
40+
if (process.argv.length < 4) {
41+
console.error("Error: missing output file as second argument");
42+
process.exit(1);
43+
}
44+
inputFileName = process.argv[2];
45+
outputFileName = process.argv[3];
46+
47+
console.log("Starting logic to optimize wasm file:", inputFileName);
48+
49+
let dataU8;
50+
try {
51+
const data = fs.readFileSync(inputFileName);
52+
dataU8 = new Uint8Array(data.buffer);
53+
binaryen.setOptimizeLevel(4);
54+
const module = binaryen.readBinary(dataU8);
55+
module.optimize();
56+
const output = module.emitBinary();
57+
fs.writeFileSync(outputFileName, output);
58+
} catch (err) {
59+
console.error("Error:", err?.message ?? "Unknown");
60+
process.exit(1);
61+
}
62+
console.log("WASM successfuly optimized!");
63+
}

scripts/wasm-strip.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
* This file allows to remove debugging information from a WebAssembly binary
77
* file (`.wasm`).
88
*
9+
* To run it, provide the source WebAssembly file in argument, it will be
10+
* updated in place:
11+
* ```
12+
* node wasm-strip.mjs file_to_strip.wasm
13+
* ```
14+
*
915
*
1016
* == Why?
1117
*

src/parsers/manifest/dash/wasm-parser/README.md

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -246,22 +246,26 @@ On Rust-side, we exploit multiple FFI features:
246246
The Rust code is compiled through npm scripts, just like all other building
247247
logic in the RxPlayer.
248248

249-
To be able to call the corresponding npm script [1], you will need to:
249+
The name of those scripts are not repeated in this document because of the
250+
fear that they may change in the future, in which case this documentation could
251+
easily be outdated.
250252

251-
1. Install [cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html),
252-
which is roughly Rust's npm.
253+
To be able to call those scripts, you will need to have the Rust compiler
254+
toolchain installed and ready to compile to WebAssembly.
253255

254-
2. Install [binaryen](https://github.com/WebAssembly/binaryen), which is a
255-
WebAssembly toolbox we're using to optimize the built wasm file.
256+
To do this, the easiest way would be to rely on `rustup`, a tool to install and
257+
update Rust toolchains:
256258

257-
If you see error messages while building related to a "wasm32-unknown-unknown"
258-
target not being installed, you should install it.
259+
1. Install [rustup](https://rustup.rs/)
259260

260-
If you use `rustup` this can be done for example by writing:
261-
```sh
262-
rustup target add wasm32-unknown-unknown
263-
```
261+
2. Install and rely on the stable toolchain:
262+
```sh
263+
rustup default stable
264+
```
264265

265-
[1] The name of those scripts are not repeated in this document because of the
266-
fear that they may change in the future, in which case this documentation could
267-
easily be outdated.
266+
3. Add the WebAssembly compiler target:
267+
```sh
268+
rustup target add wasm32-unknown-unknown
269+
```
270+
271+
That should be it!

0 commit comments

Comments
 (0)