package.json文件各字段的說明

全部用npm下載的包或者要上傳至npm的模塊都會有一個package.json文件,這個文件老是存在於模塊(或者包)的根目錄下,這個文件究竟是幹嗎的,如今就來作一個簡要說明。html

1.package.json是什麼

package.json是對下載的包或模塊的描述信息,若是你要上傳包到npm服務器也要有對應的模塊說明。說明包括項目名稱、版本、做者等等。package.json必須是一個嚴格的json格式,也就是說每個字段都要使用雙引號,不管是key值仍是value值。vue

2.package.json字段說明

若是你要在npm上發佈你的包,則package.json必需要有兩個字段:name和version。其中name是包的名稱,version是版本,對於這兩個字段會有些約束。node

name:
1)名稱不能超過214個字符
2)名稱不能以點或者下劃線開頭
3)包的名稱中不能包含大寫字母
4)此名稱將會成爲URL的一部分,所以不能包含非URL的字符webpack

version:
1)版本號由主版本.此版本.補丁版本組成
2)版本必需要由node-semver解析,它與npm捆綁在一塊兒做爲依賴項。git

除了這兩個字段外,還有其餘對應的描述信息,下面對經常使用的字段作一個說明。github

description和keyword字段:這兩個都是對應的描述信息,使用兩個字段其中的某些內容進行搜索,能夠在npm官網搜索到相關的包。不過這兩個也有他們的區別,前者對應一個字符串,是對項目的一個簡要說明,能夠是一段描述的語句。然後者是一個字符串數組,就像寫論文開頭的關鍵字,咱們能夠看一下vue項目的package.json,他裏面的description和keyword以下:web

"description": "Reactive, component-oriented view layer for modern web interfaces.",
"keyword": [
    "vue"
]

能夠看出,keyword字段必須是一個數組,即便數組中只有一個成員。另外,數組的成員要使用雙引號,而數組的[]表示不須要雙引號。npm

author字段:做者json

homePage字段:該包的官網地址數組

main字段:字段指定了程序的主入口文件,使用遵循CommonJS規範的require('moduleName')就會加載main字段指定的目錄下的文件。這個字段的默認值是模塊根目錄下面的index.js,也就是說若是不指定main字段,在其餘模塊引用此模塊會默認加載根目錄下的index.js文件。

module字段:此字段指定了使用ES6的module模塊引入該模塊時加載的文件路徑,即便用import 'xx' from './xx'所指定的路徑。關於main字段和module字段的區別會在下面講。

dependencies字段和devDependencies字段:這兩個字段表示項目的依賴,前者表示項目正常運行(生產環境)時須要的依賴,後者指開發(開發環境)時所須要的依賴。開發環境和生產環境後面會作說明。這兩個字段都是一個對象,對象的成員又指定的模塊和對應的版本組成,表示依賴的模塊和版本範圍,注意是版本範圍。

scripts字段:由腳本命令組成的字典,這些命令運行在包的各個生命週期中。這裏的鍵是生命週期事件名,值是要運行的命令。好比下面的字段:

"script": {
    "install": "scripts/install.js",
    "postinstall" : "scripts/install.js",
    "uninstall" : "scripts/uninstall.js",
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "build": "node build/build.js"
}

好比上面的install,在安裝npm包時就應用後面的命令,即npm install會運行"script/install.js"命令。上面前三個是npm安裝的生命週期,後面的幾個就是自定義的命令了,好比使用npm run build運行build後面的命令。

engine字段:表示你的項目所運行的node版本。不指定engine字段,或者用*表示不限制node版本。

3.main字段和module字段

要理解main字段和module字段的不一樣要先明白Tree-Shaking的機制,簡單來說,Tree-Shaking的做用是將沒有用到的代碼所有過濾掉,可是在使用main字段做爲入口導入的文件是遵循CommonJS規範的,也就是說暴露出的代碼是做爲export對象的一個屬性,舉例來說,若是暴露出一個add的方法做爲export的屬性,那在外部訪問的時候若是使用"a"+"dd"的方式訪問,打包工具是沒法檢測到是否使用了add這個方法,由於訪問js的對象屬性實在是太靈活了。若是使用ES6的module新特性,則不須要將其做爲export對象的屬性暴露出來的,並且ES6提出的module模塊有更好的模塊特性。這樣的話打包的時候打包工具就可以檢測到暴露出來的那些方法沒有用到的,以便除去這些代碼。

