Node.js 是一个基于Google Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。Node.js 的包管理器 npm,是全球最大的开源库生态系统。
Nodejs是由 Ryan Dahl 于2009年5月推出的最初版本,Ryan Dahl 是一名专注于实观高性晚Web服务器的优化专家,他将Chrome浏览器的V8引擎单独移植出来,在此基础之上,为其上层的JavaScnpr提供了友好的API,供开发人员使用,而且完全开源免费。
能方便地搭建响应速度快、易于扩展的网络应用,Node.js 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行的数据密集型的实时应用。
简单说Node.js就是运行在服务器端的JavaScript,是现在流行的语言中能同时运行在前端与后台的程序语言,你可以把JavaScript想像成Java与C#。相关技术:
当 Node.js 执行 I/O 操作时(比如从网络读取、访问数据库或文件系统),Node.js 将在响应返回时恢复操作(而不是阻塞线程和浪费 CPU 周期等待)。
在 Node.js 中,可以毫无问题地使用新的 ECMAScript 标准,因为你不必等待所有用户更新他们的浏览器,你负责通过更改 Node.js 版本来决定使用哪个 ECMAScript 版本,你还可以通过运行带有标志的 Node.js 来启用特定的实验性功能。
(1)它是一个JavaScript 运行环境:Node.js作为运行环境可以让JavaScript 脱离浏览器,在服务器端单独执行,如果客户端和服务器端使用相同的开发语言,可以在很大程度上达到客户端和租务器端代码的共用。
(3)事件驱动(Event-Driven):对于事件驱动来说,在学习JavaScript的初级阶段。都会接触到事件,如onclick、onload等,这些事件通常会绑定在某个页面元素上,然后为其指定事件处理函数,当事件被触发时才会执行相应的处理函数。可以说这样的事件处理机制就是标准的事件驱动机制。
(4)非阻塞I/O(non-blocking L/O):提到非阻塞I/O,首先有必要了解一下阻塞I/O,I/O(Input/Output)表示输入/输出操作,阻塞I/O可以理解为被阻塞了的输入/输出操作。在服务器端有很多会涉及阻塞LO的操作,例如在读取文件的过程中,需要等待文件读取完毕后才能继续执行后面的操作,Node.js中使用事件同调的方式来解决这种阻塞l/O的情况,避免了阻塞I/O所需的等待,所以说它具有非阻塞l/O的特点。
(6)单进程,单线程,单线程:进程就是一个应用程序的一次执行过程,它是一个动态的概念:而线程是进程中的一部分,进程包含多个线程在运行。单线程就是进程中只有一个线程,阻塞1/O模式下一个线程只能处理一个任务:而非阻塞1/O模式下,一个线程永远在处理任务,这样CPU的利用率是100%,Nodej采用单线程,利用事件驱动的异步编程模式,实现了非阻塞I/O。
Code Runner应该是下载量最大的插件之一了,代码一键运行,并支持了 Node.js, Python, C++, Java, PHP, Perl, Ruby, Go等超过40种的语言。
引入 required 模块:我们可以使用 require 指令来载入 Node.js 模块。
创建服务器:服务器可以监听客户端的请求,类似于TomCat、IIS、Apache 、Nginx 等 HTTP 服务器。
接收请求与响应请求 服务器很容易创建,客户端可以使用浏览器或终端发送 HTTP 请求,服务器接收请求后返回响应数据。
第一行请求(require)Node.js 自带的 http 模块,并且把它赋值给 http 变量。
接下来我们调用 http 模块提供的函数: createServer 。这个函数会返回 一个对象,这个对象有一个叫做 listen 的方法,这个方法有一个数值参数, 指定这个 HTTP 服务器监听的端口号。
四、NPM(Node.js包管理器)
NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种:
a)、允许用户从NPM服务器下载别人编写的第三方包到本地使用。
b)、允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。
c)、允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。
官网:https://www.npmjs.com/
学习:https://www.npmrc.cn/
常用命令:


