Introducing binaryen-loader

View this thread on: d.buzz | hive.blog | peakd.com | ecency.com
ยท@drsensorยท
0.000 HBD
Introducing binaryen-loader
#### Repository
| Repository        | Link                                                   |
| ----------------- | ------------------------------------------------------ |
| `binaryen-loader` | https://github.com/DrSensor/binaryen-loader            |
| Example Project   | https://github.com/DrSensor/example-vue-component-rust |

#### About binaryen-loader
[Binaryen][binaryen] is a compiler and toolchain infrastructure library for WebAssembly, written in C++. Most of the tools are *cli* app and one of them can be embedded into javascript ([binaryen.js][]). This project is just a webpack loader that wraps [binaryen.js][] (only the optimization parts) so it can be chained easily with other webpack-loader. For more insight see [this tutorial](https://steemit.com/utopian-io/@drsensor/mix-rust-code-webassembly-with-vue-component-optimization-analyze-wasm-call-graph-and-shrink-the-size) in section *Using Binaryen*.

<center><img src="https://cdn.steemitimages.com/DQmT3VXuETtqegrS9LAFtPesDgd2S8TnisMnzMDBts16d8c/Selection_028.png" alt="example usage"/></center><center><sub>chaining `binaryen-loader` with other webpack loader</sub></center>

#### Current features
Since this project based on [binaryen.js][], most of the features are just wrappers from [module-optimization](https://github.com/AssemblyScript/binaryen.js#module-optimization) section. Some of the features are:

- define optimization flags in `options.optimization`
- run specific passes by defining it in `options.transformation.passes` (sometimes it can shrink the bundle size, sometimes it can increase the execution speed, sometimes it does the opposites for both of them)
- enables debug information in emitted wasm code by setting the `options.debug` to `true`

#### Technology Stack
Since this project generated from [webpack-defaults][] with some modification (see [commit before v0.0.2][]), the tech stack used is what [webpack-defaults][] proposed.

| Task                    | Tech/Tool                           | Configuration                                                                |
| ----------------------- | ----------------------------------- | ---------------------------------------------------------------------------- |
| Package Manager         | [npm][] (not `yarn`)                | [package.json][]                                                             |
| Test Framework          | [Jest][]                            | [jest.config.js][], [jest.setup.js][]                                        |
| Linter and others       | [ESLint][], [Prettier][], [husky][] | [.prettierrc][], [.eslintrc.js][], [lint-staged][], [commitlint.config.js][] |
| Release Tool            | [husky][], [standard-version][]     |                                                                              |
| Build Tool (Transpiler) | [Babel][]                           | [.babelrc][]                                                                 |
| CI                      | [circleci][]                        | [.circleci/config.yml][]                                                     |

#### Some interesting things to note
- โœจ There is helper file I created to make the testing enjoyable called [on.js][]. For people who wrote some of webpack-loader, maybe you want to copy and edit that file ๐Ÿฃ

<center><img src="https://cdn.steemitimages.com/DQmUa8cTKfyfa4Xy1QruiiRvAwoKS1Gs65PYjvYUFGwWZSa/onjs.png" alt="on.js usage"/></center><center><sub>[on.js][] in action</sub></center>

- ๐Ÿ› In Jest, [`expect(err).toThrowErrorMatchingSnapshot()`](https://github.com/DrSensor/binaryen-loader/blob/133c0225ec4cdd5a5e23d43a4c6be2fc54e56d17/test/error.test.js#L9) can make the test fail if runned on nodejs v10 or newer.

<center><img src="https://cdn.steemitimages.com/DQmV5k5T8jD2c1yVDBTRG22t8vgSRPxhpd22pTthep4tLxJ/snapshot_comparison.png" alt="jest_node10_bug"/></center><center><sub>comparison of snapshot generated by `.toThrowErrorMatchingSnapshot()`. Left: generated when running on `node:10`. Right: generated when running on `node:8` and `node:6`</sub></center>

- ๐Ÿ’š Since CircleCI now support [Manual Approval][], I edit the [.circleci/config.yml][] (see this [commit history](https://github.com/DrSensor/binaryen-loader/commits/361b2d681769d21af91b68f60a8e5754313e225a/.circleci/config.yml)) and use that feature.

<center><img src="https://cdn.steemitimages.com/DQmUndTfpsFFvB1J2wLmBNFsrdCiCTGtBenqoKVika1f8cH/manual_approval.gif" alt="manual_approval demo"/></center><center><sub>using Manual Approval feature on binaryen-loader workflow</sub></center>

- โœ…โ” There is [fix attempt for timeout problem][] as shown below. Not sure if the fix is because running jest with `--ci` flag or set `testEnvironment: 'node'` (since by default `testEnvironment` is `jsdom`). Maybe adding [jest.config.js][] override jest configuration in [package.json](https://github.com/DrSensor/binaryen-loader/blob/d235d1100205b7bf64ddd3406559d00fefea747a/package.json#L80-L82) (making it invalid).

<center><img src="https://cdn.steemitimages.com/DQmXxfry8ADHyF2ppv6oHP35EPhaYWxzZVEMvTtr8kwKmTG/fix%20attempt%20for%20timeout%20problem.png" alt="timeout problem"/></center><center><sub>timeout problem when running on CI. Fix on [commit 33123b0][fix attempt for timeout problem]</sub></center>

- ๐Ÿ’ฉ Since [conventionalcommits][] take to much space on commit message, I try to combine it with [gitmoji][] convention. Not sure if it's a good idea ๐Ÿ˜†

<center><img src="https://cdn.steemitimages.com/DQmcaZwwFBmVyFRAz62C3USnixwyYyMrfdPbfWPAn7P5gAo/commit_convention.png" alt="gitmoji+conventionalcommits"/></center><center><sub>new combo: gitmoji + conventionalcommits</sub></center>

#### Future Plans
- Currently, using `passes` like `print-call-graph` that is print the call-graph to `stdout` will pollute webpack outputted message. I plan to pipe the output into a file but still don't have a clue how to do it. Feel free to make PR, open an Issue, or just comment below if anyone has an idea ๐Ÿ™‚
- There is an idea to separate some passes into categories ([issue #2][]). Still evaluating and looking some feedback for this.
- I do document some behavior of some configuration in a form of unit-tests, like the provided export it exposed and range of binary size of wasm code after running [Binaryen][]. I will continue this effort when finding something interesting along the way. Feel free to make PR (adding fixture and/or test case) if anyone found something interesting ๐Ÿ™‚
- Add test case when chained to another loader, especially from foreign programming language (e.g Rust using [`rust-native-wasm-loader`](https://github.com/dflemstr/rust-native-wasm-loader)).

#### How to contribute?
The project is open to contributions in any way possible. If you find a bug, please open an issue in the project's issue tracker. For submitting code patches, feel free to open pull requests on Github. Read [CONTRIBUTING.md][] first for the best experience ๐Ÿ˜„

#### GitHub Account
https://github.com/DrSensor

[commit before v0.0.2]: https://github.com/DrSensor/binaryen-loader/commits/2c474177e04795523ca3018b6360a6e8ae1d4a63
[issue #2]: https://github.com/DrSensor/binaryen-loader/issues/2
[Manual Approval]: https://circleci.com/docs/2.0/workflows/#holding-a-workflow-for-a-manual-approval
[fix attempt for timeout problem]: https://github.com/DrSensor/binaryen-loader/commit/33123b00ffaee364360961fdea8b9b56f8db9897?diff=split

[on.js]: https://github.com/DrSensor/binaryen-loader/blob/master/test/helpers/on.js

[gitmoji]: https://gitmoji.carloscuesta.me/
[conventionalcommits]: https://conventionalcommits.org/
[circleci]: https://circleci.com/docs/2.0/
[Binaryen]: https://github.com/WebAssembly/binaryen
[ESLint]: https://eslint.org/
[Prettier]: https://prettier.io/
[npm]: https://docs.npmjs.com/cli/npm
[binaryen.js]: https://github.com/AssemblyScript/binaryen.js
[webpack-defaults]: https://github.com/webpack-contrib/webpack-defaults
[Babel]: https://babeljs.io/
[Jest]: https://facebook.github.io/jest/
[husky]: https://github.com/typicode/husky
[standard-version]: https://github.com/conventional-changelog/standard-version

[.circleci/config.yml]: https://github.com/DrSensor/binaryen-loader/blob/master/.circleci/config.yml
[package.json]: https://github.com/DrSensor/binaryen-loader/blob/master/package.json
[lint-staged]: https://github.com/DrSensor/binaryen-loader/blob/133c0225ec4cdd5a5e23d43a4c6be2fc54e56d17/package.json#L85-L89
[commitlint.config.js]: https://github.com/DrSensor/binaryen-loader/blob/master/commitlint.config.js
[.eslintrc.js]: https://github.com/DrSensor/binaryen-loader/blob/master/.eslintrc.js
[.prettierrc]: https://github.com/DrSensor/binaryen-loader/blob/master/.prettierrc
[jest.config.js]: https://github.com/DrSensor/binaryen-loader/blob/master/jest.config.js
[jest.setup.js]: https://github.com/DrSensor/binaryen-loader/blob/master/jest.setup.js
[.babelrc]: https://github.com/DrSensor/binaryen-loader/blob/master/.babelrc
[CONTRIBUTING.md]: https://github.com/DrSensor/binaryen-loader/blob/master/.github/CONTRIBUTING.md![commit_convention.png](https://cdn.steemitimages.com/DQmcaZwwFBmVyFRAz62C3USnixwyYyMrfdPbfWPAn7P5gAo/commit_convention.png)
๐Ÿ‘ , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,