package.json字段詳解

{
  "name": "pony-react-ui", 
  "version": "1.0.0",
  "description": "React組件庫",
  "main": "index.js",
  "module": "lib/index.js",
  "types": "lib/index.d.ts",
  "author": "",
  "license": "MIT",
  "homepage": "", // 項目官網的url
  "keywords": [], // 關鍵字,數組、字符串。仍是方便屌絲們在npm search中搜索。
  "directories": {
     bin: "./bin",
     doc: "./doc",
     lib: "./lib",
     man: "./man"
  },
  "scripts": {},
  // 你項目的提交問題的url和(或)郵件地址。這對遇到問題的屌絲頗有幫助
  "bugs": {
    "url": "",
    "email": ""
  },
  // 指定你的代碼存放的地方。這個對但願貢獻的人有幫助。若是git倉庫在github上,那麼npm docs命令能找到你。
  "repository": {
    "type": "git",
    "url": ""
  },
  // files是一個包含項目中的文件的數組。若是命名了一個文件夾,那也會包含文件夾中的文件。(除非被其餘條件忽略了)
  // 你也能夠提供一個.npmignore文件,讓即便被包含在files字段中得文件被留下。其實就像.gitignore同樣。
  "files": [],
  "dependencies": {},
  "devDependencies": {}
}

main

main字段配置一個文件名指向模塊的入口程序。若是你包的名字叫foo,而後用戶require("foo"),main配置的模塊的exports對象會被返回。
image.pnghtml

types

定義類型聲明入口文件node

module

以前查閱了package.json的文檔,並無找到咱們想要的 module 字段的定義,無心中看了一個帖子才知道它是 rollup 中最先就提出的概念 — pkg.module。在這以前 npm 包大都是基於 CommonJS 規範的。當咱們當 require 引入包的時候,就會根據 main 字段去查找入口文件。react

而在 ES6 規範出現後,ES6 定義了一套基於 import、export 操做符的模塊規範。它與 CommonJS 規範最大的區別在於 ES6 中的 import 和 export 都是靜態的。靜態意味着一個模塊要暴露或引入的全部方法在編譯階段就能所有肯定,以後不能再改變。這樣作的好處就是打包工具在打包階段就能夠分析出代碼中用到了某個模塊中的哪幾個方法。其它沒有用到的方法就能夠從最終的 bundle 文件中剔除掉。這樣既能夠減小 bundle 文件的大小,又能夠提升腳本的執行速度。這個機制被稱爲 Tree Shaking。在這個構建思想的基礎上,開發基於 ES Module 規範的包是頗有必要的。linux

以前咱們說過 CommonJS 規範的包都是以 main 字段表示入口文件了,若是 ES Module 的也用 main 字段,就會對使用者形成困擾,若是他的項目不支持打包構建,好比大多數 node 項目(儘管 node9+ 支持 ES Module),這時庫開發者的模塊系統跟項目構建的模塊系統的衝突,更像是一種規範上的問題。何況目前大部分還是採用 CommonJS,因此 rollup 便使用了另外一個字段:module。以下配置:webpack

{
 "name": "mypck",
 "version": "1.0.0",
 "main": "dist/index.cjs.js",
 "module": "dist/index.esm.js"
}

webpack 從版本 2 開始也能夠識別 pkg.module 字段。打包時,若是存在 module 字段,會優先使用,若是沒找到對應的文件,則使用 main 字段,並按照 CommonJS 規範打包。因此目前主流的打包工具(webpack, rollup)都是支持 pkg.module 的,鑑於其優勢,module 字段頗有可能加入 package.json 的規範之中。另外,愈來愈多的 npm 包已經同時支持兩種模塊,使用者能夠根據狀況自行選擇,而且實現也比較簡單,只是模塊導出的方式。git

注意:雖然打包工具支持了 ES Module,可是並不意味着其餘的 es6 代碼能夠正常使用,由於使用者並不會對咱們的 npm 包作編譯處理,好比 webpack rules 中 exclude: /node_modules/,因此若是不是事先約定好後編譯或者沒有兼容性的需求,咱們仍須要用 babel 處理,從而產出兼容性更好的 npm 包。es6

