HammerJSを用いたプロジェクトにAngular UniversalでSSR対応を試みた結果、下記のエラーに遭遇したのでメモ。
})(window, document, 'Hammer');
ReferenceError: window is not defined
SSRでwindow周りのエラーが起きることはよくあるが、今回はHammerJSの内部の問題なので、isPlatformBrowserなどでサーバーでの実行時に処理を飛ばすことができない。
どうやらhammerjsをフォークした@egjs/hammerjsを用いると良いらしい。
ドキュメントにはserver friendlyと書いてある。
具体的には下記のように修正した。
src/main.ts
- import 'hammerjs';
+ import '@egjs/hammerjs';
src/app/app.module.ts
import {
HammerModule, HammerGestureConfig,
HAMMER_GESTURE_CONFIG, HAMMER_LOADER
} from '@angular/platform-browser';
import Hammer from '@egjs/hammerjs';
@Injectable()
export class MyHammerGestureConfig extends HammerGestureConfig {
buildHammer(element: HTMLElement) {
const mc = new Hammer(element, this.options);
mc.get('pinch').set({enable: true});
mc.get('rotate').set({enable: true});
for (const eventName in this.overrides) {
mc.get(eventName).set(this.overrides[eventName]);
}
return mc;
}
}
@NgModule({
...
providers: [
{ provide: HAMMER_GESTURE_CONFIG, useClass: MyHammerGestureConfig },
{ provide: HAMMER_LOADER, useValue: () => import('@egjs/hammerjs').then(m => (window as any)['Hammer'] = m) },
]
})
export class AppModule { }
これでビルドが通る。