- 主要学习教程: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