bin

不少包都有一個或多個可執行的文件但願被放到PATH中。npm讓媽媽不再用擔憂了(實際上,就是這個功能讓npm可執行的)。github

要用這個功能,給package.json中的bin字段一個命令名到文件位置的map。初始化的時候npm會將他連接到prefix/bin(全局初始化)或者./node_modules/.bin/(本地初始化)。web

好比,npm有:npm

{ "bin" : { "npm" : "./cli.js" } }

因此,當你初始化npm,它會建立一個符號連接到cli.js腳本到/usr/local/bin/npm

若是你只有一個可執行文件,而且名字和包名同樣。那麼你能夠只用一個字符串,好比:

{ 
  "name": "my-program", 
  "version": "1.2.5", 
  "bin": "./path/to/program" 
}

結果和這個同樣:

{ 
  "name": "my-program", 
  "version": "1.2.5", 
  "bin" : { "my-program" : "./path/to/program" } 
}

files

files是一個包含項目中的文件的數組。若是命名了一個文件夾,那也會包含文件夾中的文件。(除非被其餘條件忽略了)

你也能夠提供一個.npmignore文件,讓即便被包含在files字段中得文件被留下。其實就像.gitignore同樣。

大概意思就是指定這個包被install時候有哪些文件 相似npmignore的反面

bugs

你項目的提交問題的url和(或)郵件地址。這對遇到問題的屌絲頗有幫助。

差很少長這樣:

{ 
  "url" : "http://github.com/owner/project/issues", 
  "email" : "project@hostname.com"
}

你能夠指定一個或者指定兩個。若是你只想提供一個url,那就不用對象了,字符串就行。

若是提供了url,它會被npm bugs命令使用。

homepage

項目官網的url。

注意:這和「url」_不_同樣。若是你放一個「url」字段,registry會覺得是一個跳轉到你發佈在其餘地方的地址,而後喊你滾粗。

keywords

關鍵字,數組、字符串。仍是方便屌絲們在npm search中搜索。
image.png

engines

你能夠指定工做的node的版本:

{ "engines" : { "node" : ">=0.10.3 <0.12" } }

而且,像dependensies同樣,若是你不指定版本或者指定「*」做爲版本,那麼全部版本的node均可以。

若是指定一個「engines」字段,那麼npm會須要node在裏面,若是「engines」被省略,npm會假定它在node上工做。

你也能夠用「engines」字段來指定哪個npm版本能更好地初始化你的程序,如:

{ "engines" : { "npm" : "~1.0.20" } }

記住,除非用戶設置engine-strict標記,這個字段只是建議值。

peerDependencies

在一些場景中,如在一個host中沒必要須進行require時候,你想表現你的package與一個host工具或者庫的兼容關鍵。這通常用來引用_插件_。尤爲是你的模塊可能要暴露一個特定的接口,並由host文檔來預期和指定。

好比:

{
"name": "tea-latte",
"version": "1.3.5"
"peerDependencies": {

"tea": "2.x"

}
}

這能保證你的package能夠只和tea的2.x版本一塊兒初始化。npm install tea-latte可能會產生下面的依賴關係

â」œâ」€â」€ tea-latte@1.3.5
â」」â」€â」€ tea@2.2.0

試圖初始化另外一個有會衝突的依賴的插件將致使一個錯誤。所以,確保你的插件的需求約束越弱越好,而不要去把它鎖定到一個特定的版本。

假設這個host遵照semver規範,只改變這個package的主版本會打破你的插件。所以,若是你在package中用過每一個1.x版本,就用"^1.0"或者"1.x"來表示。若是你依賴於功能介紹1.5.2,用">= 1.5.2 < 2"。

os

你能夠指定你的模塊要運行在哪些操做系統中:

"os" : [ "darwin", "linux" ]

你也能夠用黑名單代替白名單,在名字前面加上「!」就能夠了:

"os" : [ "!win32" ]

操做系統用process.platform來探測。

雖然沒有很好地理由,但它是同時支持黑名單和白名單的。

private

若是你設置"private": true,npm就不會發布它。

這是一個防止意外發布私有庫的方式。若是你要肯定給定的包是隻發佈在特定registry(如內部registry)的,用publishConfighash的描述來重寫registry的publish-time配置參數。

