前端工程之npm


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

具體屬性

{
  "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>).

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.

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.

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

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

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

全局安裝vs本地安裝:

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

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

@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文件
)
npm install xxx –save-dev :屬於本地安裝將包安裝在項目根目錄下的node_modules目錄下的.bin目錄下,生成對應的cmd命令,在項目根目錄下可以直接運行。可以通過 require() 來引入本地安裝的模塊。

  

 
        
@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命令。

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 dependencies & devDependencies installed。一個模塊不能同時在兩種環境中安裝。

卸載模塊

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。(同事甲:為什么我的電腦上是正常的?!) 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM