Because every method is bound up in a Class, instantiated in the module factory, then exported, consumers will get every method of Immer in their bundle, whether they use it or not.
A slight reorganization of the code would allow their optimizing compilers to tree-shake away the method implementations that they don't need.
Summary
This PR reorganizes the code such that requiring one method of Immer doesn't force you to take a hard dependency on all the others. You can now do this:
import { produce } from 'immer';
produce(state, draft => { /* ... */ });
…and have all of the other methods that you haven't used (produceWithPatches, setAutoFreeze, setUseStrictShallowCopy, applyPatches, createDraft, finishDraft) be reaped by your optimizing compiler.
Results
Consider this typical application that only uses produce():
Problem
Because every method is bound up in a
Class
, instantiated in the module factory, then exported, consumers will get every method of Immer in their bundle, whether they use it or not.A slight reorganization of the code would allow their optimizing compilers to tree-shake away the method implementations that they don't need.
Summary
This PR reorganizes the code such that requiring one method of Immer doesn't force you to take a hard dependency on all the others. You can now do this:
…and have all of the other methods that you haven't used (
produceWithPatches
,setAutoFreeze
,setUseStrictShallowCopy
,applyPatches
,createDraft
,finishDraft
) be reaped by your optimizing compiler.Results
Consider this typical application that only uses
produce()
:When bundled with an optimizing compiler:
This PR (in combination with #1124) results in a bundle that's 13% smaller, gzipped (diff)
Test plan