淺談JavaScript工具鏈不完全指南
在 JavaScript 語言日漸強大的同時,與其配套的開發工具也蓬勃發展。現在的 Web 前端項目,早已不是寫幾個 HTML 頁面,加點 CSS 和 JS 就完事了。隨便一個實用的項目,可能都需要用到一些框架和第三方庫,以及相應的腳手架、依賴包管理、預編譯、構建打包、壓縮合并等等工具。純手工完成這些任務,已經幾乎不太可能了。
科學技術是第一生產力,而工具就是其中的一個體現。工欲善其事必先利其器,既然工具解放了人力,我們就應該擁抱它們。本文總結了圍繞 JavaScript 的一系列工具,看看一個常見的項目到底需要用到哪些工具。
靜態類型檢查JavaScript 本身是一門動態腳本語言,是弱類型的。也就是說,沒有編譯階段的數據類型檢查,只能在運行時確定類型。好處是比較靈活,簡單易學,代碼量也比較少。缺點也是明顯的,就是稍不注意容易出 bug,特別是大型項目,如果沒有開發規范,任由開發人員自由發揮,維護起來簡直就是災難。為了彌補這個缺陷,一些自帶類型系統、可轉譯成 JavaScript 的語言出現了。
Flow:Facebook 出品,用 OCaml 寫的 JavaScript 靜態類型檢查系統。支持類型系統、類型標注,可定義 library,提供代碼 lint 等。Vue.js 2.x 就是用 Flow 寫的。不過,Vue 3.0 改用另一種靜態類型語言了,那就是 TypeScript。
TypeScript:TypeScript 是微軟開發的語言,是 JavaScript 的超集,能夠編譯成 JavaScript。現在 TypeScript 越來越流行,獲得了大量項目的認可。
代碼風格檢查(Linter)由于JavaScript 動態語言的特性,在寫法上過于靈活,往往導致多人協作的項目代碼風格各異,給維護和擴展帶來不少麻煩。另外,部分語言特性容易導致 bug,最佳實踐里通常不推薦使用。因此,代碼 Lint 工具就派上用場了。它不但可以檢查代碼書寫格式,還可以檢查出引用未定義的變量等低級錯誤。
曾經出現過很多種 Lint 工具,比如 JSLint、JSHint、StandardJS、JSCS 等等,現在有大一統的趨勢,基本都用 ESLint 了。
剛開始用 Lint 工具的時候可能會不適應,因為限制太多,動不動就警告和報錯。但從長遠來看,JavaScript 項目引入 Linter 還是有必要的。
包管理器JavaScript 之所以能夠遍地開花,很大程度是因為技術生態非常繁榮,各種第三方庫應有盡有。如此龐大的第三方庫集合,勢必需要一個管理平臺,負責第三方包的托管、版本管理、下載安裝和依賴管理等。
npm:JavaScript 包管理器的集大成者,目前最主流的工具。 基于 Node.js,包含網站和 CLI,上面的包總數超過 100萬,基本涵蓋了 JavaScript 項目所需的方方面面。
yarn:2016 年 Facebook 推出的包管理器,跟 npm registry 兼容,主打 CLI 的快速、安全和確定性。
bower:曾經比較流行,用于管理前端的 JavaScript 包,因為當初 npm 只支持 node 環境的包管理。隨著 npm 和 yarn 同時支持 node 和瀏覽器端的包管理,bower 也逐漸淡出歷史了。
pnpm:通過硬鏈接(hard links)的方式在硬盤上對某個版本的模塊只保存一份,可以在多個項目之間共用,從而節省了大量硬盤空間,順便也加快了模塊安裝速度。
模塊加載器JavaScript 早期沒有語言層面的模塊化支持,導致大型項目的依賴管理非常不方便。變量名沖突、全局變量污染、模塊加載順序等問題比較突出。曾經出現過各種模塊化方案,比如 CommonJS Modules (CJS),Asynchronous Module Definition (AMD)和 Universal Module Definition (UMD)。從 2015 年開始,ES6 從語言層面支持了模塊化,即 ECMAScript Modules (ESM)。
除了上述常見的 JavaScript 模塊格式,還有像 System.register或全局模塊,以及一些非 JavaScript 模塊,比如 JSON modules,CSS modules,Web Assembly 等。
模塊加載器就是加載和處理上面各種類型模塊代碼的工具,有同步和異步、靜態和動態之分。通常,一個模塊放在一個單獨的文件里,通過一些指令來導入。當一個項目有幾十上百個模塊的時候,如何保證它們的加載執行先后順序就是個問題。不用擔心,模塊加載器會幫你處理好依賴關系。
RequireJS:實現了 AMD 模塊加載,主要用于瀏覽器端,也可以在 Node 里使用。
SystemJS:一個動態模塊加載器,可以加載所有類型的 JavaScript 模塊,甚至包括非 JavaScript 模塊,可用于瀏覽器和 Node。
StealJS:可以加載 ESM,ADM 和 CJS 格式的模塊。
ES Module Loader:瀏覽器實現的模塊加載器,Node.js 里加上 --experimental-modules標志也能使用。
以上模塊加載器是在運行時加載和執行代碼的。不要跟構建工具里的各種 loader 混淆,那些是在構建時進行預處理的工具,只是做一些格式轉換。
打包工具一個實際的生產項目,通常不是把源碼直接發布到服務器上。而是通過一些工具對各種模塊和靜態資源進行整合處理,最終生成的代碼可能跟源碼完全不一樣了。這就是打包工具的作用。比較常見的打包工具有:
Webpack:可以說是最流行的打包器,幾乎是大部分項目的標配。它本身只能識別 JavaScript 和 JSON 文件,但是它的架構設計提供了無限的可能,通過各種 loader 可以處理任意類型的資源,通過插件可以優化打包結果和進行資源管理、注入環境變量等。它的構建目標也可以根據平臺定制,比如瀏覽器、Node.js、web worker, Electron 等。
Rollup:也是一個優秀的打包器,支持輸出 library 和 application。它最大的賣點就是默認支持 ES 模塊,很早就實現了 tree-shaking 功能。同時也具備插件和 hook 功能,可定制化也比較好。
Parcel:工具界的后起之秀,號稱“零配置*的打包器,如果你曾經被 Webpack 繁瑣的配置困擾過,那它可能會吸引你。
Browserify:應用范圍稍窄的打包器,專門用于轉換 Node.js 包以便能在瀏覽器運行。它跟 Node.js 使用相同的模塊系統,有些模塊只用于 Node 平臺,通過它的轉換就可以在瀏覽器端使用了。它只能處理純 JavaScript 模塊,通常跟 Gulp 配合使用。
Metro:React Native 專用的打包器,通過一個入口文件和各種配置,最后打成包含所有代碼和依賴的單個 JavaScript 文件。
任務管理工具(Task Runner)Task Runner 的作用是自動化執行項目所需的各種重復性動作,比如:
CSS 預處理 (Less, Sass) CSS 自動添加新特性屬性前綴(Autoprefixer) 優化圖片 合并、壓縮 JavaScript 文件 監聽文件變化,自動執行任務比較主流的任務管理器是 Grunt 和 Gulp,Webpack 也算一個。
Grunt:命令行工具,通過精細化的配置和豐富的插件可以完成很多復雜的任務。
Gulp:跟 Grunt 不同,Gulp 采用流式管道組合多個任務,任務之間的臨時結果是放在內存中的,執行效率會高很多。
Webpack:又是你,Webpack。任務管理只是 Webpack 強大功能的一部分,通過不同的插件在構建的不同階段執行個性化的任務。
如果你覺得上面幾個任務管理器有點殺雞用牛刀,你也可以根據實際情況選用 bash 腳本,npm 腳本或者 Makefile 等實現一些簡單的任務管理。
轉譯器JavaScript 轉譯器的作用是將非 JavaScript 語言(TypeScript,CoffeeScript,LiveScript 等)或不同版本的 JavaScript(ES6,ES7,ES8 等)翻譯成符合目標平臺要求(兼容性、變量混淆、嚴格模式等)的等價代碼。
大部分轉譯器在處理源碼和代碼優化的過程中都使用抽象語法樹(AST)作為中間格式。AST 將源碼逐步拆分解析成帶有元數據的樹形結構:
Code --(parse)-->AST--(transform)-->AST--(generate)-->Code
Babel是目前主流的 JavaScript 轉譯器,它的工具鏈體系主要用于將 ES6 以上版本的 JavaScript 轉譯成向后兼容瀏覽器的代碼。Babel 可以轉換語法、提供目標平臺缺失的特性支持、轉換源碼等。
有了 Babel,我們可以盡早用上新的語言特性,而不用擔心目標瀏覽器是否支持。
構建工具構建其實是個綜合概念,它包含了模塊打包、源碼轉譯、任務管理等多個步驟。其他語言和平臺有各種 Build 工具,比如 Make,Gradle,Ant,Maven,Rake 或 MSBuild 等。其中 Make 是最常見的通用構建工具,通常用于 C 語言,但其實也可以用于構建 JavaScript 項目。
對于 JavaScript 工具鏈來說,構建的目標可能是 npm 包、網站、Node 服務器、RN 應用、Electron 應用等等。有些任務可用專門的工具完成,但構建是個復雜的過程,通常需要綜合使用多個工具。
比如 Build 可以用 Buck,Bazel,Lerna 等工具同時管理多個模塊,實現增量 Build(只重新構建有改動的模塊,提高效率)。任務管理使用 Grunt 和 Gulp,模塊打包用 Webpack、Rollup、Parcel、Browserify 等。
調試工具調試器在開發過程中必不可少,它可以在 Node.js 和瀏覽器中跟蹤查看運行中的代碼。通常會提供斷點、單步執行、監視變量、查看內存和 CPU 使用情況等功能。
Chrome DevTools:Chrome 瀏覽器自帶的開發者工具,是目前瀏覽器開發工具里最好用的(沒有之一)。它的功能之強大,用法之多可以寫本書了。
node-inspector:早期用于調試 Node.js 代碼的工具,現在基本不用了,因為 Node.js 已經內置了基于 DevTools 的調試器。
VS Code:又一調試神器,內置 Node.js 調試器,還能調試 TypeScript 和其他能轉譯成 JavaScript 的語言。
Node 進程管理器Node 進程管理器用于管理運行中的 Node 應用程序。提供高可用、自動重啟、文件監控、性能和資源監控和集群等功能。
Forever:顧名思義,它的作用是保持 Node.js 程序永遠運行。它是一個簡單的命令行工具,對小型 Node.js 應用比較方便。
PM2:用于生產環境的 Node.js 進程管理工具,內置負載均衡、自動重啟和日志、監控和集群管理等功能。
StrongLoop Process Manager(Strong-PM):跟 PM2 差不多,也可用于生產環境的 Node.js 進程管理,有多主機部署功能。
另外,SystemD 是 Linux 系統里的默認進程管理器,可用它把 Node.js 應用作為服務運行。
項目腳手架隨著項目復雜度的提升,創建新項目的步驟也變得越來越繁瑣,可能需要重復大量的配置工作。這個時候就需要項目腳手架了。很多框架都提供了腳手架工具,比如 Vue.js 有 Vue CLI,Angular 有 Angular CLI,React 有 create-react-app 等。也有通用的腳手架,Yeoman 就是最流行的一個。
快速創建新項目 創建模塊或 package 啟動新服務 統一代碼風格、最佳實踐等 項目推廣,讓用戶快速上手示例 app以上就是淺談JavaScript工具鏈不完全指南的詳細內容,更多關于JS工具鏈不完全指南的資料請關注好吧啦網其它相關文章!
相關文章:
