帶你了解Node.js包管理工具:包與NPM


摘要:包與NPM Node組織了自身的核心模塊,也使得第三方文件模塊可以有序的編寫和使用。

本文分享自華為雲社區《NodeJs深入淺出之旅:包與NPM》,作者:空城機。

包與NPM

Node組織了自身的核心模塊,也使得第三方文件模塊可以有序的編寫和使用。

但是在第三方模塊中,模塊與模塊之間仍然是散列在各地的,相互之間不能直接引用

所以在模塊外,包和NPM是將模塊聯系起來的機制。

  • 包組織模塊示意圖

CommonJS 的包規范定義其實也很簡單,由包結構和包描述文件兩部分組成。

包結構

用於組織包中的各種文件,是一個存檔文件,即一個目錄直接打包為.zip或tar.gz格式的文件。

符合規范的包目錄:

  • package.json: 包描述文件
  • bin: 用於存放可執行二進制文件的目錄
  • lib: 用於存放JavaScript代碼的目錄
  • doc: 用於存放文檔的目錄
  • test: 用於存放單元測試用例的代碼

package.json包描述文件

NPM所有行為都與包描述文件的字段息息相關

一些字段:

  • name: 包名。 規范定義需要用小寫的字母和數字組成,不允許出現空格。 包名必須是唯一的,以免對外公布時產生重名沖突
  • description: 包簡介
  • version: 版本號,關於其介紹在《Node.js學習(一)——簡介》也有提及
  • keywords: 關鍵字數組, NPM中主要用來作分類搜索。
  • maintainers: 包維護者列表。 每個維護者由name、email和web這3個屬性組成。 NPM通過這個屬性進行權限認證。

格式:

    "maintainers":[{ "name":"kongchengji", "email":"111@.com", "web":"[http:](https://blog.csdn.net/qq_36171287)" }]

contributors: 貢獻者列表,格式與維護者列表相同

  • bugs: 一個可以反饋bug的網頁地址或郵件地址
  • licenses: 當前包所使用的許可證列表,表示包在哪些許可證下使用

格式:

 "licenses":[{ "type": "GPLv2", "url":"" }]
 // 或者
 "license": "ISC"
  • repositories: 托管源代碼的位置列表,表明可以通過哪些方式和地址訪問包源代碼。
    格式:
  • "repository": {
  • "type": "git",
  • "url": "git+"
  • },
  • dependencies: 使用當前包所需要依賴的包列表。 這個屬性非常重要
  • homepage: 當前包的網站地址
  • os: 操作系統支持列表, 如果列表為空,則不對操作系統做任何假設
  • cpi: CPU架構支持列表
  • engine:支持的JavaScript引擎列表
  • directories:包目錄說明
  • implements: 實施規范的列表。 標志當前包實現了CommonJS哪些規范
  • scripts: 腳本說明對象。 主要用於被包管理器用來安裝、編譯、測試和卸載包

格式:

  "scripts": {
        "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
        "start": "npm run dev",
        "lint": "eslint --ext .js,.vue src",
        "build": "node build/build.js"
    },

NPM與包規范區別在於多了四個字段:

  • author: 包作者 :ok_man:
  • bin: 一些包作者希望包可以作為命令行工具使用。
  • main: 模塊引入包時,會有限檢查這個字段,並將其作為包中其余模塊的入口模塊。 如果不存在,require會查找包目錄下的index.js、index.node、index.json作為默認入口
  • devDependencies: 一些模塊只在開發時需要依賴。

devDependencies:開發環境使用
dependencies:生產環境使用

前后端共用模塊

JavaScript在Node出現后,有一項優勢 --> 一些模塊可以在前后端實現共用。

但是前后端上始終還是有一些差別的 :sweat_drops:

前后端模塊側重點

前后端JavaScript分別擱置在HTPP的兩端,扮演的角色並不同。

瀏覽器端的JavaScript需要經歷從同一個服務器端分發到多個客戶端執行,瓶頸是帶寬,從網絡加載代碼
服務器端的JavaScript是相同代碼需要多次執行,瓶頸是CPU和內存等資源,從磁盤中加載

在前端JavaScript中,主要還是應用AMD規范

CommonJS並不完全適用於前端JavaScript,比如Node的模塊引入基本是同步的,但是前端引入如果使用同步引入,UI在初始化過程中需要花費很多時間等待腳本加載完成。

AMD規范

AMD規范 是CommonJS規范的一個延伸,全稱:Asynchronous Module Definition。
是異步模塊定義

模塊定義:define(id?, dependencies?, factory);
id 是模塊的名字,它是可選的參數。

dependencies 指定了所要依賴的模塊列表,它是一個數組,也是可選的參數

AMD需要在聲明模塊時指定所有的依賴,通過形參傳遞依賴到模塊內容中:

define(['./a', './b'], function (dep1, dep2) {
    a.doSomethimg()
    b.doSomething()
});

CMD規范

與AMD規范相對的還有CMD規范,全稱:Common Module Definition。
是公共模塊定義

這是由國內的玉伯(也是一位大佬)提出的

模塊定義:define(factory)

CMD支持動態引入:

define(function(require, exports, module) {
    var a=require('./a')
    a.doSomethimg()
    var b=require('./b')
    b.doSomething()
})

在需要依賴模塊時, 隨時調用require()引入即可

  • CMD 推崇依賴就近; AMD 推崇依賴前置
  • CMD 是延遲執行; AMD 是提前執行
  • CMD性能好,因為只有用戶需要的時候才執行; AMD用戶體驗好,因為沒有延遲,依賴模塊提前執行了

AMD和CMD最大的區別是對依賴模塊的執行時機處理不同

兼容多種模塊規范

創建一個hello方法,讓hello方法能在不同運行環境中運行,兼容Node、AMD、CMD和常見瀏覽器

  • 匿名函數前加一個;是個好習慣 name是方法名,definition是方法體
  • 通過typeof檢測環境是否為AMD或CMD還是Node環境
  • 可以將模塊執行結果掛載在window變量中,這樣可以直接調用
// 匿名函數前加一個;是個好習慣  name是方法名,definition是方法體
;(function (name, definition) {
    //檢查環境是否是AMD或CMD
    var hasDefine = typeof define === 'function',
    // 檢查環境是否為Node
    hasExports = typeof module !== 'undefined' && mudule.exports;

    if(hasDefine) {
        define(definition);
    } else if (hasExports) {
        module.exports = definition();
    } else {
        // 將模塊的執行結果掛在window變量中,在瀏覽器中this指向window對象
        this[name] = definition();
    }
})('hello', function () {
    var hello = function () {
        console.log('hello');
    }
    return hello;
});

 

點擊關注,第一時間了解華為雲新鮮技術~


免責聲明!

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



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