wasm-bindgenを用いることでjsファイルで定義されたクラスや関数などをRustから利用できます.今回はそのwasm_bindgenとJavaScript等のバンドラであるwebpackを利用して,jsパッケージ(具体的にはplyr)をRustから利用してみます.また,バンドルサイズを小さくするためにjsパッケージをCDNからも利用してみます.作成したクレートはこちら.
JavaScriptのバンドル
まずはwebpackを利用するプロジェクトをwebpackのGetting Startedに従って作成します.次に利用したいjsライブラリであるplyrをnpmなどでインストールします.
npm i plyr
そしてエントリーとなるsrc/index.js
を作成します.本来はこちらにRust側で利用したい関数やクラスなどを定義するのですが,今回はデフォルトimportしたPlyr
クラスをそのままexportします.
import Plyr from 'plyr';
export {Plyr};
次にバンドルについての設定をwebpack.config.js
に記述します.output.library.type
を'module'
とすることでバンドルしたファイルをESモジュールとして読み込めるようになります.type
を'module'
にするにはexperiments.outputModule
をtrue
にする必要があるためそちらも設定しておきます.
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
experiments: {
outputModule: true,
},
output: {
path: path.resolve(__dirname, '../dist'),
filename: 'main.js',
library: {
type: 'module',
},
},
};
これによって
npm run build
(webpack
コマンドが実行される)で利用したパッケージを含めてバンドルされ,dist/main.js
が作成されます.
一方でパッケージをバンドルに含めずCDNで利用したい場合は以下のようにconfig.js
を設定します.先ほどの例と異なる部分はexternalsType
とexternals
です.CDNとして読み込むためexternalsType
には'global'
を指定します.その場合externals
にはプロジェクトで利用するライブラリ名(plyr
)と対応するCDNを読み込んだグローバル変数名('Plyr'
)を指定します.
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
experiments: {
outputModule: true,
},
output: {
path: path.resolve(__dirname, '../dist_cdn'),
filename: 'main.js',
library: {
type: 'module',
},
},
externalsType: 'global',
// externalsType: 'window', // こちらでもよい
externals: {
plyr: "Plyr"
}
};
これによって
npm run build -- --config cdn_webpack.config.js
でplyr
が除外されてバンドルされ,dist_cdn/main.js
が作成されます.
この作成されたdist/main.js
とdist_cdn/main.js
をwasm_bindgenから読み込みます.
wasm-bindgenでjsファイルを読み込む
あとはwasm-bindgenの公式ドキュメントにあるようにwasm_bindgen
アトリビュートにmodule
を指定してjsファイルを読み込みます.cfg_attr
で指定したfeature
に応じて読み込まれるファイルを異なるようにすると便利です.以下ではPlyr
型とそのコンストラクタを定義しています.このコンストラクタからは読み込んだjs側のPlyr
クラスのコンストラクタが呼び出されます.
use wasm_bindgen::prelude::*;
#[cfg_attr(feature = "cdn", wasm_bindgen(module = "/dist_cdn/main.js"))]
#[cfg_attr(not(feature = "cdn"), wasm_bindgen(module = "/dist/main.js"))]
extern "C" {
#[derive(Debug, Clone)]
pub type Plyr;
#[wasm_bindgen(constructor)]
pub fn new(css_selector: &str) -> Plyr;
}
これで以下のように利用できるようになります.
let player = Plyr::new("#player");
module
でパスを指定することで,クレートとして利用したときにもjsスニペットごと利用できます.