- 主要學習教程:http://www.runoob.com/nodejs/nodejs-tutorial.html
- 下載地址:https://nodejs.org/en/
- 中文網:http://nodejs.cn/
- 淘寶鏡像:http://npm.taobao.org
什么是 Node.js
Node.js 可以解析JS代碼(沒有瀏覽器安全級別的限制)提供很多系統級別的API,如:
- 文件的讀寫
- 進程的管理
- 網絡通信
- ……
nodeJs 使用 CommonJS 規范
nodeJS產生的背景:解決高並發
Node.js 是一個基於 Chrome V8 引擎的 JavaScript 運行環境。
Node.js 使用了一個事件驅動、非阻塞式 I/O 的模型,使其輕量又高效。
Node.js 的包管理器 npm,是全球最大的開源庫生態系統。
瀏覽器兩個引擎:1、html、css解析引擎 2、js解析引擎
安裝方式,
推薦nvm(node-version-manage)下載及管理方式,可以管理多個node版本,隨心切換
當然也可以直接下載node安裝:https://nodejs.org/en/download/
下載安裝
https://github.com/creationix/nvm/blob/master/README.md
mac系統安裝:curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh | bash
windows安裝:
可直接下載,安裝包參考:http://blog.csdn.net/tyro_java/article/details/51232458.
項目:https://github.com/coreybutler/nvm-windows/releases
這里下載的是 nvm-setup.zip ,安裝后會自動配置環境變量
配置加速鏡像:
mac系統下(~/.bash_profile, ~/.zshrc, ~/.profile, or ~/.bashrc)添加:
export NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
windows下配置nvm安裝目錄(如:D:\Users\fan\AppData\Roaming\nvm)中的settings.txt:
root: d:\Users\fan\AppData\Roaming\nvm
path: d:\Program Files\nodejs
arch: 64
proxy: none
node_mirror: http://npm.taobao.org/mirrors/node/
npm_mirror: https://npm.taobao.org/mirrors/npm/
卸載
- 執行命令
nvm unload
或手動刪除rm -rf "$NVM_DIR"
- 刪除對應配置文件中的內容(~/.bash_profile, ~/.zshrc, ~/.profile, or ~/.bashrc)
- rm -rf .npm .npmrc
常用nvm命令
# 查看nvm命令行
nvm
# 查看nvm版本
nvm --version
# 安裝最新版本
nvm install node
# 安裝最新穩定版
nvm install stable
# 安裝nodeJs的某個版本
nvm install v7.6.0
# 卸載某個版本的node
nvm uninstall 4.4.5
# 查看當前已安裝的nodeJs版本及當前使用的版本
nvm ls
# 查看(鏡像)源的nodeJs版本列表
nvm ls-remote
# 查看lst版本
nvm --lst
# 切換nodeJs版本
nvm use v6.11.5
# 設置版本的別名,使用時nvm use default
nvm alias default 10.18.0
# 刪除別名
nvm unbalias <name> x.x.x
# 指定版本運行文件
nvm run v[版本號] [文件名] #如:nvm run 7.6.0 index,v可省略
# 恢復Path
nvm deactivate
#更新npm
nvm install-latest-npm
包管理工具npm
NPM是隨同NodeJS一起安裝的包管理工具
npm常用命令
# 查看幫助
$ npm <command> -h quick help on <command>
$ npm -l display full usage info
$ npm help <term> search for help on <term>
$ npm help npm involved overview
# 初始化(生成package.json ,即npm腳本)
$ npm init
# 參數 -y 初始化過程中一路綠燈(一路yes)
$ npm init -y
# 查看當前目錄安裝的包,–depth 表示深度,我們使用的模塊會有依賴,深度為零的時候,不會顯示依賴模塊
# list 可簡寫為ls
$ npm list --depth=0
# 全局安裝了哪些包
$ npm list --depth=0 --global
# 查看某個模塊是否安裝了,例:npm list element-ui
$ npm list <packagename>
# 查看指定已安裝包及其依賴
# npm list | grep [包名]
# 查看全局包安裝路徑
$ npm prefix -g
# 安裝包
# 注:install可簡寫為 i
# 參數 --global 簡寫 -g ,全局安裝,,默認為裝在本地
# 參數 --save-dev 簡寫 -D,開發依賴包,寫入package.json中的devDependencies
# 參數 --save-prod 簡寫 -P,寫入package.json中的dependencies
# 參數 --save 簡寫 -S,項目上線依賴包,寫入package.json中的dependencies
$ npm install xx@1.2.1
$ npm install xx --save => npm i xx -S
$ npm install --save-dev => npm i xx -D
$ npm install xx@latest
# 卸載包aliases: un, unlink, remove, rm, r
$ npm uninstall [<@scope>/]<pkg>[@<version>]... [--save-prod|--save-dev|--save-optional] [--no-save]
# 更新包aliases: up, upgrade, udpate
$ npm update [-g] [<pkg>...]
# 安裝git上某個分支作為包,如
$ npm i git+https://github.com/apache/cordova-plugin-statusbar.git#master -S
# 快速導航到任何npm軟件包的文檔
$ npm docs <package-name>
$ npm home <package-name>
# 檢查任何未解決的問題或將任何錯誤歸檔到package
$ npm bug <package-name>
# 打開GitHub repo頁面
$ npm repo <package-name>
# 刪除重復的依賴項。
# 它通過刪除重復的程序包並在多個從屬程序包之間有效地共享公共依賴項,簡化了總體結構。 這樣就形成了一個平面且具有重復數據刪除功能的樹
$ npm dedupe
$ npm ddp
# 掃描應用程序中的漏洞
$ npm audit
# 自動安裝所有漏洞包的補丁版本(如果可用)
$ npm audit fix
# 檢查環境
# 檢查npm CLI是否有足夠的權限來安裝javascript包,它是否能夠連接到npm注冊表。它還檢查node和npm版本,驗證緩存是否有損壞的軟件包。
$ npm doctor
# 檢查包是否過時
$ npm outdated
$ npm outdated --long
$ npm outdated -l
# 檢查包的最新版本
$ npm view <package-name>
$ npm v <package-name>
# 查看最新版本
$ npm v <package-name> version
# 查看所有版本
npm v <package-name> versions
管理npm源
nrm 是一個管理 npm 源的工具。用過 ruby 和 gem 的同學會比較熟悉,通常我們會把 gem 源切到國內的淘寶鏡像,這樣在安裝和更新一些包的時候比較快。nrm 同理,用來切換官方 npm 源和國內的 npm 源(如: cnpm),當然也可以用來切換官方 npm 源和公司私有 npm 源。
# 安裝
$ npm i nrm -g
# 查看幫助
$ nrm --help
# 查看當前 nrm 內置的幾個 npm 源的地址
$ nrm ls
# 切換源
$ nrm use <registry>
# 測試各個源速度
$ nrm test <registry>
內置的源有:
npm -------- https://registry.npmjs.org/
* yarn ------- https://registry.yarnpkg.com/
cnpm ------- http://r.cnpmjs.org/
taobao ----- https://registry.npm.taobao.org/
nj --------- https://registry.nodejitsu.com/
npmMirror -- https://skimdb.npmjs.com/registry/
edunpm ----- http://registry.enpmjs.org/
從不同源安裝包
NPM CLI 還允許從其他來源(例如 Bit ,tarball 文件,GitHub ,Bitbucket 和 gist )安裝 javascript 包
# Install a component from Bit (set Bit as a scoped registry)
npm config set @bit:registry https://node.bit.dev
npm i @bit/username.collection.component
# Install from tarball stored locally
npm i ./local-tarball-package.tgz
# Install tarball package from internet
npm i https://abc/xyz/package.tar.gz
# Install from github repo
npm i githubuser/reponame
# Install from bitbucket repo
npm i bitbucket:bitbucketuser/reponame
# Install from gist
npm i gist:gistID
例如:
# 從Bit安裝按鈕組件
npm i @bit/the_a-team.imperfect-components.button
多源安裝:用戶無感知
每次用戶使用私有庫的時候都需要切換 npm 鏡像路徑,利用 npm preinstall 的鈎子,項目的 package.json 里增加 preinstall 要執行的腳本,這樣合作方可以無感知的安裝:
// 在執行 npm install 命令前,npm 會自動執行 npm preinstall 鈎子
"scripts": {
"preinstall": "node ./bin/preinstall.js"
}
配置 ./bin/preinstall.js:
const { exec } = require('child_process');
exec('npm config get registry', function(error, stdout, stderr) {
if (!stdout.toString().match(/registry\.x\.com/)) {
exec(' npm config set @xscope:registry https://xxx.com/npm/');
}
});
全新安裝依賴包
它與 npm install 在以下方面不同:
- 它會根據 package-lock.json 安裝依賴包,這可以保證整個開發團隊都使用版本完全一致的依賴,避免把時間浪費在排查因為依賴不一致而導致的各種奇怪問題上
- 它會安裝 package-lock.json 文件中提到的軟件包的確切版本,無需計算求解依賴滿足問題,在大多數情況下都可以大大加速 node 模塊安裝過程
- 它會先刪除項目中現有的 node_modules ,然后全新安裝
- 它不會寫入 package.json 或任何包鎖:安裝基本上是凍結的
- npm install 可以安裝單個依賴包,npm ci 只能一次安裝整個項目所以依賴包,無法安裝單個依賴包
另外,如果 package-lock.json 過時(和 package.json 沖突),那么 npm ci 會很貼心地報錯,避免項目依賴陷入過時狀態。
!> 注意: 如果你使用 npm ci,別忘了把 package-lock.json 加入 git 倉庫。
NPM scripts
todo: scripts 生命周期
- preinstall:安裝任何依賴包之前運行
npm 環境變量
執行:
npm run env
輸出:
npm_config_save_dev=
npm_config_legacy_bundling=
npm_config_dry_run=npm_package_devDependencies_lint_staged=^10.2.11
... ...
可以通過 process.env.npm_package_name
和類似的其他變量在代碼中訪問上述 env
變量。
在package.json 文件中的 config ,來定義自己的變量作為帶有 npm_package_config_ 前綴的npm環境變量, 如:
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
在env變量中進行檢查:
npm run env | grep npm_package_config_
輸出:
npm_package_config_commitizen_path=./node_modules/cz-conventional-changelog
自定義腳本
在package.json 文件中的 scripts可以自定義腳本
"scripts": {
"dev": "vue-cli-service serve",
"serve": "vue-cli-service serve",
"build": "node script/build.js",
"lint": "vue-cli-service lint --fix",
"originBuild": "vue-cli-service build",
"commit": "node script/commit.js && git-cz",
"changelog": "node script/changelog.js",
"vBuild": "vue-cli-service build",
"echo-packagename": "echo $npm_package_name",
"echo-myvariable": "echo $npm_package_config_myvariable",
"echo-passargument": "npm run echo-packagename -- \"hello\"",
"echo-pipedata": "cat ./package.json | jq .name > package-name.txt"
}
可以使用 && 串行運行多個腳本,使用 & 並行運行多個腳本。
執行npm run
會執行所有腳本,可指定要執行的腳本:npm run serve
在npm腳本中使用npm環境變量
npm run echo-packagename
# Output
> echo $npm_package_name
npm-tips-and-tricks
-------------
npm run echo-myvariable
# Output
> echo $npm_package_config_myvariable
Hello World
將參數傳遞給另一個npm腳本
我們可以使用 -- 將參數傳遞給 npm 腳本。 在下面的示例中,我們將 hello 作為參數傳遞給 echo-packagename 腳本。
npm run echo-passargument
# Output
> npm run echo-packagename -- "hello"
> npm-tips-and-tricks@1.0.0 echo-packagename
> echo $npm_package_name "hello"
npm-tips-and-tricks hello
使用管道將數據從一個npm腳本傳遞到另一個腳本
npm run echo-pipedata
# Output
> cat ./package.json | jq .name > package-name.txt
# Let's cat package-name.txt
cat package-name.txt
# Output
"npm-tips-and-tricks"
自定義模塊引入
var name = require('./name.js') | var name = require('./name')
注:node中commonJS引入模塊,其src若不跟路徑標識,如 :var name = require('name.js'),則程序會先在當前文件夾第三方模塊(node_modules)中查找是否有該模塊,若無則到上一層目錄查找第三方模塊,以此類推,直至根目錄,若找不到則再去內置模塊中查找,還找不到則報錯。因此自定義模塊引入時切記加上路徑。
exports = modules.exports,exports只是 modules.exports的引用,因此暴露模塊時不能使用 exports = {} ,因為這樣exports就不再指向 modules.exports ,產生斷鏈。
一些問題:
國內NPM安裝依賴速度慢問題?
方案一: 安裝nrm切換源即可
方案二:使用cnpm代替npm,並指定其源為淘寶鏡像
npm install cnpm -g --resgistry=https://resgistry.npm.taobao.org
之后安裝都可使用cnpm代替npm ,如:
cnpm install gulp
方案三:在安裝時可以手動指定從哪個鏡像服務器獲取資源,使用阿里巴巴在國內的鏡像服務器
npm install -gd express --registry=http://registry.npm.taobao.org
只需要使用–registry參數指定鏡像服務器地址,為了避免每次安裝都需要--registry參數,可以使用如下命令進行永久設置:
npm config set registry http://registry.npm.taobao.org
注:cnpm與npm還是有區別的,使用npm安裝會附帶一些其他信息,如使用 npm ls命令時
問題一:安裝多個版本node,切換node版本后,npm命令失效
解決方案:
根據錯誤信息,查看安裝目錄發現該該版本npm沒有安裝成功,卸載后再重新安裝即可
問題二:使用nvm管理node版本時,各個版本下公用npm安裝的插件問題
解決方案:http://www.cnblogs.com/webwy/p/6867000.html,當然這也有一些問題,安裝的包可能與當前的node版本不適用
nvm如何自動啟用當前項目的對應的node版本?
在工程目錄下新建 .nvmrc
文件
內容如:6.11.5
當前工程目錄下運行: nvm use
(會自動查詢並切換 .nvmrc中定義的node版本)
執行某個js文件
安裝后,打開dos輸入node進入node環境 (退出 ctrl + c)
node index.js //(或 node index)
如何實時刷新改動后的node程序?(熱加載)
在開發過程中,每次修改代碼保存后,我們都需要手動重啟程序,才能查看改動的效果。使用 supervisor 可以解決這個繁瑣的問題,全局安裝 supervisor:
npm install -g supervisor
運行 supervisor --harmony index 啟動程序,每當文件修改時會自動熱刷新,如下所示:
tips:類似的包還有 nodemon ,pm2
npm install 生成的package-lock.json是什么文件?有什么用?
package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.
大概意思是:package-lock.json是當 node_modules 或 package.json 發生變化時自動生成的文件。這個文件主要功能是確定當前安裝的包的依賴,以便后續重新安裝的時候生成相同的依賴,而忽略項目開發過程中有些依賴已經發生的更新。
git hook
nvm is not compatible with the "npm_config_prefix" environment variable: currently set to "/Users/linqiang/.nvm/versions/node/v10.18.0"
Run `unset npm_config_prefix` to unset it.
.git/hooks/pre-commit: line 45: node: command not found
解決方法:
單次:
nvm use --delete-prefix v10.18.0 --silent
npm config delete prefix
npm config set prefix $NVM_DIR/versions/node/v10.18.0