【干貨】年度最具影響力開源JavaScript軟件庫Immer發布第四版
JavaScript獲獎軟件庫Immer的主要貢獻者Alec Larson在幾天前發布了該軟件的第四次主迭代版本,針對一些邊緣情況打了補丁。作為JavaScript軟件庫,Immer通過一種稱為“寫入時復制(copy-on-write)”的機制,支持開發人員在像操作可變狀態一樣便利地操作不可變狀態。今年,Immer榮獲了多項殊榮,包括響應式開源獎( React open source award)中的“年度最具突破者”(Breakthrough of the year),以及JavaScript開源獎(JavaScript open source award)中的“最具影響貢獻者”(Most impactful contribution)。
Immer(德語,表示“一以貫之”)軟件庫支持JavaScript開發人員像操作可變狀態那樣,簡潔便利地操作不可變狀態。為實現該功能,Immer結合JavaScript的Proxy技術,使用了一種稱為“結構化共享(structural sharing)”的“寫入時復制”機制。
具體而言,作為當前狀態currentState的代理,開發人員會維護一個臨時的draftState可變狀態。進而根據臨時狀態的可變情況,生成一個nextState狀態,并將狀態的未更改部分共享給currentState狀態。由此,開發人員像以往那樣改變數據,同時保有不可變數據的收益。
下面給出一段示例代碼:
import produce from "immer"
const baseState = [
{
todo: "Learn typescript",
done: true
},
{
todo: "Try immer",
done: false
}
]
const nextState = produce(baseState, draftState => {
draftState.push({todo: "Tweet about it"})
draftState[1].done = true
})
示例代碼展示了如何在不影響baseState的情況下操作可變狀態draftState。而nextState是一個不可變狀態樹,維護了對draftState的所有更改操作,并實現對狀態中所有未更改之處的結構化共享。
Immer第四版中修補了一個重要的邊緣情況,避免了一些常見性問題。
在修復前,Immer不支持對變化點之外的狀態賦予不變性。這意味著,如果通過API生成的nextState對象并未做任何修改,那么該對象將維持可變狀態。該錯誤行為可通過如下代碼示例闡明:
const d: D = {a: {b: 2}, z: {y: 3}};
const immutable = produce(d, draft => {
draft.a.b = 1;
});
// 不可修改a.b
expect(() => immutable.a.b = 5).to.throw("");
// 但是可以修改z.y??!
immutable.z.y = 4;
expect(immutable.z.y).eql(4);
Immer第四版修復了上述錯誤行為。它返回一個深度凍結(deeply frozen)的對象樹,使得immutable.z.y不再支持修改操作。
不可變數據結構是JavaScript開發人員經常使用的數據結構,它直接支持性能優化、撤銷/重做特性,并對更新提供了更好的可追蹤能力。在React/Redux環境中,不可變數據結構是非常重要的,因為應用狀態表示為“凍結的對象快照”,狀態的更改只能通過一類稱為reducer的純函數實現?;诖?,在Redux-ecosystem-links網頁上列出了約70多個實現在Redux中操作不可變數據結構的軟件包。
從標準JavaScript的語法、互操作性、性能等特性上看,Immer相對于其它類型軟件包而言是使用最廣的。對于Immer在React編程中的異軍突起,React團隊成員及Redux和Create React App項目的共同創始人Dan Abramov給出了如下解釋:
Immer成功的秘訣在于:提供易于調試的軟件庫,減少編寫程序的煩惱。感謝@mweststrate提供了Immer!
但也應注意,Immer是基于ES6 Proxy的。而ES6 Proxy是一種必須在舊版瀏覽器上使用的Polyfill,這可能對性能產生影響。此外,開發人員應該了解官方文檔中給出的由于使用Proxy而導致的一些缺陷。
2019年,Immer榮獲了兩個獎項,即JavaScript開源獎(JavaScript open source award)中“最具影響貢獻者”(Most impactful contribution),以及React開源獎( React open source award)中的“年度最具突破者”(Breakthrough of the year)。這兩個獎項是分別授予對JavaScript生態做出突出貢獻的項目,以及“為進一步開發增添了新的維度和可能性、首次出色實現并未來具有巨大潛力的新概念和想法”。
Immer的創始人Michel Weststrate,也是狀態管理軟件庫mobx的創始人。
Immer使用MIT許可開源提供,歡迎通過Immer的GitHub項目和Open Collective對項目做出貢獻。