Skip to content

Instantly share code, notes, and snippets.

@adamay000
Last active Nov 14, 2018
Embed
What would you like to do?
CanvasでHMRするときの基本
/**
* hmr前後で引き継ぎたいデータはまとめて外出する(Store)
* Storeを書き換えた場合はページをリロードするか、もしくは別途accept()の処理を書く
* Storeはconstructorの引数でどんどん子孫に渡していく。必要ならDIなりdecoratorなりでコードをキレイにする
*/
/** @type {Assets} 一度だけロードすればいいやつとかはまとめておくと良い */
let assets = null;
/** @type {Store} 復元したいデータは全部外にまとめておく or serialize的な保存・復元の方法が必要 */
let store = null;
/** @type {Application} メインの処理 */
let app = null;
(async () => {
// 初期ロードかどうかはグローバルオブジェクトにフラグを持たせて判別する
// if (module.hot) で囲んだ部分はプロダクションビルド時に削除されるため、
// if (module.hot && module.hot.data) で判別はしないこと
if (window.__init) {
// hmr時に実行する処理
// 古いアプリケーションの破棄とか
await hmr();
} else {
window.__init = true;
// 初期ロード時に実行する処理
// 一度だけ行えればいいassetsの読み込みとか
await init();
}
// アプリケーションの再構築が済んでからaccept()する
// それ以外は画面がリロードされてしまっても良いと思う
if (module.hot) {
module.hot.accept(console.error);
// hmr後に引き継ぎたいデータを保存する
module.hot.dispose((data) => {
data.assets = assets;
data.store = store;
data.app = app;
});
}
});
/**
* ロード時に一度だけ実行する処理
*/
async function init() {
assets = new Assets();
store = new Store();
// ローディング的なのが必要ならここ
await assets.load();
app = new Application(assets, store);
}
/**
* hmr時に実行する処理
*/
async function hmr() {
if (module.hot && module.hot.data) {
// hmr時にはもともと持ってたデータを引き継ぐ
assets = module.hot.data.assets;
store = module.hot.data.store;
// リロード前のアプリケーションを破棄する(listenerとかを解除する)
// これはdispose時に実行しても良い
module.hot.data.app.destroy();
}
app = new Application(assets, store);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment