先日、React + Redux + Typescriptで開発しているプロジェクトで"JavaScript heap out of memory"に遭遇し、解決に1日掛かりました。
最終的に設計した自分のせいだったのですが、戒めの意味でもここで共有しておきます。
ReduxにDOMの参照を持たせたのが原因
はい、もう恥ずかしいぐらいにいろいろやらかしています。そもそもReduxはデータをimmutableに扱うのが原則です。そこにmutableでしかありえないものをホイっと渡していました。
発生するheapエラーの厄介な点は、コードのどこが原因なのかをエラーメッセージが教えてくれないことです。"JavaScript heap out of memory"で調べると、「ビルドする際に使用するメモリーを増やすオプション(--max-old-space-size=xxxx
)を追加すると解決する」という情報しか出てきません。
さらにTypescriptを使っていたのでReduxのモジュールとしてstateに以下のようなコードを書いた時点で、そのモジュールのアクションを経由して実際に値を入れたりしなくても、このエラーは発生してしまいます。
import { createSlice, PayloadAction } from 'redux-starter-kit';
type DangerousRefState = {
div: HTMLDivElement | null;
}
const initialState: DangerousRefState = {
div: null
};
const dangerousRefModule = createSlice({
name: "dangerous-ref",
initialState,
reducers: {
// 実際にこのアクションを呼ぶコードを書かなくても、
// ビルドすると"JavaScript heap out of memory"
setRef: (state, action: PayloadAction<HTMLDivElement>) => ({
div: action.payload
})
}
});
以上です。
ちなみになぜ、DOMの参照を持たせようと思ったのか...については恥ずかし過ぎて言えません。。