
新聞動態
用文字傳播思想
用行動感動自己

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