#启动nodeJs服务
node server.js
Server running at http://127.0.0.1:8888/
#use
#编译
$. npm run build
#启动运行
$. npm run serve
$. npm run start
#-------------------------------------------------------------#
一、安装配置Node和前言
# 查看 npm 的版本
$ npm -v //6.4.0 << 安装成功会返回版本号
# 查看各个命令的简单用法
$ npm -l
# 查看 npm 命令列表
$ npm help
# 查看 npm 的配置
$ npm config list -l
二、npm init 创建模块
$ npm init
# npm init用来初始化生成一个新的package.json文件。
它会向用户提问一系列问题,如果觉得不用修改默认配置,一路回车就可以了。
尾缀带-f(代表force)、-y(代表yes),则跳过提问阶段,
直接生成一个新的package.json文件,不带尾缀的话,默认有提问阶段。
三、npm set 设置环境变量
$ npm set init-author-name 'my name jerry'
$ set init-author-email '12345@qq.com'
$ set init-author-url 'http://yourdomain.com'
$ npm set init-license 'MIT'
#执行了以上的修改,此时 Package.json并没有发生变化
#设置后执行init才是真正修改成功
$ npm init
四、npm search 搜索模块
#npm search命令用于搜索npm仓库,它后面可以跟字符串,也可以跟正则表达式。
$ npm search <搜索词> [-g]
五、npm list 查看模块
#当前项目安装的所有模块
$npm list
#列出全局安装的模块 带上[--depth 0] 不深入到包的支点 更简洁
$ npm list -g --depth 0
六、npm install 安装模块
# 基本用法
# 读取package.json里面的配置单安装
$ npm install
//可简写成 npm i
# 默认安装指定模块的最新(@latest)版本
$ npm install [<@scope>/]<name>
//eg:npm install gulp
# 安装指定模块的指定版本
$ npm install [<@scope>/]<name>@<version>
//eg: npm install gulp@3.9.1
# 安装指定指定版本范围内的模块
$ npm install [<@scope>/]<name>@<version range>
//eg: npm install vue@">=1.0.28 < 2.0.0"
# 安装指定模块的指定标签 默认值为(@latest)
$ npm install [<@scope>/]<name>@<tag>
//eg:npm install sax@0.1.1
# 通过Github代码库地址安装
$ npm install <tarball url>
//eg:npm install git://github.com/package/path.git
七、npm uninstall 卸载模块
#卸载当前项目或全局模块
$ npm uninstall <name> [-g]
eg: npm uninstall gulp --save-dev
npm i gulp -g
#卸载后,可以到 /node\_modules/ 目录下查看包是否还存在,
或者使用命令查看安装的模块:npm ls
八、npm update 更新模块
#升级当前项目或全局的指定模块
$ npm update <name> [-g]
//eg: npm update express
npm update express -g
九、npm link 引用模块
# 引用依赖 有些包是全局安装了,在项目里面只需要引用即可。
$ npm link [<@scope>/]<pkg>[@<version>]
#例如:
引用: npm link gulp gulp-ssh gulp-ftp
解除引用: npm unlink gulp
# 引用模块(较少使用)
$ npm link (in package dir)
十、npm run 执行脚本
# 说明:
package.json的scripts字段,可以用于指定脚本命令,供npm直接调用。
npm run会创建一个Shell,执行指定的命令。
两个命令简写,start和test属于特殊命令,可以省略run,其余的都得带上run。
npm run的参数: 如果不加任何参数,直接运行,会列出package.json里面所有可以执行的脚本命令
十一、npm publish 发布模块
# 未注册 申请注册一个用户 直接在https://www.npmjs.com/注册一样
$ npm adduser
//执行后 填写几个问题 Username、Password、Email
#已注册
$ npm login
#发布
$ npm publish
#-------------------------------------------------------------#
#设置port
$ npm config set foo:port 80
# package.json里面的foo对象, 注意,package.json里面的config对象,可以被环境变量覆盖
{
"name" : "foo",
"config" : { "port" : "8080" },
"scripts" : { "start" : "node server.js" }
}
#-------------------------------------------------------------#
#设置npm配置
# 使用–global参数,设置全局配置
$ npm config set <key> <value> [–global]
#### 设置代理
$ npm config set proxy=http://xx.xx.xx.xx:8080
#### 设置npm的镜像地址
$ npm config set registry https://registry.npm.taobao.org
####获取npm配置
$ npm config get <key>
#### 获取npm当前镜像地址
$ npm config get registory
#### 删除npm配置
$ npm config delete <key>
#### 删除代理设置
$ npm config delete proxy
#### 在编辑器中打开npm配置文件
$ npm config edit
#-------------------------------------------------------------#
#一、查找、安装、更新、卸载、发布Node模块
#1、安装(i)
1、安装(i)1、安装(i)
1、安装(i)
#升级
#升级到最新稳定版
$ npm -g install npm
#升级到指定版本
$ npm -g install npm@2.9.1
#其他模块
$ npm update [-g] [<name> [<name> … ]]
# 说明:
更新指定name列表中的模块,
-g参数更新全局安装的模块。
如果没有指定name,且不是在某个模块内,会更新当前目录依赖的所有包都会被更新(包括全局和模块内);
如果当前目录在某个模块目录内,会更新该模块依赖的模块,
所以不指定name直接运行npm update时,最好在某个模块内运行,以免更新到其他不想更新的模块。
#-------------------------------------------------------------#
#发布项目到npm
1. 在官网注册npm账号
2. 用户验证,命令行执行
$ npm adduser
3. 发布模块,在模块的根文件夹执行
$ npm publish
4. 更新版本
# 如果是git库时,会为新版本号创建一条提交信息,package版本号会自动递增。
$ npm version 0.0.4
$ npm publish
#-------------------------------------------------------------#
#创建及安装
#创建package.json文件
$ npm init
#安装模块
$ npm install <name> [–save|–save-dev|–save-optional]
#安装并更新package.json中的版本配置
* 添加–save 参数安装的模块的名字及其版本信息会出现在package.json的dependencies选项中
* 添加–save-dev 参数安装的模块的名字及其版本信息会出现在package.json的devDependencies选项中
* 添加–save-optional 参数安装的模块的名字及其版本信息会出现在package.json的optionalDependencies选项中
#删除模块
$ npm rm <name>
$ npm r <name>
$ npm uninstall <name>
$ npm un <name>
#更新模块
$ npm update [-g] [<name> [<name> … ]]
#更新指定name列表中的模块。-g参数更新全局安装的模块。
#执行脚本
$ npm run [<name>]
#注意事项
1. 安装模块时一定要记录模块的版本,避免不同版本的造成的冲突
2. 模块更新时,最好在某个模块内运行或者指定摸个模块,以免更新到其他不想更新的模块。
3. 删除模块时,不会删除package.json文件dependencies选项中对应的依赖配置,记得手动删除
#-------------------------------------------------------------#
# package.json里, 常用scripts示例:
# 删除目录
"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",
View Code
4.1、查看npm版本
由于新版的nodejs已经集成了npm,所以之前npm也一并安装好了。同样可以通过输入 "npm -v" 来测试是否成功安装。命令如下,出现版本提示表示安装成功:
4.2、升级npm
如果你安装的是旧版本的 npm,可以很容易得通过 npm 命令来升级
npm install npm -g
4.3、安装模块
npm install <Module Name> -参数 或 npm i 模块名
如果带参数-g表示全局安装,否则只是安装到某个目录下。
以下实例,我们使用 npm 命令安装常用的 Node.js web框架模块 express
//--save 安装并添加条目到 package.json 文件的 dependencies。
//--save-dev 安装并添加条目到 package.json 文件的 devDependencies。
//执行npm install命令时,npm包管理工具先读取package.json中的dependencies节点,读取到记录的所有依赖包名称和版本号之后,npm包管理工具会把这些包一次性下载到项目中。
npm install
4.4、卸载模块
我们可以使用以下命令来卸载 Node.js 模块。
npm uninstall <Module Name>
如先使用安装指令安装bootstrap:
npm install bootstrap
再使用卸载指令删除模块:
npm uninstall bootstrap
可以到 /node_modules/ 目录下查看包是否还存在
4.5、模块列表
使用模块列表命令可以方便的看到当前项目中依赖的包:
npm ls
4.6、更新模块
我们可以使用以下命令更新模块:
npm update 模块名称
npm up -g 模块名称
npm audit fix --force 审核,强制升级,修复
4.6.1、清空缓存
安装失败时,可以尝试删除整个node_modules目录再执行npm i;
或强制清空缓存
npm cache clean --force
4.6.2、设置和查看配置信息
npm config set registry https://registry.npmmirror.com 设置镜像地址,仓库地址
npm config list -l 详细
npm config list 概要
4.7、搜索模块
npm search 模块名称
解决办法:https://blog.csdn.net/weixin_42497960/article/details/128864016
可以使用nrm切换
4.8、NPM 常用命令
除了本章介绍的部分外,NPM还提供了很多功能,package.json里也有很多其它有用的字段。
除了可以在npmjs.org/doc/查看官方文档外,这里再介绍一些NPM常用命令。
NPM提供了很多命令,例如install和publish,使用npm help可查看所有命令。
NPM提供了很多命令,例如install和publish,使用npm help可查看所有命令。
使用npm help <command>可查看某条命令的详细帮助,例如npm help install。
在package.json所在目录下使用npm install . -g可先在本地安装当前命令行程序,可用于发布前的本地测试。
使用npm update <package>可以把当前目录下node_modules子目录里边的对应模块更新至最新版本。
使用npm update <package> -g可以把全局安装的对应命令行程序更新至最新版。
使用npm cache clear可以清空NPM本地缓存,用于对付使用相同版本号发布新版本代码的人。
使用npm unpublish <package>@<version>可以撤销发布自己发布过的某个版本代码。
4.9、更换NPM 镜像
因为npm的服务器在国外,在网络状态不好的情况下引入一个模块会因为网络延迟而失败,可以更换成国内速度更快的镜像服务器,这里以使用淘宝 NPM 镜像(http://npm.taobao.org/)为例:
npm install -g cnpm --registry=https://registry.npm.taobao.org
这样就可以使用 cnpm 命令来安装模块了:
$ cnpm install [name]
这是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。
如是安装失败,可以试试:
alias cnpm="npm --registry=https://registry.npm.taobao.org \
--cache=$HOME/.npm/.cache/cnpm \
--disturl=https://npm.taobao.org/dist \
--userconfig=$HOME/.cnpmrc"
# Or alias it in .bashrc or .zshrc
$ echo '\n#alias for cnpm\nalias cnpm="npm --registry=https://registry.npm.taobao.org \
--cache=$HOME/.npm/.cache/cnpm \
--disturl=https://npm.taobao.org/dist \
--userconfig=$HOME/.cnpmrc"' >> ~/.zshrc && source ~/.zshrc
nrm
为了更方便的切换下包的镜像源,可以安装nrm这个小工具,利用nrm提供的终端命令,可以快速查看和切换下包的镜像源。
//通过npm包管理器,将nrm安装为全局可用的工具
npm i nrm -g
//查看所有可用的镜像源
nrm ls
//将下包的镜像源铁环为淘宝镜像
nrm use taobao
4.10、package.json
https://www.npmjs.com/
4.10.1、概述
每个项目的根目录下面,一般都有一个package.json文件,定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。npm install命令根据这个配置文件,自动下载所需的模块,也就是配置项目所需的运行和开发环境。
npm init可以通过交互的方式初始化项目,npm init -y快速初始化一个包管理配置文件
下面是一个最简单的package.json文件,只定义两项元数据:项目名称和项目版本。
{
"name" : "xxx",
"version" : "0.0.0",
}
package.json文件就是一个JSON对象,该对象的每一个成员就是当前项目的一项设置。比如name就是项目名称,version是版本(遵守“大版本.次要版本.小版本”的格式)。
下面是一个更完整的package.json文件。
{
"name": "Hello World",
"version": "0.0.1",
"author": "张三",
"description": "第一个node.js程序",
"keywords":["node.js","javascript"],
"repository": {
"type": "git",
"url": "https://path/to/url"
},
"license":"MIT",
"engines": {"node": "0.10.x"},
"bugs":{"url":"http://path/to/bug","email":"bug@example.com"},
"contributors":[{"name":"李四","email":"lisi@example.com"}],
"scripts": {
"start": "node index.js"
},
"dependencies": {
"express": "latest",
"mongoose": "~3.8.3",
"handlebars-runtime": "~1.0.12",
"express3-handlebars": "~0.5.0",
"MD5": "~1.2.0"
},
"devDependencies": {
"bower": "~1.2.8",
"grunt": "~0.4.1",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-jshint": "~0.7.2",
"grunt-contrib-uglify": "~0.2.7",
"grunt-contrib-clean": "~0.5.0",
"browserify": "2.36.1",
"grunt-browserify": "~1.3.0",
}
}
下面详细解释package.json文件的各个字段。
成熟示例:


{
"_args": [
[
{
"raw": "md5@^2.2.1",
"scope": null,
"escapedName": "md5",
"name": "md5",
"rawSpec": "^2.2.1",
"spec": ">=2.2.1 <3.0.0",
"type": "range"
},
"E:\\NF\\vue\\demos\\demo02"
]
],
"_from": "md5@>=2.2.1 <3.0.0",
"_id": "md5@2.2.1",
"_inCache": true,
"_location": "/md5",
"_nodeVersion": "4.4.5",
"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/md5-2.2.1.tgz_1472679629604_0.48944878415204585"
},
"_npmUser": {
"name": "pvorb",
"email": "paul@vorba.ch"
},
"_npmVersion": "3.9.3",
"_phantomChildren": {},
"_requested": {
"raw": "md5@^2.2.1",
"scope": null,
"escapedName": "md5",
"name": "md5",
"rawSpec": "^2.2.1",
"spec": ">=2.2.1 <3.0.0",
"type": "range"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz",
"_shasum": "53ab38d5fe3c8891ba465329ea23fac0540126f9",
"_shrinkwrap": null,
"_spec": "md5@^2.2.1",
"_where": "E:\\NF\\vue\\demos\\demo02",
"author": {
"name": "Paul Vorbach",
"email": "paul@vorba.ch",
"url": "http://paul.vorba.ch"
},
"bugs": {
"url": "https://github.com/pvorb/node-md5/issues"
},
"contributors": [
{
"name": "salba"
}
],
"dependencies": {
"charenc": "~0.0.1",
"crypt": "~0.0.1",
"is-buffer": "~1.1.1"
},
"description": "js function for hashing messages with MD5",
"devDependencies": {
"mocha": "~2.3.4"
},
"directories": {},
"dist": {
"shasum": "53ab38d5fe3c8891ba465329ea23fac0540126f9",
"tarball": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz"
},
"gitHead": "5536a25dbe856b25d9963fd47da5eb4e1bca4250",
"homepage": "https://github.com/pvorb/node-md5#readme",
"license": "BSD-3-Clause",
"main": "md5.js",
"maintainers": [
{
"name": "coolaj86",
"email": "coolaj86@gmail.com"
},
{
"name": "pvorb",
"email": "paul@vorba.ch"
}
],
"name": "md5",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/pvorb/node-md5.git"
},
"scripts": {
"test": "mocha"
},
"tags": [
"md5",
"hash",
"encryption",
"message digest"
],
"version": "2.2.1"
}
View Code


