Ecosystem

JSX

事實上,JSX 並非一種全新的語言,而是一種語法糖(Syntatic Sugar),一種語法類似XML的 ECMAScript 語法擴充。

NPM

NPM(Node Package Manager)是 Node.js 下的主流套件管理工具。

NPM 是基於 Nested Dependency Tree,不同的套件有可能會在引入依賴時會引入相同但不同版本的套件,造成檔案大小過大的情形。這和另一個套件管理工具 Bower 專注在前端套件且使用 Flat Dependency Tree(讓使用者決定相依的套件版本)是比較不同的地方。

ES6+

ES6+係指 ES6(ES2015)和 ES7 的聯集

Babel

由於並非所有瀏覽器都支援 ES6+ 語法,所以透過Babel這個 JavaScript 編譯器(可以想成是翻譯機或是翻譯蒟篛)可以讓你的 ES6+ 、JSX 等程式碼轉換成瀏覽器可以看得懂的語法。

JavaScript 模組化開發

在一開始沒有官方定義的標準時出現了各種社群自行定義的規範和實踐。

  1. CDN-Based

    也就是最傳統的<script>引入方式,然而使用這種方式雖然簡單方便,但在開發實際中大型應用程式時會產生許多弊端:

    • 全域作用域容易造成變數污染和衝突

    • 文件只能依照<script>順序載入,不具彈性

    • 在大型專案中各種資源和版本難以維護

    • 必須由開發者自行判斷模組和函式庫之間的依賴關係

  2. AMD

    Asynchronous Module Definition簡稱 AMD,為非同步載入模組的規範,其在宣告時模組時即需定義依賴的模組。AMD 常用於瀏覽器端,其最著名的實踐為RequireJS

    基本格式:

    define
    (id?, dependencies?, factory);
  3. CommonJS

    CommonJS規範是一種同步模組載入的規範。以 Node.js 其遵守 CommonJS 規範,使用require進行模組同步載入,並透過exportsmodule.exports來輸出模組。主要實現為Node.js伺服器端的同步載入和瀏覽器端的Browserify

  4. CMD

    CMD 全稱為Common Module Definition,其規範和 AMD 類似,但相對簡潔,卻又保持和 CommonJS 的兼容性。其最大特色為:依賴就近,延遲執行。主要實現為:Sea.js

  5. UMD

    Universal Module Definition是為了要兼容 CommonJS 和 AMD 所設計的規範,希望讓模組能跨平台執行。

  6. ES6 Module

    ECMAScript6 的標準中定義了 JavaScript 的模組化方式,讓 JavaScript 在開發大型複雜應用程式時上更為方便且易於管理,亦可以取代過去 AMD、CommonJS 等規範,成為通用於瀏覽器端和伺服器端的模組化解決方案。但目前瀏覽器和 Node 在 ES6 模組支援度還不完整,大部分情況需要透過Babel轉譯器進行轉譯。

Webpack/Browserify + Gulp

Webpack 和 Browserify + Gulp 則是進行 React 應用程式開發常用的開發工具,可以協助進行自動化程式碼打包、轉譯等重複性工作,提昇開發效率。本書範例主要會搭配 Webpack 進行開發。

  1. Webpack

    Webpack是一個模組打包工具(module bundler),以下列出 Webpack 的幾項主要功能:

    • 將 CSS、圖片與其他資源打包

    • 打包之前預處理(Less、CoffeeScript、JSX、ES6 等)的檔案

    • 依 entry 文件不同,把 .js 分拆為多個 .js 檔案

    • 整合豐富的 Loader 可以使用(Webpack 本身僅能處理 JavaScript 模組,其餘檔案如:CSS、Image 需要載入不同 Loader 進行處理)

  2. Browserify

    如同官網上說明的:Browserify lets you require('modules') in the browser by bundling up all of your dependencies.,Browserify 是一個可以讓你在瀏覽器端也能使用像 Node 用的CommonJS規範一樣,用輸出(export)和引用(require)來管理模組。此外,也能讓前端使用許多在 NPM 中的模組。

  3. Gulp

    Gulp是一個前端任務工具自動化管理工具(Task Runner)。隨著前端工程的發展,我們在開發前端應用程式時有許多工作是必須重複進行,例如:打包文件、uglify、將 LESS 轉譯成一般的 CSS 的檔案,轉譯 ES6 語法等工作。若是使用一般手動的方式,往往會造成效率的低下,所以透過像是Grunt、Gulp 這類的 Task Runner 不但可以提昇效率,也可以更方便管理這些任務。由於 Gulp 是透過 pipeline 方式來處理檔案,在使用上比起 Grunt 的方式直觀許多,所以這邊我們主要討論的是 Gulp。

