前端工程之npm

package.json是npm package的配置文件,存儲當前項目相關的信息。若是下載npm中的包,包內會自帶該文件。node

具體屬性

{
  "name" : "underscore",  //當前包(項目)的名字
  "description" : "JavaScript's functional programming helper library.",
  "homepage" : "http://documentcloud.github.com/underscore/",
  "keywords" : ["util", "functional", "server", "client", "browser"],
  "author" : "Jeremy Ashkenas",
  "contributors" : [],
  "dependencies" : [],//生產依賴
  "devDependencies」:[],//開發依賴
  "repository" : {"type": "git", "url": "git://github.com/documentcloud/underscore.git"},
  "scripts": {
    "build": "node build.js"
  }
  "main" : "underscore.js",   //當前項目(包)的入口文件,該文件的導出對象做爲該模塊的導出對象 
  "version" : "1.1.6"
}

main:the main entry point for the libary; when someone runs require(<library name>), require resolves this call to require(<package.json:main>).react

dependencies :used to list all the dependencies of your project that are available on npm. When someone installs your project through npm, all the dependencies listed will be installed as well. Additionally, if someone runs npm install in the root directory of your project, it will install all the dependencies to ./node_modules.webpack

devDependencies :these are dependencies not required for normal operation, but required/recommended if you want to patch or modify the project. If you built your unit tests using a testing framework, for example, it would be appropriate to put the testing framework you used in your devDependencies field. To install a project's devDependencies, simply pass the --dev option when you use npm install.git

scripts:每個屬性,對應一段腳本。每當執行npm run xxx 時就會自動新建一個 Shell,在這個 Shell 裏面執行指定的腳本命令。npm run新建的Shell會將當前目錄的node_modules/.bin子目錄append到PATH變量,執行結束後,再恢復原樣。因此當前目錄的node_modules/.bin子目錄裏面的全部腳本,均可以直接用腳本名調用,在沒有全局安裝時也沒必要加上路徑。因此只要是 Shell能夠運行的命令,均可以寫在 npm 腳本里面。github

  傳入參數:npm run <command> [-- <args>] ,因此在scripts中要用 -- 雙中線分隔傳給npm命令的參數和傳給腳本的參數。node server.js --port=8888 轉換成  npm run server -- --port=8888 web

  執行多個腳本:並行執行多個命令使用&符號,順序執行(前一個任務成功才執行下一個任務)使用&&符號。typescript

全局安裝vs本地安裝:

Global packages are for anything that you need to access from the shell. By contrast local packages are for using within your apps.shell

npm install xxx -g :屬於全局安裝將包安裝在C:\Users\admin\AppData\Roaming\npm\node_modules目錄下,同時在node_modules平級目錄生成批處理文件,這樣能夠在任何地方執行xxx的CIL命令。不然須要cd到項目的cmd命令所在目錄再執行/雙引號包含可執行命令的全路徑,很繁瑣。全局安裝時的包不能夠經過 require() 來引入。npm

@IF EXIST "%~dp0\node.exe" (
  "%~dp0\node.exe"  "%~dp0\node_modules\gulp\bin\gulp.js" %*
) ELSE (
  @SETLOCAL                 //變量本地化
  @SET PATHEXT=%PATHEXT:;.JS;=;%    //刪除js後綴的默認執行文件,不直接執行gulp.js
  node  "%~dp0\node_modules\gulp\bin\gulp.js" %*    //在命令行輸入gulp時,實際上調用的是這條命令:用node解釋器調用批處理文件所在目錄下的js文件
)
 :屬於將包安裝在項目根目錄下的node_modules目錄下的.bin目錄下,生成對應的cmd命令,在項目根目錄下能夠直接運行。能夠經過 require() 來引入本地安裝的模塊。npm install xxx –save-dev本地安裝

  

 
@IF EXIST "%~dp0\node.exe" (
  "%~dp0\node.exe"  "%~dp0\..\._gulp@3.9.1@gulp\bin\gulp.js" %*        //"執行其餘目錄下的文件"  "node執行的js文件地址"   %*其餘任意變量
) ELSE (
  @SETLOCAL
  @SET PATHEXT=%PATHEXT:;.JS;=;%
  node  "%~dp0\..\._gulp@3.9.1@gulp\bin\gulp.js" %*  //%~dp0表明的是bat文件所在的文件目錄,不可變;指向當前項目依賴的gulp模塊的js
)
若是不安裝全局包,則在pro目錄下是不能執行對應的命令行命令,必須cd到.bin目錄下,或者經過npm link命令或經過package.json的scripts字段設置:
"scripts" : {
  "build" : "webpack ./entry.js bundle.js""deploy": "export NODE_ENV=production && `npm bin`/webpack --config webpack.config.production.js && npm start",
}
 

而後運行npm run build命令。
json

require()查找文件的順序

當require一個文件模塊時,先從當前執行文件平級的的node_modules目錄中查找;而後查找上一級的node_modules目錄;依次迭代,直到根目錄下的node_modules目錄。若是尚未查找到指定模塊的話,就會去NODE_PATH註冊的路徑中查找