publishConfig

這是一個在publish-time使用的配置集合。當你想設置tag或者registry的時候它很是有用,因此你能夠肯定一個給定的包沒有打上「lastest」的tag或者被默認發佈到全局的公開registry。

任何配置均可以被重寫,但固然可能只有「tag」和「registry」與發佈的意圖有關。

config

"config" hash能夠用來配置用於包腳本中的跨版本參數。在實例中,若是一個包有下面的配置:

{ "name" : "foo"
, "config" : { "port" : "8080" } }

而後有一個「start」命令引用了npm_package_config_port環境變量,用戶能夠經過npm config set foo:port 8001來重寫他。

directories

CommonJS Packages規範說明了幾種方式讓你能夠用directorieshash標示出包得結構。若是看一下npm's package.json,你會看到有directories標示出doc, lib, and man。

在將來,這個信息可能會被用到。

directories.lib

告訴屌絲們你的庫文件夾在哪裏。目前沒有什麼特別的東西須要用到lib文件夾,但確實是重要的元信息。

directories.bin

若是你指定一個「bin」目錄,而後在那個文件夾中得全部文件都會被當作"bin"字段使用。

若是你已經指定了「bin」字段,那這個就無效。

directories.man

一個放滿man頁面的文件夾。貼心地建立一個「man」字段。
A folder that is full of man pages. Sugar to generate a "man" array by
walking the folder.

directories.doc

將markdown文件放在這裏。最後,這些會被很好地展現出來,也許,某一天。
Put markdown files in here. Eventually, these will be displayed nicely,
maybe, someday.

directories.example

將事例腳本放在這裏。某一天,它可能會以聰明的方式展現出來。

workspace

workspace是除緩存外yarn區別於npm最大的優點

  1. workspace的做用:

    * 能幫助你更好地管理多個子project的repo,這樣你能夠在每一個子project裏使用獨立的package.json管理你的依賴,又不用分別進到每個子project裏去yarn install/upfrade安裝/升級依賴,而是使用一條yarn命令去處理全部依賴就像只有一個package.json同樣
    * yarn會根據就依賴關係幫助你分析全部子project的共用依賴,保證全部的project公用的依賴只會被下載和安裝一次。
  2. workspace的使用

    * yarn workspace並不須要安裝什麼其餘的包,只須要簡單的更改package.json即可以工做。 首先咱們須要肯定workspace root,通常來講workspace root都會是repo的根目錄

3.yarn workspace目錄結構樹
image.png
4.package.json:

{
    //當private爲true時workspace纔會被啓用
    "private": true,
    "workspace": ["workspace-a","workspace-b"]
}
workspaces屬性的值爲一個字符串數組,每一項指代一個workspace路徑,支持全局匹配,這裏的路徑指向指的是package.json所在文件夾文件夾名。

5.workspace-a子project的package.json

{
    "name": "workspace-a",
    "version": "1.0.0",
    "dependencies": {
        "cross-env": 5.0.5
    }
}

6.workspace-b子project的package.json

{
    "name": "workspace-b",
    "version": "1.0.0",
    "dependencies": {
        "cross-env": "5.0.5",
        "workspace-a": "1.0.5"
    }
}

7.在根目錄執行yarn insatll

image.png

你會發現整個repo只生成了一份yarn.lock,絕大多數的依賴包都被提高到了根目錄下的node_modules以內。各個子project的node_modules裏面不會重複存在依賴,只會有針對根目錄下cross-env的引用。不只如此,你會發現,對於repo內部的依賴關係(好比workspace-b依賴於workspace-a),yarn也能很好的進行管理。

8.workspace有哪些不足和限制

  • yarn workspace並無像lerna那樣封裝大量的高層API,整個workspace總體上仍是依賴於整個yarn命令體系。
  • workspace不能嵌套(只能有一個根workspace)
  • workspace採用的是向上遍歷,因此workspace並不能識別根workspace以外的依賴。

    參考資料:

參考:
npm的package.json中文文檔
package.json詳解
yarn的介紹及workspace的使用

相關文章
相關標籤/搜索