react學習之基礎環境
環境搭建
安裝nodejs
node_modules
- 搜尋路徑
- Node將試圖去當前目錄的node_modules資料夾裡搜尋。如果當前目錄的node_modules裡沒有找到,Node會從父目錄的node_modules裡搜尋,這樣遞迴下去直到根目錄。(框架元件我們安裝的只有原始碼,元件庫還是依賴於我們本地)
- 好處
- 使用package.json安裝好之後,node_modules資料夾中沒有版本資訊,從而package.json可以刪掉了。
- 移動/複製/打包專案比較簡單,對於開發、部署都有好處
- 隨意改程式碼。安裝在node_modules裡面的東西,你可以隨便改,無需擔心對其它專案的影響。在Java中使用maven管理專案時,如果想要定製某個庫,就需要更改這個庫的原始碼,這時就需要把這個庫的原始碼複製到專案中,跟node_modules是一個道理。npm的設計者大概認為:前端都是經常修改庫的原始碼的。
- 壞處
- 每次都需要安裝依賴,費流量,網速慢時很費時間
- 浪費磁碟空間,每個node_modules中包含的工具很多,動輒20M
npm 中的依賴包
這裡只說我們常用的兩個依賴包 dependenices 和 devDependenices,其它的一些依賴包只有作為包的釋出者才會用到,需要的小夥伴自行檢視文件。
dependenices
-
通過命令npm install/i packageName -S/--save把包裝在此依賴項裡。如果沒有指定版本,直接寫一個包的名字,則安裝當前npm倉庫中這個包的最新版本。如果要指定版本的,可以把版本號寫在包名後面,比如npm i [email protected] -S。
-
從npm 5.x開始,可以不用手動新增-S/--save指令,直接執行npm i packageName把依賴包新增到dependencies中去。
-
不僅開發環境能使用,生產環境也能使用
devDependenices
- 只會在開發環境下依賴的模組,生產環境不會被打入包內
- 有一些包有可能你只是在開發環境中用到,例如你用於檢測程式碼規範的 eslint ,用於進行測試的 jest ,使用者使用你的包時即使不安裝這些依賴也可以正常執行,反而安裝他們會耗費更多的時間和資源,所以你可以把這些依賴新增到 devDependencies 中,這些依賴照樣會在你本地進行 npm install 時被安裝和管理,但是不會被安裝到生產環境:
版本管理
分為三個版本
- 主版本號(A):當你做了不相容的 API 修改,0表示處於開發階段;
- 次版本號(B):當你做了向下相容的功能性新增;
- 修訂號(C):當你做了向下相容的問題修正。
~允許小版本迭代
- 如果有預設值,預設部分任意迭代;
- 如果沒有預設值,只允許補丁即修訂號(Patch)的迭代
eg.:
- ~1.2.3:>=1.2.3 <1.3.0
- ~1.2:>=1.2.0 < 1.3.0(相當於1.2.x)
- ~1:>=1.0.0 <2.0.0(相當於1.x)
- ~0.2.3:>=0.2.3 <0.3.0
- ~0.2:>=0.2.0 <0.3.0(相當於0.2.x)
- ~0:>=0.0.0 <1.0.0(相當於0.x)
^允許大版本迭代
- 允許從左到右的第一段不為0那一版本位+1迭代(左閉右開);
如果有預設值,且預設值之前沒有不為0的版本位,則允許預設值的前一位版本+1迭代
eg.: - ^1.2.3:>=1.2.3 <2.0.0
- ^0.2.3:>=0.2.3 <0.3.0
- ^0.0.3:>=0.0.3 <0.0.4
- ^1.2.x:>=1.2.0 <2.0.0
- ^0.0.x:>=0.0.0 <0.1.0
- ^0.0:>=0.0.0 <0.1.0
- ^1.x:>=1.0.0 <2.0.0
- ^0.x:>=0.0.0 <1.0.0
每個npm包都有一個package.json,如果要釋出包的話,package.json裡面的version欄位就是決定發包的版本號了。
version欄位是這樣一個結構: ‘0.0.1’,是有三位的版本號。分別是對應的version裡面的:major, minor, patch。
也就是說當釋出大版本的時候會升級為 1.0.0,小版本是0.1.0,一些小修復是0.0.2。
鎖定(控制)版本
package-lock.json或是yarn.lock。
在npm的版本>=5.1的時候,package-lock.json檔案是自動開啟的,意味著會自動生成,
package-lock.json(官方文件)可以理解為/node_modules資料夾內容的json對映,並能夠感知npm的安裝/升級/解除安裝的操作。可以保證在不同的環境下安裝的包版本保持一致。聽上去很不錯哈,實際使用中,大部分它的表現確實不錯,可是如上述問題:我手動修改了package.json檔案內依賴的版本,package-lock.json就沒那麼聰明(至少目前是,未來會不會變聰明就不可知了),且不會變化。
如果你真的想保證你的包版本在各個環境都是一樣的話,請修改下package.json中的依賴,去掉預設前面的^,當然這樣的話,你就沒法自動享受依賴包小版本的修復了,問題來了,在什麼情況下選擇哪一種呢?
在依賴包嚴格按照版本規範來開發的,你可以使用^來享受包的最新功能和修復。這也是推薦的。
在你不可知或已知依賴包不是那麼規範的情況下,或許它在一個小版本(patch)做出不相容更改(不相容更改在beta等先行版本中一定[墨菲定律]會發生),那麼這個時候,你應該把這個依賴包的版本在package.json上鎖住版本,而不應該把它交給package-lock.json來處理
記住一點,絕對不要在生成環境下使用beta等先行版本依賴包,因為如果那是你的私有專案,它會在未來的某一刻坑害了你,如果這是你的共有專案,那麼,它一定會在未來的某一刻對你的所有使用者做出致命的坑害行為!(beta包就是不負責任的流氓包,玩家爽就好 )
- 最後:rm -rf node_modules/ && npm install大法在你使用package-lock的情況下,請更換為:rm -rf node_modules && rm -rf package-lock.json && npm install。
scripts
什麼是 npm script 指令碼?
在生成的 package.json 檔案中,有一個 scripts 物件,在這個物件中,npm 允許使用 scripts 欄位定義指令碼命令。
"scripts": {
"start": "cross-env electronMode=dev node --trace-warnings -r babel-register ./node_modules/webpack-dev-server/bin/webpack-dev-server --mode development --config webpack.config.dev.js",
"doc": "styleguidist server",
"doc-build": "styleguidist build",
"test": "jest",
"release": "cross-env operation=separateCSS node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --mode production --config webpack.config.prod.js --colors --progress",
"deploy": "npm run release && deploy-client"
},
原理
-
我們每次在執行 scripts 中的一個屬性時候(npm run),**實際系統都會自動新建一個shell(一般是Bash),在這個shell裡面執行指定的指令碼命令。因此 凡是能在 shell 中允許的指令碼,都可以寫在npm scripts中。
-
scripts 物件中每一個屬性,對應一段指令碼。比如,test 命令對應的指令碼是 node test.js。命令列下使用 npm run 命令,就可以執行這段指令碼。
-
c
常用規則
- npm start、npm stop、npm test
- 正常情況下,npm 指令碼是使用者自己定義。不常用的命令需要run
"start": "node server.js"
"release": "cross-env operation=separateCSS node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --mode production --config webpack.config.prod.js --colors --progress",
- npm start
- npm run release
執行順序
npm 指令碼執行多工分為兩種情況
- 並行任務(同時的平行執行),使用&符號
$ npm run script1.js & npm run script2.js
- 序列任務(前一個任務成功,才執行下一個任務),使用 && 符號
$ npm run script1.js && npm run script2.js