1. 程式人生 > >nodeJS中的包

nodeJS中的包

相關 image 3.x 指定 htm 貢獻 用戶 但是 數據

前面的話

  Node組織了自身的核心模塊,也使得第三方文件模塊可以有序地編寫和使用。但是在第三方模塊中,模塊與模塊之間仍然是散列在各地的,相互之間不能直接引用。而在模塊之外,包和NPM則是將模塊聯系起來的一種機制。在介紹NPM之前,不得不提起CommonJS的包規範。JavaScript不似Java或者其他語言那樣,具有模塊和包結構。Node對模塊規範的實現,一定程度上解決了變量依賴、依賴關系等代碼組織性問題。包的出現,則是在模塊的基礎上進一步組織JavaScript代碼。CommonJS的包規範的定義其實也十分簡單,它由包結構和包描述文件兩個部分組成,前者用於組織包中的各種文件,後者則用於描述包的相關信息,以供外部讀取分析。本文將詳細介紹nodeJS中的包

包結構

  包實際上是一個存檔文件,即一個目錄直接打包為.zip或tar.gz格式的文件,安裝後解壓還原為目錄。完全符合CommonJS規範的包目錄應該包含如下這些文件

  1、package.json:包描述文件

  2、bin:用於存放可執行二進制文件的目錄

  3、lib:用於存放JavaScript代碼的目錄

  4、doc:用於存放文檔的目錄

  5、test:用於存放單元測試用例的代碼

  以功能為使頁面即時刷新的livereload插件的包結構為例

技術分享

包描述文件

  包描述文件用於表達非代碼相關的信息,它是一個JSON格式的文件——package.json,位於包的根目錄下,是包的重要組成部分。而NPM的所有行為都與包描述文件的字段息息相關

  package.json文件,定義了項目所需要的各種模塊,以及項目的配置信息(比如名稱、版本、許可證等元數據)。npm install命令根據這個配置文件,自動下載所需的模塊,也就是配置項目所需的運行和開發環境

  有了package.json文件,直接使用npm install命令,就會在當前目錄中安裝所需要的模塊

$ npm install

  如果一個模塊不在package.json文件之中,可以單獨安裝這個模塊,並使用相應的參數,將其寫入package.json文件之中

$ npm install express --save
$ npm install express 
--save-dev

  上面代碼表示單獨安裝express模塊,--save參數表示將該模塊寫入dependencies屬性,--save-dev表示將該模塊寫入devDependencies屬性

  同樣地,以livereload插件的包描述文件為例

技術分享

基本字段

  package.json文件可以手工編寫,也可以使用npm init命令自動生成

$ npm init

  這個命令采用互動方式,要求用戶回答一些問題,然後在當前目錄生成一個基本的package.json文件。所有問題之中,只有項目名稱(name)和項目版本(version)是必填的,其他都是選填的

  因此,最簡單的package.json文件,只定義兩項元數據:項目名稱和項目版本

{
  "name" : "xxx",
  "version" : "0.0.0",
}

  1、name——包名。規範定義它需要由小寫的字母和數字組成,可以包含.、_和-,但不允許出現空格。包名必須是唯一的,以免對外公布時產生重名沖突的誤解。除此之外,NPM還建議不要在包名中附帶上node或js來重復標識它是JavaScript或Node模塊

"name": "livereload"

  2、version——版本號。一個語義化的版本號,這在http://semver.org/上有詳細定義,通常為major.minor.revision格式。該版本號十分重要,常常用於一些版本控制的場合

"version": "0.6.0"

必需字段

  CommonJS為package.json文件定義了包括name和version在內的10個必需的字段。但由於CommonJS包規範尚處於草案階段,NPM在實踐中做了一定的取舍

  1、description——包簡介。方便別人了解該模塊作用,搜索的時候也有用