ESLint

ESLint是一個提供 JavaScript 和 JSX 的程式碼檢查工具,可以確保團隊的程式碼品質。其支援可插拔的特性,可以根據需求在.eslintrc設定檢查規則。目前主流的檢查規則會使用 Airbnb 所釋出的Airbnb React/JSX Style Guide,在使用上需先安裝eslint-config-airbnb等套件。

React Router

React Router是 React 中主流使用的 Routing 函式庫,透過 URL 的變化來管理對應的狀態和元件。若開發不刷頁的單頁式(single page application)的 React 應用程式通常都會需要用到。

Flux/Redux

Flux是一個實現單項流的應用程式資料架構(architecture),同樣是由 Facebook 推出,並和 React 專注於 View 的部份形成互補。而由 Dan Abramov 所開發的Redux被 React 開發社群認為是 Flux-like 更優雅的作法,也是目前主流搭配 React 的狀態(State)管理工具。讓你在開發複雜的應用程式時可以更方便管理你的狀態(state)。

ImmutableJS

ImmutableJS,是一個能讓開發者建立不可變資料結構的函式庫。建立不可變(immutable)資料結構不僅可以讓狀態可預測性更高,也可以提昇程式的效能。

Isomorphic JavaScript

Isomorphic JavaScript 是指前後端(Client/Server)共用相同部分的程式碼,讓 JavaScript 應用可以同時執行在瀏覽器端和伺服器端,在 React 中可以透過伺服器端渲染(server side rendering)靜態 HTML 的方式達到 Isomorphic JavaScript 效果,讓 SEO 和執行效能更加提昇並讓前後端共用程式碼。而另一個常一起出現的 Universal JavaScript 一般定義更為廣泛,係指可以運行在不同環境下的 JavaScript Code,並不局限於瀏覽器和伺服器端。但要留意的是在 Github 和許多技術文章的分享上會把兩者定義為同一件事情。

React 測試

Facebook 本身有提供Test Utilities,但由於不夠好用,所以目前主流開發社群比較傾向使用 Airbnb 團隊開發的enzyme,其可以與市面上常見的測試工具(MochaKarma、Jest 等)搭配使用。其中Jest是 Facebook 所開發的單元測試工具,其主要基於Jasmine所建立的測試框架。Jest 除了支援 JSDOM 外,也可以自動模擬 (mock) 透過require()進來的模組,讓開發者可以更專注在目前被測試的模組中。

React Native

React Native和過去的Apache Cordova等基於 WebView 的解決方案比較不同,它讓開發者可以使用 React 和 JavaScript 開發原生應用程式(Native App),讓Learn once, write anywhere理想變得可能。

GraphQL/Relay

GraphQL是 Facebook 所開發的資料查詢語言(Data Query Language),主要是想解決傳統 RESTful API 所遇到的一些問題,並提供前端更有彈性的 API 設計方式。Relay則是 Facebook 提出搭配 GraphQL 用於 React 的一個宣告式數據框架,可以降低 Ajax 的請求數量(類似的框架還有 Netflix 推出的Falcor)。但由於目前主流的後端 API 仍以傳統 RESTful API 設計為主,所以在使用 GraphQL 上通常會需要比較大架構設計的變動。因此本書則是把 GraphQL/Relay 介紹放到附錄的部份,讓有興趣的讀者可以自行參考體驗一下。

[Reference] https://github.com/kdchang/reactjs101/blob/master/Ch01/react-ecosystem-introduction.md

Last updated

Was this helpful?