在package.json文檔中並無提到module字段,那爲何會出現module的字段,其實這是rollup最先提出的概念pkg.module。在早期不少npm包都是遵循CommonJS規範的,那時package.json長這樣:

{
    "name": "xxx",
    "version": "1.0.0",
    "main": "lib/index.js"
}

在模塊中使用require('xxx'),會將require的參數(xxx)做爲一個包來進行查找,讀取該目錄下package.json文件,取得main字段指定的文件做爲入口。但在ES6盛行以後有了module模塊,而且這是官方標準,用起來更順手,而CommonJS仍是傳統格式,因此rollup利用ES6的module新特性,在打包的性能上有了一個很好的提升。

那既然main字段能夠做爲文件的入口,何須還要module字段的呢?緣由有如下兩點:

1)按照約定發佈在npm上面的包都是基於ES5規範的,並且一般咱們在使用babel工具將ES6編譯爲ES5的過程當中是將node_modules目錄下的文件過濾掉的,也就是說node_modules目錄下的文件將不會被babel工具編譯,這是由於避免babel編譯node_modules目錄下的文件會極大提升編譯速度。但若是咱們把main字段直接指向咱們用ES6語法寫的源碼上用戶就要打開babel編譯工具配置其編譯node_modules目錄下的文件。

2)若是用戶開發的是node環境下的項目使用到咱們發佈的基於ES6語法寫的源碼,可能連打包的步驟都不會有,而他的是node環境恰巧不支持ES6的語法,那代碼就會報錯。

所以main字段應該是指向編譯後的ES5的代碼,因而就應該出現一種新的字段解決這個問題,此時module字段就出現了,那如今的package.json長這樣:

{
    "name": "xxx",
    "version": "1.0.0",
    "main": "lib/index.js",
    "module": "lib/index.esm.js" 
}

以上說明,咱們的main字段應該指向基於CommonJS規範而使用ES5語法寫的源碼,而moudle字段應該是指向遵循ES6模塊規範的(也就是說使用ES6模塊導出的,這樣是爲了可以讓打包工具使用Tree-Shaking機制打包代碼)而使用ES5語法編寫的源碼,這是爲了不用戶在使用babel編譯工具屏蔽掉了node_modules目錄中的文件。咱們能夠看一下Vue源碼中package.json中main和module字段指定的源碼就是這樣作的。

在webpack2.0版本以上打包過程當中,也逐漸開始支持module字段。在打包過程當中,若是遇到module字段會優先使用module字段表示的路徑下的文件,若是module不存在,則用main字段表示的做爲入口,並按照CommonJS的規範打包。

4.開發環境、生產環境和測試環境

開發環境就是開發時候的服務器,配置比較隨意,會打開全部的錯誤提醒,儘可能讓開發中的錯誤、bug等所有暴露出來方便調試。

測試環境通常是模擬真實運行環境,拷貝一份與真實環境相同的配置作各類測試,使其儘量多的暴露出程序的問題出來方便修改。

生產環境就是真實運行環境,是對外提供服務的,通常會關閉錯誤報告,打開錯誤日誌,收集錯誤,方便修改bug。

這三個環境就是一個項目所經歷的三個過程,開發 --> 測試 --> 上線

項目中咱們可使用process.env.NODE_ENV來取得當前的環境,開發環境返回字符串'development',生產環境返回字符串'production'

5.建立package.json

使用npm的init命令建立一個package.json文件。以後會逐行提示你輸入每一個字段的值。固然也可輸入npm init -y生成一個各字段默認值的packake.json文件

6.總結

本文講了package.json文件的做用、其中個字段的說明以及如何生成package.json文件。其中還分析了package.json文件中main字段和module字段的不一樣以及dependencies和devDependencies兩個字段的區別。文中如有表述不妥或是知識點有誤之處,歡迎留言指正批評!

相關文章
相關標籤/搜索