LoginSignup
8
6

More than 5 years have passed since last update.

Emscripten + browserifyでNode.js,ブラウザ向け対応

Last updated at Posted at 2016-03-03

Node.jsではrequire経由で呼び出す、ブラウザ向けにはbrowserifyで吐き出すようにしたら、わりとソースが整理できたという話。C言語前提になりますが、C++ではEmbindを使うと同じことができます。

Node.js向けにビルド

まず、とりあえずテキトーにCの関数を作ってコンパイルしてみます。

foo.c
int foo() {
  return 1;
}
emcc -O2 --closure 1 --memory-init-file 0 foo.c -o foo.js -s EXPORTED_FUNCTIONS="['_foo']"

コンパイルオプションを一応説明すると

  • -O2: 最適化する(asm.jsとか)
  • --closure 1: closure compilerで圧縮する
  • --memory-init-file 0: 初期のメモリファイルを外出ししない
  • -s EXPORTED_FUNCTIONS="['_foo']": 上のfoo関数をjs上で_fooとしてエクスポートする

といった具合です。これをnodeで実行してみると_foo関数が確かにエクスポートされています。

var Module = require('./foo');
Module._foo(); // 1

これを最終的にindex.js等でラップした関数を作って外部に公開するようにすれば、Node.js向けのライブラリが作れます。簡単ですね!

index.js
var Module = require('./foo');
module.exports.foo = function() {
  return Module._foo();
};

ブラウザ向けビルド

ブラウザ向けではすこしだけ、コツが要ります。とりあえずwindow.fooにエクスポートしたい感じのコードを書いてみます。

bar.js
var Module = require('./foo');
window['foo'] = function() {
  return Module._foo();
};
browserify bar.js -o baz.js

ブラウザで実行してみるとエラーが出ます。

Uncaught TypeError: Module._foo is not a function(…)

これはEmscriptenはNode.js向けにはModuleをエクスポートしますがブラウザだとしてくれないからです。

emccするときに--post-jsで吐き出されるコードの後ろにjsを追加することで回避します。

post.js
module.exports = Module;
emcc -O2 --closure 1 --memory-init-file 0 foo.c -o foo.js --post-js post.js -s EXPORTED_FUNCTIONS="['_foo']"
browserify bar.js -o baz.js

これでブラウザ向けもビルドできますね。

minifyについて

ブラウザ向けにビルドする場合、minifyしたいと思いますが、Emscriptenが吐き出したコードまでminifyするとasm.js用に最適化している部分が消えるので無視するようにして下さい。以下、minifyifyを使った例。

browserify -p [minifyify --exclude=foo.js --no-map] bar.js -o baz.js

@printf_moriken 曰くuglify v2.5.0以降なら"use asm";と書かれたスコープ内は空白削除だけということなので安心してminifyできます。

まとめ

Emscripten + browserifyでNode.js,ブラウザ向け対応を行う方法を紹介しました。実際にukyo/zlib-asmで同じことをしていますので、よければこちらも参照して下さい。

8
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6