新聞動態(tài)
用文字傳播思想
用行動感動自己


大家都知道 react 是 facebook 的產(chǎn)品,而 angular 是 google 產(chǎn)品,angular 是用 typescript 來編寫,通過 typescript 這個 javascript 超級是 angular 可以輕松地勝任開發(fā)大型應(yīng)用。 而且形成自己生態(tài),自己語言自己框架。所以 facebook 可能也不甘示弱,準(zhǔn)備用一門其他語言類型的語言來高效寫出穩(wěn)定可靠的 javascript 語言。最終選擇了這個有了 20 多年歷史的語言 ocaml, 估計很多人連聽都過這門語言。 這是一門函數(shù)式編程的語言。但是 ocaml 是無法運(yùn)行在瀏覽器上的,而且需要對前端那些熟悉 javascript 的程序員友好。為了解決這些問題,出現(xiàn)了 Reason ,reason 是 OCaml 的語言接口,對于有 javascript 開發(fā)經(jīng)驗的開發(fā)者友好。有了 reason 那么如何將 reason 編譯為 javascript 呢?答案是 BuckleScript ,BS (BuckleScript )是將 ocamel/reason 編譯為 javascript 的編譯器。 這不是一個簡單的編譯轉(zhuǎn)換工具,BS 不但可以將 Ocaml 代碼編譯為 javascript 而且是可以編譯為高效的 javascript,而且易于閱讀。編譯后的代碼你是看不這是機(jī)器寫的,而且 BS 也是中國人寫的,是我們的驕傲。 這么三個相對獨(dú)立的語言和工具,他們之間的關(guān)系又是怎么建立起來的呢? 我們通過分析 Ocaml 編譯器來看一看是如何將他們整合到一起的。 我們從 Ocaml 編譯過程作為切入點進(jìn)行分析,將三者聯(lián)系起來。 source code :在這個階段編譯器獲取 OCaml 的代碼 unTyped AST :進(jìn)行代碼進(jìn)行解析和預(yù)處理,后生產(chǎn)一個棵沒有類型的 AST 。 Typed AST :然后對類型進(jìn)行推測和檢驗生產(chǎn)有類型的 AST。 Lambda IR :這應(yīng)該是 Ocaml 重點,但是應(yīng)該不是我們今天重點,不過可以了解一下 將定義類型的 AST 轉(zhuǎn)為為無類型的 IR ,轉(zhuǎn)換格式依據(jù) s-express 這句話中出現(xiàn)了兩個難懂的詞 IR 和 s-express s-express 知乎一下沒有,wiki 中找到了,我們嘗試?yán)斫庖幌隆? 百度一下,百度翻譯的還不錯。在此基礎(chǔ)解釋一下。 **s-expression**應(yīng)該是一種表示數(shù)據(jù)結(jié)構(gòu)的表達(dá)方式例如(*2(+3 4)),就是將剛剛生產(chǎn)樹形結(jié)構(gòu)數(shù)據(jù)表達(dá)成這樣。是嵌套列表(樹形結(jié)構(gòu))數(shù)據(jù)的一種表示法,由編程語言lisp發(fā)明并推廣,它將它們用于源代碼和數(shù)據(jù)。 Bytecode :最后經(jīng)過進(jìn)行推理將 IR 編譯成字節(jié)碼或機(jī)器碼 了解 ocaml 的整個編譯過程,那么我們的 reason 和 bs 出現(xiàn)在哪個階段呢? Reason 出現(xiàn)在 unTyped AST 這個編譯階段,通過一些預(yù)處理讓我們源碼可以解析成 AST 支持一些新語法的特性 BuckleScript 將使用無類型的 IR 進(jìn)行編譯為可以高效執(zhí)行的 javascript 而不是字節(jié)碼和機(jī)器碼 BuckleScript 的神奇之處編譯的 javascript 可能比你這的還好。計算機(jī)更喜歡函數(shù)式編程。讓我們擁抱機(jī)器,學(xué)一點稍微難于理解但是高效的函數(shù)式編程吧。 React 已經(jīng)采用 reason 來寫組件,下面列出其好處。 - 更安全,更簡潔的方式去構(gòu)建 React 組件 - 完全兼容 JSX - 類型安全兼容 javascript 編寫的組件 - 用于一種全新的表述型 API 來描述狀態(tài)管理 昨天我們通過一個示例,做了一個簡單的 Demo。也知道我們可以用 reason 來寫 react 組件,reason 提供兩種模板讓我們來創(chuàng)建組件。 無類型的組件statelessComponent let component = ReasonReact.statelessComponent("SimpleComponent"); let make = _children => { ...component, render: _self => (ReasonReact.string("Reason Projects")) , }; 然后我們創(chuàng)建一個 TutData.re 文件,其中定義一個 tut 類型,定義數(shù)據(jù)的結(jié)構(gòu)。 type tut = { title:string, body:string } 我們創(chuàng)建一個 statessComponent 組件。 let component = ReasonReact.statelessComponent("SimpleComponent"); let make = _children => { ...component, render: _self => { (ReasonReact.string("Reason Projects")) ; }, }; 我們在定義一個組件 TutItem,~tut 表示給這個參數(shù)打一個標(biāo)簽,雖然我們可調(diào)整參數(shù)的位置,然后通過標(biāo)簽對參數(shù)進(jìn)行傳值。 let component = ReasonReact.statelessComponent("TutItem"); let make =(~tut: TutData.tut, _children) => { ...component, render: _self => { //創(chuàng)建數(shù)據(jù) (ReasonReact.string(tut.title)) ; }, }; 創(chuàng)建 tut 類型的 dummyTut 的數(shù)據(jù),然后將 dummyTut 通過 prop 傳入組件。 let component = ReasonReact.statelessComponent("SimpleComponent"); let make = _children => { ...component, render: _self => { //創(chuàng)建數(shù)據(jù) let dummyTut:TutData.tut = { title:"angular tut", body:"angular tut body" }; <div> <h1>(ReasonReact.string("Reason Projects")) h1> <TutItem tut=dummyTut/> div> ; }, };