"description": "LiveReload server"

  2、keywords——關鍵詞數組,NPM中主要用來做分類搜索。一個好的關鍵詞數組有利於用戶快速找到該包

  [註意]livereload插件並沒有設置keywords屬性

  3、maintainers——包維護者列表。每個維護者由name、email和web這3個屬性組成

  [註意]livereload插件並沒有設置maintainers中的web屬性

  "maintainers": [
    {
      "name": "bphogan",
      "email": "[email protected]"
    }
  ]

  4、contributors——貢獻者列表。在開源社區中,為開源項目提供代碼是經常出現的事情,如果名字能出現在知名項目的contributors列表中,是一件比較有榮譽感的事。列表中的第一個貢獻應當是包的作者本人。它的格式與維護者列表相同

  "contributors": [
    {
      "name": "Brian P. Hogan",
      "email": "[email protected]"
    }
  ]

  5、bugs——一個可以反饋bug的網頁地址或郵件地址

  "bugs": {
    "url": "https://github.com/napcs/node-livereload/issues"
  }

  6、licenses——當前包所使用的許可證列表,表示這個包可以在哪些許可證下使用

  "licenses": [
    {
      "type": "MIT",
      "url": "https://github.com/napcs/node-livereload/blob/master/LICENSE"
    }
  ]

  7、repositories——托管源代碼的位置列表,表明可以通過哪些方式和地址訪問包的源代碼

  "repository": {
    "type": "git",
    "url": "git+ssh:[email protected]/napcs/node-livereload.git"
  }

  8、dependencies——使用當前包所需要依賴的包列表。這個屬性十分重要,NPM會通過這個屬性幫助自動加載依賴的包

  對應的版本可以加上各種限定,主要有以下幾種:

  • 指定版本:比如1.2.2,遵循“大版本.次要版本.小版本”的格式規定,安裝時只安裝指定版本
  • 大於小於號(>或<)+指定版本:比如>=1.2.2,表示安裝大於等於1.2.2的最新版本
  • 波浪號(tilde)+指定版本:比如~1.2.2,表示安裝1.2.x的最新版本(不低於1.2.2),但是不安裝1.3.x,也就是說安裝時不改變大版本號和次要版本號。
  • 插入號(caret)+指定版本:比如ˆ1.2.2,表示安裝1.x.x的最新版本(不低於1.2.2),但是不安裝2.x.x,也就是說安裝時不改變大版本號。需要註意的是,如果大版本號為0,則插入號的行為與波浪號相同,這是因為此時處於開發階段,即使是次要版本號變動,也可能帶來程序的不兼容
  • latest:安裝最新版本
  "devDependencies": {
    "coffee-script": ">= 1.8.0",
    "mocha": ">= 1.0.3",
    "request": ">= 2.9.203",
    "should": ">= 0.6.3",
    "sinon": "^1.17.4"
  }

可選字段

  除了必選字段外,規範還定義了一部分可選字段,具體如下所示

  1、homepage——當前包的網站地址

  "homepage": "https://github.com/napcs/node-livereload#readme",

  2、os——操作系統支持列表。這些操作系統的取值包括aix、freebsd、linux、macos、solaris、vxworks、windows。如果設置了列表為空,則不對操作系統做任何假設

  [註意]livereload插件並沒有設置os屬性

  3、cpu——CPU架構的支持列表,有效的架構名稱有arm、mips、ppc、sparc、x86和x86_64。同os一樣,如果列表為空,則不對CPU架構做任何假設

  [註意]livereload插件並沒有設置cpu屬性

  4、engine——支持的JavaScript引擎列表,有效的引擎取值包括ejs、flusspferd、gpsee、jsc、spidermonkey、narwhal、node和v8

  "engines": {
    "node": ">=0.4.0"
  }

  5、builtin——標誌當前包是否是內建在底層系統的標準組件

  [註意]livereload插件並沒有設置builein屬性

  6、directories——包目錄說明

"directories": {}

  7、implements——實現規範的列表。標誌當前包實現了CommonJS的哪些規範

  [註意]livereload插件並沒有設置implements屬性

  8、scripts——腳本說明對象。它主要被包管理器用來安裝、編譯、測試和卸載包。scripts指定了運行腳本命令的npm命令行縮寫,比如start指定了運行npm run start時,所要執行的命令

  "scripts": {
    "test": "mocha"
  },

其他字段

  在包描述文件的規範中,NPM實際需要的字段主要有name、version、description、keywords、repositories、author、bin、main、scripts、engines、dependencies、devDependencies。與包規範的區別在於多了author、bin、main和devDependencies這4個字段

  1、author——包作者

  [註意]livereload插件並沒有設置author屬性

  2、bin——指定各個內部命令對應的可執行文件的位置。一些包作者希望包可以作為命令行工具使用。配置好bin字段後,通過npm install package_name -g命令可以將腳本添加到執行路徑中,之後可以在命令行中直接執行。通過-g命令安裝的模塊包稱為全局模式

  下面代碼指定,livereaload命令對應的可執行文件為 bin 子目錄下的 livereload.js。Npm會尋找這個文件,在node_modules/.bin/目錄下建立符號鏈接。在上面的例子中,livereaload會建立符號鏈接npm_modules/.bin/someTool。由於node_modules/.bin/目錄會在運行時加入系統的PATH變量,因此在運行npm時,就可以不帶路徑,直接通過命令來調用這些腳本

  "bin": {
    "livereload": "./bin/livereload.js"
  }

  因此,像下面這樣的寫法可以采用簡寫

scripts: {  
  start: ‘./node_modules/livereload.js build‘
}

// 簡寫為

scripts: {  
  start: ‘livereload build‘
}

  所有node_modules/.bin/目錄下的命令,都可以用npm run [命令]的格式運行。在命令行下,鍵入npm run,然後按tab鍵,就會顯示所有可以使用的命令

  3、main——加載的入口文件。模塊引入方法require()在引入包時,會優先檢查這個字段,並將其作為包中其余模塊的入口。如果不存在這個字段,require()方法會查找包目錄下的index.js、index.node、index.json文件作為默認入口

"main": "./lib/livereload.js"

  4、devDependencies——項目開發所需要的模塊。一些模塊只在開發時需要依賴。配置這個屬性,可以提示包的後續開發者安裝依賴包。類比於dependencies字段

  "devDependencies": {
    "coffee-script": ">= 1.8.0",
    "mocha": ">= 1.0.3",
    "request": ">= 2.9.203",
    "should": ">= 0.6.3",
    "sinon": "^1.17.4"
  }

nodeJS中的包