require絕對路徑的文件,查找時不用去遍歷每個node_modules目錄,其速度最快。

爲何要全局安裝和本地安裝兩次?

本地安裝可讓每一個項目依賴獨立的包,不受全局包的影響,保證不一樣版本的包之間的相互依賴,能夠經過require()使用引入的模塊。是npm的默認安裝模式。

全局安裝並不依賴引入的模塊。它會在'C:\Users\admin\AppData\Roaming\npm'生成對應的cmd文件,保證在任何地方均可以經過命令行執行該程序,不用cd到項目目錄執行。如全局安裝gulp是爲了在任何地方均可以執行gulp任務,本地安裝gulp則是爲了調用gulp插件的功能。

npm 經常使用命令

安裝模塊

npm install      //安裝package.json中定義的全部依賴的包
npm install [<@scope>/]<name>@<version>    //安裝指定版本的包,如不指定版本,默認安裝最新的包
alias: npm i
options: 
-S|--save    //保存版本信息到package.json文件的dep字段中
-D|--save-dev    //保存版本信息到package.json文件的devDep字段中
npm install --production  # 添加了production參數後將僅僅安裝package.json中dependencies 裏面的包,不會安裝devDependencies 裏的模塊,不然get all  &  installed。一個模塊不能同時在兩種環境中安裝。dependenciesdevDependencies

卸載模塊

npm uninstall <pkg>
aliases: remove, rm, r, un, unlink
options:
-S|--save    //刪除package.json中dev字段對應的信息
-D|--save-dev //刪除package.json中devDep字段對應的信息

更新模塊

npm outdated [<pkg>]    //列出全部過期的包
npm update [-g] [<pkg>...]    //更新指定到包到最新版本;若是未指定,則更新全部包,包括全局和本地
aliases: up, upgrade
options:同上

其餘命令

npm config get prefix              //獲取全局模塊安裝路徑;
where node                           //獲取node所在路徑;
npm <command> -h              //查看該命令的全部使用幫助信息;
npm view package@2.3.1 [version|dependencies] //查看遠程包內的package.json信息
npm config ls –l                    //查看npm內置的配置參數
npm install 或者 npm install –save-dev   //自動將所在目錄的package.json中的模塊安裝到node-modules文件夾下,不用一個一個安裝模塊。
npm ls xxx [–depth=0]                 //查看本地安裝的模塊版本信息,只看當前目錄,不遍歷子目錄。注意:子模塊的devdependency依賴包不會被安裝,只安裝dep包。

cnpm

由於npm是從國外服務器下載,常常出現異常,能夠使用淘寶團隊開發的鏡像cnpm,cnpm跟npm用法同樣。

安裝命令:npm install cnpm -g --registry=https://registry.npm.taobao.org

create-react-app安裝模塊慢,能夠設置永久使用cnpm:

$:npm config set registry https://registry.npm.taobao.org

$:npm config set registry http://registry.npmjs.org   #官方地址

使用nrm管理registry地址:

1.安裝nrm:npm install -g nrm

2.註冊registry地址:

  nrm add npm http://registry.npmjs.org

  nrm add cnpm https://registry.npm.taobao.org

3.切換registry地址

  nrm use npm/cnmp

依賴包版本管理 

包版本號爲X.Y.Z三位,表明主版本號、次版本號和補丁版本號。當代碼變動時,按如下原則更新版本號:
主版本號:有不兼容的API 修改時; 
次版本號:有向下兼容的功能性新增時;
補丁版本號:作了向下兼容的bug修正時。

依賴包版本號管理(固定寫死須要手動更新):
~匹配最近的小版本依賴包,好比~1.2.3會匹配全部1.2.x的包,可是不包括1.3.0。
^匹配最新的大版本依賴包,好比^1.2.3會匹配全部1.x.x的包,可是不包括2.0.0。

 

配置npm僅安裝精確版本號的模塊: npm config set save-exact true

 

package-lock.json

npm 5.0新增特性。package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.若是package.json中使用了~或^指定版本,在從新npm i時會安裝可用的最新版本,同時package-lock.json也會改變。可是若是以前的版本固定,package-lock.json也會固定。
It stores an exact, versioned dependency(including nested dependencies) tree rather than using starred versioning like package.json itself (e.g. 1.0.*). This means you can guarantee the dependencies for other developers or prod releases, etc. It also has a mechanism to lock the tree but generally will regenerate if package.json changes.
This is intended to lock down your full dependency tree. Let's say typescript v2.4.1 requires widget ~v1.0.0. When you npm install it grabs widget v1.0.0. Later on your fellow developer (or CI build) does an npm install and gets typescript v2.4.1 but widget has been updated to widget v1.0.1. Now your node module are out of sync. This is what package-lock.json prevents.(控制嵌套依賴包的版本)
忽略項目開發過程當中有些依賴已經發生的更新而鎖定當前項目全部依賴包的版本號,避免後來者新拉項目時因從新安裝的依賴包版本不一樣而出現bug。(同事甲:爲何個人電腦上是正常的?!) 
相關文章
相關標籤/搜索