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