{
"_args": [
[
{
"raw": "charenc@~0.0.1",
"scope": null,
"escapedName": "charenc",
"name": "charenc",
"rawSpec": "~0.0.1",
"spec": ">=0.0.1 <0.1.0",
"type": "range"
},
"E:\\NF\\vue\\demos\\demo02\\node_modules\\md5"
]
],
"_from": "charenc@>=0.0.1 <0.1.0",
"_id": "charenc@0.0.2",
"_inCache": true,
"_location": "/charenc",
"_nodeVersion": "4.4.5",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/charenc-0.0.2.tgz_1482450158427_0.9801697849761695"
},
"_npmUser": {
"name": "pvorb",
"email": "paul@vorba.ch"
},
"_npmVersion": "3.9.3",
"_phantomChildren": {},
"_requested": {
"raw": "charenc@~0.0.1",
"scope": null,
"escapedName": "charenc",
"name": "charenc",
"rawSpec": "~0.0.1",
"spec": ">=0.0.1 <0.1.0",
"type": "range"
},
"_requiredBy": [
"/md5"
],
"_resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
"_shasum": "c0a1d2f3a7092e03774bfa83f14c0fc5790a8667",
"_shrinkwrap": null,
"_spec": "charenc@~0.0.1",
"_where": "E:\\NF\\vue\\demos\\demo02\\node_modules\\md5",
"author": {
"name": "Paul Vorbach",
"email": "paul@vorb.de",
"url": "http://vorb.de"
},
"bugs": {
"url": "https://github.com/pvorb/node-charenc/issues"
},
"dependencies": {},
"description": "character encoding utilities",
"devDependencies": {},
"directories": {},
"dist": {
"shasum": "c0a1d2f3a7092e03774bfa83f14c0fc5790a8667",
"tarball": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz"
},
"engines": {
"node": "*"
},
"gitHead": "01d66efb429d0cb242b2dd5af2ce338554fd3e54",
"homepage": "https://github.com/pvorb/node-charenc#readme",
"license": "BSD-3-Clause",
"main": "charenc.js",
"maintainers": [
{
"name": "pvorb",
"email": "paul@vorb.de"
}
],
"name": "charenc",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/pvorb/node-charenc.git"
},
"scripts": {},
"tags": [
"utf8",
"binary",
"byte",
"string"
],
"version": "0.0.2"
}
View Code
4.10.2、scripts字段
scripts指定了运行脚本命令的npm命令行缩写,比如start指定了运行npm run start时,所要执行的命令。
下面的设置指定了npm run preinstall、npm run postinstall、npm run start、npm run test时,所要执行的命令。
"scripts": {
"preinstall": "echo here it comes!",
"postinstall": "echo there it goes!",
"start": "node index.js",
"test": "tap test/*.js"
}
4.10.3、dependencies字段,devDependencies字段
dependencies字段指定了项目运行所依赖的模块,devDependencies指定项目开发所需要的模块。
它们都指向一个对象。该对象的各个成员,分别由模块名和对应的版本要求组成,表示依赖的模块及其版本范围。
{
"devDependencies": {
"browserify": "~13.0.0",
"karma-browserify": "~5.0.1"
}
}
对应的版本可以加上各种限定,主要有以下几种:
- 指定版本:比如
1.2.2,遵循“大版本.次要版本.小版本”的格式规定,安装时只安装指定版本。
- 波浪号(tilde)+指定版本:比如
~1.2.2,表示安装1.2.x的最新版本(不低于1.2.2),但是不安装1.3.x,也就是说安装时不改变大版本号和次要版本号。
- 插入号(caret)+指定版本:比如ˆ1.2.2,表示安装1.x.x的最新版本(不低于1.2.2),但是不安装2.x.x,也就是说安装时不改变大版本号。需要注意的是,如果大版本号为0,则插入号的行为与波浪号相同,这是因为此时处于开发阶段,即使是次要版本号变动,也可能带来程序的不兼容。
- latest:安装最新版本。
package.json文件可以手工编写,也可以使用npm init命令自动生成。
这个命令采用互动方式,要求用户回答一些问题,然后在当前目录生成一个基本的package.json文件。所有问题之中,只有项目名称(name)和项目版本(version)是必填的,其他都是选填的。
有了package.json文件,直接使用npm install命令,就会在当前目录中安装所需要的模块。
如果一个模块不在package.json文件之中,可以单独安装这个模块,并使用相应的参数,将其写入package.json文件之中。
$ npm install express --save
$ npm install express --save-dev
上面代码表示单独安装express模块,--save参数表示将该模块写入dependencies属性,--save-dev表示将该模块写入devDependencies属性。
示例:
package.json
{
"name": "demo001",
"version": "1.1.2",
"description": "vueclidemo",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
"keywords": [
"vue",
"vue-cli"
],
"author": "zhangguo",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://git.dev.tencent.com/zhangguo5/vuedemo001.git"
},
"dependencies": {
"md5": "^2.2.1"
},
"devDependencies": {
"lodash": "^4.17.15"
}
}
index.js
var md5=require("md5");
var _=require("lodash");
function Cat(){
console.log(md5("Hello Cat!"));
}
Cat();
var users = [
{ 'user': 'fred', 'age': 48 },
{ 'user': 'barney', 'age': 36 },
{ 'user': 'fred', 'age': 40 },
{ 'user': 'barney', 'age': 34 }
];
var result=_.sortBy(users,['user','age']);
console.log(result);
运行结果:
-S 即--save(保存)
包名会被注册在package.json的dependencies里面,在生产环境下这个包的依赖依然存在。
-D 即--dev(生产)
包名会被注册在package.json的devDependencies里面,仅在开发环境下存在的包用-D,如babel、sass-loader这些解析器
1. devDependencies中的插件只用于开发环境,不用于生产环境,而dependencies是需要发布到生产环境的。像gulp、babel、webpack这些压缩代码、打包的工具,在实际运行中不需要,所以用-D
2.elementui、echarts这些插件在实际运行中也是需要的,所以用-S。
4.10.3.1、Jest
Jest是 Facebook 的一套开源的 JavaScript 测试框架, 它自动集成了断言、JSDom、覆盖率报告等开发者所需要的所有测试工具,是一款几乎零配置的测试框架。并且它对同样是 Facebook 的开源前端框架 React 的测试十分友好。
https://github.com/jestjs/jest
https://jest.nodejs.cn/
从 github starts & issues 以及 npm 下载量角度来看,Jest 的关注度更高、社区更活跃
| 框架 | 断言 | 异步 | 代码覆盖率 |
| Mocha |
不支持(需要其他库支持) |
友好 |
不支持(需要其他库支持) |
| Jest |
默认支持 |
友好 |
支持 |
1. Mocha 生态好,但是需要较多的配置来实现高扩展性
2. Jest 开箱即用
无论是受欢迎度和写法上,Jest 都有很大的优势,因此推荐你使用开箱即用的 Jest
4.10.4、peerDependencies
有时,你的项目和所依赖的模块,都会同时依赖另一个模块,但是所依赖的版本不一样。比如,你的项目依赖A模块和B模块的1.0版,而A模块本身又依赖B模块的2.0版。
大多数情况下,这不构成问题,B模块的两个版本可以并存,同时运行。但是,有一种情况,会出现问题,就是这种依赖关系将暴露给用户。
最典型的场景就是插件,比如A模块是B模块的插件。用户安装的B模块是1.0版本,但是A插件只能和2.0版本的B模块一起使用。这时,用户要是将1.0版本的B的实例传给A,就会出现问题。因此,需要一种机制,在模板安装的时候提醒用户,如果A和B一起安装,那么B必须是2.0模块。
peerDependencies字段,就是用来供插件指定其所需要的主工具的版本。
{
"name": "chai-as-promised",
"peerDependencies": {
"chai": "1.x"
}
}
上面代码指定,安装chai-as-promised模块时,主程序chai必须一起安装,而且chai的版本必须是1.x。如果你的项目指定的依赖是chai的2.0版本,就会报错。
注意,从npm 3.0版开始,peerDependencies不再会默认安装了。
4.10.5、bin字段
bin项用来指定各个内部命令对应的可执行文件的位置。
"bin": {
"someTool": "./bin/someTool.js"
}
上面代码指定,someTool 命令对应的可执行文件为 bin 子目录下的 someTool.js。Npm会寻找这个文件,在node_modules/.bin/目录下建立符号链接。在上面的例子中,someTool.js会建立符号链接npm_modules/.bin/someTool。由于node_modules/.bin/目录会在运行时加入系统的PATH变量,因此在运行npm时,就可以不带路径,直接通过命令来调用这些脚本。
因此,像下面这样的写法可以采用简写。
scripts: {
start: './node_modules/someTool/someTool.js build'
}
// 简写为
scripts: {
start: 'someTool build'
}
所有node_modules/.bin/目录下的命令,都可以用npm run [命令]的格式运行。在命令行下,键入npm run,然后按tab键,就会显示所有可以使用的命令。
4.10.6、main字段
main字段指定了加载的入口文件,require('moduleName')就会加载这个文件。这个字段的默认值是模块根目录下面的index.js。
4.10.7、config 字段
config字段用于添加命令行的环境变量。
下面是一个package.json文件。
{
"name" : "foo",
"config" : { "port" : "8080" },
"scripts" : { "start" : "node server.js" }
}
然后,在server.js脚本就可以引用config字段的值。
http
.createServer(...)
.listen(process.env.npm_package_config_port)
用户执行npm run start命令时,这个脚本就可以得到值。
用户可以改变这个值。
$ npm config set foo:port 80
特别注意:直接运行单个文件时是获取不到这个值的,因为没有以项目的形式运行。
4.10.8、browser字段
browser指定该模板供浏览器使用的版本。Browserify这样的浏览器打包工具,通过它就知道该打包那个文件。
"browser": {
"tipso": "./node_modules/tipso/src/tipso.js"
},
4.10.9、engines 字段
engines字段指明了该模块运行的平台,比如 Node 的某个版本或者浏览器。
{ "engines" : { "node" : ">=0.10.3 <0.12" } }
该字段也可以指定适用的npm版本。
{ "engines" : { "npm" : "~1.0.20" } }
4.10.10、man字段
man用来指定当前模块的man文档的位置。
"man" :[ "./doc/calc.1" ]
4.10.11、preferGlobal字段
preferGlobal的值是布尔值,表示当用户不将该模块安装为全局模块时(即不用–global参数),要不要显示警告,表示该模块的本意就是安装为全局模块。
4.10. 12、style字段
style指定供浏览器使用时,样式文件所在的位置。样式文件打包工具parcelify,通过它知道样式文件的打包位置。
"style": [
"./node_modules/tipso/src/tipso.css"
]
4.11、gnvm-node.js多版本管理器
在多个项目同时开发时,由于项目时间不同,我们会遇到不同项目所支持的node.js版本不一致的情况,导致运行项目时产生冲突。那么怎样可以使我们的node.js版本灵活支持我们所运行的项目呢?使用gnvm,Windows 下的 Node.js 多版本管理器,类似 nvm、nvmw、nodist。
安装地址:32-bit | 64-bit
(1)、特点:
下载即用,无需配置。
彩色日志输出。
支持多线程下载。
内置 TAOBAO,方便切换,也支持自定义 。
支持 NPM 下载/安装/配置。
(2)、安装gnvm
1、用管理员权限启动cmd;
并确保node是空闲的(将使用中的node关闭)
(3)、安装gnvm:
gnvm下载地址:
将gnvm.exe 文件放在Node.js 所在的文件夹,
文件夹路默认安装路径为:C:\Program Files\nodejs,如果不知道node的安装路径
可查看node安装的位置:where node
验证gnvm是否可用:
使用指令 gnvm version
这时候就可以使用gnvm指令管理nodejs版本了
(4)、gnvm相关指令
1、安装多个 node 版本
gnvm search *.*.* //查询所有版本
gnvm install latest 1.0.0-x86 1.0.0-x64 5.0.0 // 安装
gnvm install 10.0.0 // 安装指定版本,也可以指定安装32位或64位,eg: gnvm install 10.0.0-x64
gnvm update latest // 更新本地 latest 的 node 版本
2、卸载任意版本的 node
gnvm uninstall latest // 卸载最新版本的 node
gnvm uninstall 10.0.0 // 卸载指定版本
3、查看本地所有安装的 node 版本
gnvm ls
4、切换任意版本的 node
gnvm use 10.0.0
5、安装 npm
gnvm npm latest
6、安装淘宝镜像
gnvm config registry TAOBAO
4.12、package-lock.json
package-lock.json 是一个 npm 项目中的文件,用于锁定项目的依赖版本。它记录了当前项目下各个包的精确版本号,以及其依赖树的信息。它的作用是确保每个团队成员在安装项目依赖时,所有依赖的版本都是一致的,以避免出现依赖版本冲突的问题。
package-lock.json 文件由 npm 自动创建和更新,一般情况下不需要手动修改。当执行 npm install 命令时,npm 会根据 package.json 文件中的依赖信息下载对应的包,并自动更新或创建 package-lock.json 文件。在执行 npm install 命令时,npm 会根据 package-lock.json 文件中的记录,锁定每个包的版本,确保每次安装的依赖版本一致。
4.13、pnpm
pnpm是一个快速的,节省磁盘空间的包管理工具。
1、快速
pnpm比其他包管理器快2倍。
2、高效
node_modules 中的文件为复制或链接自特定的内容寻址存储库。
3、支持monorepos
pnpm内置支持单仓多包。
4、严格
pnpm 默认创建了一个非平铺的 node_modules,因此代码无法访问任意包。
- 不会重复安装同一个包。使用
npm/yarn 的时候,如果100个包依赖lodash ,那么就可能安装了100次lodash ,磁盘中就有100个地方写入了这部分代码。但是pnpm会只在一个地方写入这部分代码,后面使用会直接使用hard link
- 即使一个包的不同版本,pnpm 也会极大程度地复用之前版本的代码。举个例子,比如 lodash 有 100 个文件,更新版本之后多了一个文件,那么磁盘当中并不会重新写入 101 个文件,而是保留原来的 100 个文件的
hardlink,仅仅写入那一个新增的文件。
https://github.com/pnpm/pnpm
https://pnpm.io/
安装:
npm i pnpm -g
配置:
pnpm config set store-dir d:\pnpm
| npm命令 | pnpm等价命令 |
| npm install |
pnpm install |
| npm install 包名 |
pnpm add 包名 |
| npm uninstall 包名 |
pnpm remove 包名 |
| npm run 脚本 |
pnpm 脚本 |
使用pnpm安装依赖包时报错:EPERM: operation not permitted
设置了pnpm-store 后问题解决
pnpm config set store-dir /home/root/.pnpm-store
五、示例下载
git:https://coding.net/u/zhangguo5/p/NodeJS001/git
git:https://coding.net/u/zhangguo5/p/NodeJSExpress/git
六、作业
6.1、请安装好node.js环境,测试版本,在控制台写一个方法用于计算1-100间的所有能被3整除的数,并调用。
6.2、重现上课的每一个示例内容,可以对照视频进行。
6.3、使用node.js完成一个web服务器,输出Hello Node.js!到客户端浏览器,要求内网穿透,手机端与其它同学的电脑可以访问。
6.4、使用md5,sha256循环10次加密你姓名的拼音,尝试破解。
6.5、使用lodash找出任意5个方法,调用方法,不能与官网的示例一样。
6.6、使用gnvm切换不同的node.js版本。
七、视频
https://www.bilibili.com/video/av17977069/