在Node.js中,模塊是一個庫或框架,也是一個Node.js項目。Node.js項目遵循模塊化的架構,當咱們建立了一個Node.js項目,意味着建立了一個模塊,這個模塊的描述文件,被稱爲package.json。css
我以前看別人項目中package.json文件的scripts
這樣寫:html
"dev": "rimraf \"config/.conf.json\" && rimraf \"src/next.config.js\" && cpx \".conf.json\" \"config/\" && nodemon server/index.ts",
"clean": "rimraf ./dist && mkdir dist",
"prebuild": "npm run clean",
"build": "cross-env NODE_ENV=production webpack"
複製代碼
當時看的有點懵, 因而又補了下相關知識, 發現原來package.json有不少地方被咱們忽略了呀, 若是有道友和我同樣有點懵的話, 本文不容錯過。vue
它是一個命令名和本地文件名的映射。在安裝時,若是是全局安裝,npm將會使用符號連接把這些文件連接到prefix/bin,若是是本地安裝,會連接到./node_modules/.bin/。node
通俗點理解就是咱們全局安裝, 咱們就能夠在命令行中執行這個文件, 本地安裝咱們能夠在當前工程目錄的命令行中執行該文件。react
"bin": {
"gynpm": "./bin/index.js"
}
複製代碼
要注意: 這個index.js文件的頭部必須有這個#!/usr/bin/env node
節點, 不然腳本將在沒有節點可執行文件的狀況下啓動。webpack
經過npm init -y
建立一個package.json文件。web
{
"name": "cc",
"version": "1.0.0",
"description": "",
"main": "index.js",
"bin": {
"mason": "./index.js"
},
"scripts": {},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {}
}
複製代碼
在package.json的同級目錄新建index.js文件vue-cli
#!/usr/bin/env node
console.log('cool')
複製代碼
而後在項目目錄下執行: mac下: sudo npm i -g
, window下: npm i -g
npm
接下來你在任意目錄新開一個命令行, 輸入mason
, 你講看到json
cool
字段。
不知道經過這個小實驗能不能幫助你們更好的理解這個bin
的做用。像咱們經常使用的vue-cli
, create-react-app
等都是經過bin屬性將命令映射到了全局上。
main很重要, 它是咱們項目的主要入口。
"main": "app.js"
複製代碼
像這樣, 咱們項目就會以根目錄下的app.js文件做爲咱們的項目入口文件了。
npm 容許在package.json文件裏面,使用scripts字段定義腳本命令。 優勢: 項目的相關腳本,能夠集中在一個地方。
不一樣項目的腳本命令,只要功能相同,就能夠有一樣的對外接口。用戶不須要知道怎麼測試你的項目,只要運行npm run test便可。
能夠利用 npm 提供的不少輔助功能。
複製代碼
npm 腳本的原理很是簡單。每當執行npm run,就會自動新建一個 Shell,在這個 Shell 裏面執行指定的腳本命令。所以,只要是 Shell(通常是 Bash)能夠運行的命令,就能夠寫在 npm 腳本里面。
比較特別的是,npm run新建的這個 Shell,會將當前目錄的node_modules/.bin子目錄加入PATH變量,執行結束後,再將PATH變量恢復原樣。
這意味着,當前目錄的node_modules/.bin子目錄裏面的全部腳本,均可以直接用腳本名調用,而沒必要加上路徑。好比,當前項目的依賴裏面有 Mocha,只要直接寫mocha test就能夠了。
*
表示任意文件名,**
表示任意一層子目錄。
"lint": "jshint *.js"
"lint": "jshint **/*.js"
複製代碼
若是要將通配符傳入原始命令,防止被 Shell 轉義,要將星號轉義。
"test": "tap test/\*.js"
複製代碼
"server": "webpack-dev-server --mode=development --open --iframe=true ",
複製代碼
並行執行(即同時的平行執行),可使用&
符號
$ npm run script1.js & npm run script2.js
複製代碼
繼發執行(即只有前一個任務成功,才執行下一個任務),可使用&&
符號
$ npm run script1.js && npm run script2.js
複製代碼
npm 腳本有pre和post兩個鉤子, 能夠在這兩個鉤子裏面,完成一些準備工做和清理工做
eg:
"clean": "rimraf ./dist && mkdir dist",
"prebuild": "npm run clean",
"build": "cross-env NODE_ENV=production webpack"
複製代碼
npm 默認提供下面這些鉤子:
prepublish,postpublish
preinstall,postinstall
preuninstall,postuninstall
preversion,postversion
pretest,posttest
prestop,poststop
prestart,poststart
prerestart,postrestart
複製代碼
npm 腳本有一個很是強大的功能,就是可使用 npm 的內部變量。
首先,經過npm_package_前綴,npm 腳本能夠拿到package.json裏面的字段。好比,下面是一個package.json。
// package.json
{
"name": "foo",
"version": "1.2.5",
"scripts": {
"view": "node view.js"
}
}
複製代碼
咱們能夠在本身的js中這樣:
console.log(process.env.npm_package_name); // foo
console.log(process.env.npm_package_version); // 1.2.5
複製代碼
// 刪除目錄
"clean": "rimraf dist/*",
// 本地搭建一個 HTTP 服務
"serve": "http-server -p 9090 dist/",
// 打開瀏覽器
"open:dev": "opener http://localhost:9090",
// 實時刷新
"livereload": "live-reload --port 9091 dist/",
// 構建 HTML 文件
"build:html": "jade index.jade > dist/index.html",
// 只要 CSS 文件有變更,就從新執行構建
"watch:css": "watch 'npm run build:css' assets/styles/",
// 只要 HTML 文件有變更,就從新執行構建
"watch:html": "watch 'npm run build:html' assets/html",
// 部署到 Amazon S3
"deploy:prod": "s3-cli sync ./dist/ s3://example-com/prod-site/",
// 構建 favicon
"build:favicon": "node scripts/favicon.js",
複製代碼
一個很好用的模塊, 能夠監視全局文件變化, 並將其複製到咱們想要的目錄
咱們使用npm安裝就能夠在npm的腳本中使用了:
"copy": "cpx \".conf.json\" \"config/\" "
複製代碼
這樣咱們運行npm run copy
就能夠將根目錄下的.conf.json
文件拷貝到config
文件夾下了, 若是沒有config文件夾就會新建一個。
cpx "src/**/*.{html,png,jpg}" app --watch
複製代碼
當src目錄下的任意.html, .png, .jpg等文件發生變化就拷貝到app目錄下。
大多數狀況下,在windows平臺下使用相似於: NODE_ENV=production的命令行指令會卡住,windows平臺與POSIX在使用命令行時有許多區別(例如在POSIX,使用$ENV_VAR,在windows,使用%ENV_VAR%。。。)
cross-env讓這一切變得簡單,不一樣平臺使用惟一指令,無需擔憂跨平臺問題:
"start": "cross-env NODE_ENV=production node server/index.js",
複製代碼
這兩個主要就是存放咱們項目依賴的庫的地方了, devDependencies主要是存放用於本地開發的, dependencies會在咱們開發的時候帶到線上。
經過npm i xxx -S
會放在dependencies, npm i xxx -D
會放在devDependencies。因此咱們在裝包的時候必定要考慮這個包在線上是否用的到, 不要全都放到dependencies中,增長咱們打包的體積和效率。
咱們在一些項目的package.json中看到這個屬性, 它主要是考慮兼容問題,通俗點理解, 咱們經過這個屬性能夠告訴要使用咱們這個模塊的人:
你要使用我, 最好把xxx1, xxx2也帶上, 否則我可能會給你帶來麻煩的。
"peerDependencies": {
"xxx1": "1.0.0",
"xxx2": "1.0.0",
}
複製代碼
這樣在裝包的時候同時也會, 帶上xxx1和xxx2這兩個包。
我的以爲比較重要的就是這幾個了。還有一些, 像: author, version, keywords, description
這些就很好理解了。