一個(gè)人如果單靠自己,如果置身于集體的關(guān)系之外,置身于任何團(tuán)結(jié)民眾的偉大思想的范圍之外,就會(huì)變成怠惰的、保守的、與生活發(fā)展相敵對(duì)的人。 —— 高爾基
一 、包管理工具
1、npm
npm是nodejs的一個(gè)模塊,是nodejs的包管理器。
我們前后端開(kāi)發(fā)項(xiàng)目時(shí),會(huì)用到很多別人已經(jīng)寫(xiě)好的javascript代碼,如果每當(dāng)我們需要?jiǎng)e人的代碼時(shí),都根據(jù)名字搜索一下,下載源碼,解壓,再使用,會(huì)非常麻煩。于是就出現(xiàn)了包管理器。大家把自己寫(xiě)好的源碼上傳到npm官網(wǎng)上,如果要用某個(gè)或某些個(gè),直接通過(guò)包管理器下載安裝就可以了,不用管那個(gè)源碼在哪里。并且如果我們要使用模塊A,而模塊A又依賴模塊B,模塊B又依賴模塊C和D,此時(shí)包管理器會(huì)根據(jù)依賴關(guān)系,把所有依賴的包都下載下來(lái)并且管理起來(lái)。
npm包管理器的的特點(diǎn)
- 不會(huì)緩存,每次安裝需要很長(zhǎng)時(shí)間
- 安裝按照隊(duì)列順序執(zhí)行,不是同步
- npm5之后才有版本鎖定功能,package-lock.json
package-lock.json詳解
一般來(lái)說(shuō),版本號(hào)主要分為三部分:主版本號(hào)、次版本號(hào)和修補(bǔ)版本號(hào)
major.minor.patch
主版本號(hào).次版本號(hào).修補(bǔ)版本號(hào)
patch:修復(fù)bug,兼容老版本
minor:新增功能,兼容老版本
major:新的架構(gòu)調(diào)整,不兼容老版本
版本號(hào)的主要符號(hào)
1、>
大于某個(gè)版本,表示只要大于這個(gè)版本的安裝包都行,如>2.0.0。2、>=
大于某個(gè)版本,表示只要大于或等于這個(gè)版本的安裝包都行,如>=2.0.0。3、<
小于某個(gè)版本,表示只要小于這個(gè)版本的安裝包都行,如<2.0.0。4、<=
小于或等于某個(gè)版本,表示只要小于或等于這個(gè)版本的安裝包都行,如<=2.0.0。5、~
如:~2.6.6,表示>=2.6.6 <2.7.0,可以是2.6.x,兼容patch。
如:~2.6,表示>=2.6.0 <2.7.0,可以是2.6.x,兼容patch。
如:~2,表示>=2.0.0 <3.0.0,可以是2.x.x,兼容minor和patch。6、^
如果major是非零數(shù)字,則兼容minor和patch,如果是0,則兼容patch。
如:^2.6.6 ,表示>=2.6.6 <3.0.0,可以是2.x.x,兼容minor和patch。
如:^0.6.6,表示>=0.6.6 <0.7.0,可以是0.6.x,兼容patch。
如:^0.6,表示 >=0.6.0 <0.7.0,可以是0.6.x,兼容patch。7、*
表示任意版本。
如:*,表示>=0.0.0的任意版本。
一般package.json很多依賴包都帶有符號(hào),在npm5版本以前,例如^2.6.6,package.json依賴包根據(jù)符號(hào),只能鎖定major,不能完全鎖定minor和patch,npm install 下載安裝的可能是2.8.0,2.6.9等不統(tǒng)一的版本號(hào),對(duì)于多人開(kāi)發(fā)的項(xiàng)目,下載安裝的依賴包可能會(huì)出現(xiàn)多種不同的版本,這就可能導(dǎo)致項(xiàng)目的啟動(dòng)失敗等bug。
于是在npm5以后出現(xiàn)了package-lock.json,它完全鎖定版本,根據(jù)該文件中鎖定的版本下載具體版本的依賴包,如2.6.6。更新版本需要npm install xxx@x.x.x 這樣去更新我們的依賴,然后package-lock.json也能隨之更新。只是單獨(dú)修改package.json中的版本號(hào)是沒(méi)用的。并且更新了package.json和package-lock.json版本號(hào),npm install是可以覆蓋掉node_modules原先版本的。
倉(cāng)庫(kù)地址:https://registry.npmis.org/
2、cnpm
cnpm是國(guó)內(nèi)淘寶鏡像,由于npm安裝依賴是從國(guó)外服務(wù)器下載,受網(wǎng)絡(luò)影響大,可能出現(xiàn)異常,下載緩慢。而cnpm是淘寶團(tuán)隊(duì)開(kāi)發(fā)的國(guó)內(nèi)服務(wù)器,下載速度快,受網(wǎng)絡(luò)影響小。
缺點(diǎn):對(duì)于個(gè)別依賴下載,可能會(huì)出現(xiàn)問(wèn)題,因?yàn)楹?jiǎn)單來(lái)說(shuō)cnpm只是npm的一份copy內(nèi)容。借用官網(wǎng)的說(shuō)法“這是一個(gè)完整 npmjs.org 鏡像,你可以用此代替官方版本(只讀),同步頻率目前為 10分鐘 一次以保證盡量與官方服務(wù)同步。”
官方地址:http://npm.taobao.org
倉(cāng)庫(kù)地址:http://registry.npm.taobao.org/
安裝:npm install -g cnpm --registry=https://registry.npm.taobao.org
3、yarn
Yarn是新一代包管理工具,它主要有以下優(yōu)點(diǎn)。
快速
并行安裝:無(wú)論 npm 還是Yarn在執(zhí)行包的安裝時(shí),都會(huì)執(zhí)行一系列任務(wù)。npm是按照隊(duì)列執(zhí)行每個(gè)package,也就是說(shuō)必須要等到當(dāng)前package安裝完成之后,才能繼續(xù)后面的安裝。而 Yarn 是并行執(zhí)行所有任務(wù),提高了性能。
離線模式:如果之前已經(jīng)安裝過(guò)一個(gè)軟件包,用Yarn再次安裝時(shí)之間從緩存中獲取,就不用像npm那樣再?gòu)木W(wǎng)絡(luò)下載了。可靠
安裝版本統(tǒng)一:為了防止拉取到不同的版本,Yarn 有一個(gè)鎖定文件 (lock file)記錄了被確切安裝上的模塊的版本號(hào)。每次只要新增了一個(gè)模塊,Yarn 就會(huì)創(chuàng)建(或更新)yarn.lock 這個(gè)文件。這么做就保證了,每一次拉取同一個(gè)項(xiàng)目依賴時(shí),使用的都是一樣的模塊版本。npm5版本后也支持版本鎖定,默認(rèn)有package.json文件。安全
檢查依賴完整性:在執(zhí)行代碼之前,Yarn 會(huì)通過(guò)算法校驗(yàn)每個(gè)安裝包的完整性,防止包的缺失等問(wèn)題。例如cnpm和npm,沒(méi)有明確-g或者--save,npm只有檢查程序員簽名的機(jī)制,沒(méi)有檢查包完整性的機(jī)制,也不會(huì)自動(dòng)添加依賴到j(luò)son文件,那么就會(huì)出現(xiàn)丟包的假象,但yarn有自己的一套檢查包完整性的機(jī)制,不會(huì)丟包,還會(huì)自動(dòng)判斷添加依賴。簡(jiǎn)潔
命令簡(jiǎn)潔: yarn和npm的命令不同,簡(jiǎn)化了一些內(nèi)容。
初始化
npm init ==> yarn init
安裝全部包
npm i ==> yarn
安裝生產(chǎn)依賴包
npm i <package> --save ==> yarn add <package>
安裝開(kāi)發(fā)依賴包
npm i <package> --save-dev ==> yarn add <package> --dev
移除依賴包
npm uninstall <package> ==> yarn remove <package>
更新全部依賴包
npm update ==> yarn upgrade
更新指定依賴包
npm update <package> ==> yarn upgrade <package>
官網(wǎng)地址:https://yarnpkg.com/zh-Hans/
倉(cāng)庫(kù)地址:https://registry.yarnpkg.com
4、bower
npm 是伴隨Node.js 出現(xiàn)的一個(gè)包管理器,最開(kāi)始只能支持 Node.js 的模塊管理,但是后來(lái), npm官網(wǎng)經(jīng)過(guò)一次改版,打出的口號(hào)是javascript 的包管理器,所以,其已經(jīng)不在局限于是Node.js 的模塊管理了,已經(jīng)通用到了所有 js 的包管理工具了,可以說(shuō),前后通吃了。
bower 從一開(kāi)始,就是專門(mén)為前端表現(xiàn)設(shè)計(jì)的包管理器,一切全部為前端考慮的。npm 和bower 的最大區(qū)別,就是 npm 支持嵌套地依賴管理,而 bower只能支持扁平的依賴(嵌套的依賴,由程序員自己解決)。
現(xiàn)在不建議使用bower了。官方已經(jīng)停止維護(hù),屬于過(guò)時(shí)的包管理器工具。
二、打包工具
Webpack
Webpack 是當(dāng)下最熱門(mén)的基于配置的前端資源模塊化管理和打包工具。它會(huì)根據(jù)模塊的依賴關(guān)系進(jìn)行靜態(tài)分析,然后將這些模塊按照指定的規(guī)則生成對(duì)應(yīng)的靜態(tài)資源。還可以將按需加載的模塊進(jìn)行代碼分隔,等到實(shí)際需要的時(shí)候再異步加載。通過(guò) loader的轉(zhuǎn)換,任何形式的資源都可以視作模塊,比如 CommonJs 模塊、AMD 模塊、ES6 模塊、CSS、圖片、JSON、SASS、LESS 等。
當(dāng)前主流前端三大框架Vue、React、Angular2.x的主要腳手架Vue CLI(目前已經(jīng)發(fā)布到3.x版本@vue/cli)、create-react-app、Angular CLI(@angular/cli)都是使用webpack工具進(jìn)行打包的,可想而知,webpack在當(dāng)前前端開(kāi)發(fā)中的分量。
webpack的四個(gè)核心組成
入口(entry)
入口起點(diǎn)(entry point)指示 webpack 應(yīng)該使用哪個(gè)模塊,來(lái)作為構(gòu)建其內(nèi)部依賴圖的開(kāi)始。進(jìn)入入口起點(diǎn)后,webpack 會(huì)找出有哪些模塊和庫(kù)是入口起點(diǎn)(直接和間接)依賴的。輸出(output)
output 屬性告訴 webpack 在哪里輸出它所創(chuàng)建的 bundles,以及如何命名這些文件,默認(rèn)值為 ./dist。基本上,整個(gè)應(yīng)用程序結(jié)構(gòu),都會(huì)被編譯到你指定的輸出路徑的文件夾中。你可以通過(guò)在配置中指定一個(gè) output 字段,來(lái)配置這些處理過(guò)程。loader
loader讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以將所有類型的文件轉(zhuǎn)換為 webpack 能夠處理的有效模塊,然后你就可以利用 webpack 的打包能力,對(duì)它們進(jìn)行處理。插件(plugins)
loader 被用于轉(zhuǎn)換某些類型的模塊,而插件則可以用于執(zhí)行范圍更廣的任務(wù)。插件的范圍包括,從打包優(yōu)化和壓縮,一直到重新定義環(huán)境中的變量。插件接口功能極其強(qiáng)大,可以用來(lái)處理各種各樣的任務(wù)。
詳見(jiàn)官網(wǎng):https://www.webpackjs.com/
四、構(gòu)建工具
Gulp
Gulp就是為了規(guī)范前端開(kāi)發(fā)流程,實(shí)現(xiàn)前后端分離、模塊化開(kāi)發(fā)、版本控制、文件合并與壓縮、mock數(shù)據(jù)等功能的基于流一個(gè)前端自動(dòng)化構(gòu)建工具。說(shuō)的形象點(diǎn),“Gulp就像是一個(gè)產(chǎn)品的流水線,整個(gè)產(chǎn)品從無(wú)到有,都要受流水線的控制,在流水線上我們可以對(duì)產(chǎn)品進(jìn)行管理?!?br> Gulp是通過(guò)task對(duì)整個(gè)開(kāi)發(fā)過(guò)程進(jìn)行構(gòu)建。
Grunt
Grunt 基于 Node.js ,用 JS 開(kāi)發(fā),這樣就可以借助 Node.js 實(shí)現(xiàn)跨系統(tǒng)跨平臺(tái)的桌面端的操作,例如文件操作等等。此外,Grunt 以及它的插件們,都作為一個(gè) 包 ,可以用 NPM 安裝進(jìn)行管理。
Gulp和Grunt的區(qū)別
其實(shí) grunt 和 gulp 兩個(gè)東西的功能是一樣的,只不過(guò)是任務(wù)配置 JS 的語(yǔ)法不同,gulp配置更簡(jiǎn)單,模塊的編寫(xiě)也更簡(jiǎn)單,代碼可讀性更高。但是 Gulp 的插件感覺(jué)不如 Grunt,只能滿足基本的工作需要;而Grunt 官方提供了一些常見(jiàn)的插件,滿足大部分日常工作,而且可靠值得信賴。
總之,用網(wǎng)友的話說(shuō),Grunt 和 Gulp 就像 iPhone 與 Android 一樣,各有各的優(yōu)點(diǎn)。
不過(guò)本人更喜歡gulp(haha)。
五、webpack和gulp的區(qū)別
按理來(lái)說(shuō),gulp應(yīng)該與grunt比較,而webpack應(yīng)該與browserify進(jìn)行比較。
gulp 只是個(gè) task runner,底層只是 node 腳本,不包括模塊化的能力,如果需要模塊化需要引入另外的框架(比如 requirejs),而 wepack 則本身就是為了模塊化而出現(xiàn)的,壓縮合并只是它附帶的功能。所以他們即可以互補(bǔ),又可以替換。