简介
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。
Node.js 的包管理器 npm,是全球最大的开源库生态系统。
私下了解:
Everything runs in parallel except your code!
JS是脚本语言,脚本语言都需要一个解析器才能运行。对于写在HTML页面里的JS,浏览器充当了解析器的角色。而对于需要独立运行的JS,NodeJS就是一个解析器。
每一种解析器都是一个运行环境,不但允许JS定义各种数据结构,进行各种计算,还允许JS使用运行环境提供的内置对象和方法做一些事情。例如运行在浏览器中的JS的用途是操作DOM,浏览器就提供了document之类的内置对象。而运行在NodeJS中的JS的用途是操作磁盘文件或搭建HTTP服务器,NodeJS就相应提供了fs、http等内置对象。
NodeJS的作者(Ryan Dahl)说,他创造NodeJS的目的是为了实现高性能Web服务器,他首先看重的是事件机制和异步IO模型的优越性,而不是JS。但是他需要选择一种编程语言实现他的想法,这种编程语言不能自带IO功能,并且需要能良好支持事件机制。JS没有自带IO功能,天生就用于处理浏览器中的DOM事件,并且拥有一大群程序员,因此就成为了天然的选择。
对于前端而言,虽然不是人人都要拿NodeJS写一个服务器程序,但简单可至使用命令交互模式调试JS代码片段,复杂可至编写工具提升工作效率。NodeJS生态圈正欣欣向荣
基于我们在用windows 和 mac ,所以介绍这两种操作系统的安装配置。
下载 Windows Installer (.msi)
homebrew
js brew install node
下载包
macOS Installer (.pkg)
大量开发者的贡献使Node版本的迭代速度很快,版本很多,所以升级Node版本就成为了一个问题。目前有n和nvm这两个工具可以对Node进行无痛升级,本文简单介绍一下二者的使用
n是Node的一个模块,作者是TJ Holowaychuk(鼎鼎大名的Express框架作者),就像它的名字一样,它的理念就是简单
no subshells, no profile setup, no convoluted api, just simple
npm install -g n//npm ERR! notsup Unsupported platform for n@2.1.8: wanted {“os”:”!win32”,”arch”:” any”} (current: {“os”:”win32”,”arch”:”x64”})npm install -g n --force
//查看已安装的版本
n//查看最新版本
n --latest// 安装最新的版本并使用
n latest (-d) // -d表示仅下载不使用//查看最稳定的版本
n --stable//安装最新稳定的版本并使用
n stable//安装某个版本并使用
n <version> //n 6.2.2//删除某些版本
n rm <version>//查看可用版本
n ls//查看帮助信息
n -h//以制定的版本来执行脚本
n use <version> some.js
既然有这么简单好用的n,那么nvm为什么还会大肆流行呢?
nvm全称Node Version Manager,不同于 n,nvm 不是一个 npm package,而是一个独立软件包. 它与n的实现方式不同,其是通过shell脚本实现的.
安装方式:
//curl
curl https://raw.github.com/creationix/nvm/v0.4.0/install.sh | sh//wget
wget -qO- https://raw.github.com/creationix/nvm/v0.4.0/install.sh | sh
以上脚本会把 nvm
库clone到 ~/.nvm
,然后会在 ~/.bash_profile
, ~/.zshrc
或~/.profile
末尾添加source
,安装完成之后,你可以用以下命令来安装node
nvm 不支持windows
nvm-windows 适用于windows
//安装指定的版本
nvm install 0.10//使用指定的版本
nvm use 0.10//查看当前已经安装的版本
nvm ls//查看正在使用的版本
nvm current//以指定版本执行脚本
nvm run 0.10.24 some.js//卸载nvm
rm -rf ~/.nvm
n
vs nvm
NPM 是随同Nodejs 一起安装的包管理工具,能解决Nodejsd代码部署上的很多问题.
用法:
新版的nodejs已经集成了npm,所以npm一并安装好了,可以用
npm -v
来检测是否安装成功。
npm install 安装模块
npm uninstall 卸载模块
npm update 更新模块
npm outdated 检查模块是否已经过时
npm ls 查看安装的模块
npm init 在项目中引导创建一个package.json文件
npm help 查看某条命令的详细帮助
npm root 查看包的安装路径
npm config 管理npm的配置路径
npm cache 管理模块的缓存
npm start 启动模块
npm stop 停止模块
npm restart 重新启动模块
npm test 测试模块
npm version 查看模块版本
npm view 查看模块的注册信息
npm adduser 用户登录
npm publish 发布模块
npm access 在发布的包上设置访问级别
npm package.json的语法
具体文档参考:
https://github.com/yulongge/Vampire/blob/master/blog/npm_command.md
这是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步
你可以使用我们定制的 cnpm (gzip 压缩支持) 命令行工具代替默认的 npm:
npm install -g cnpm --registry=https://registry.npm.taobao.org
这样就可以使用 cnpm 命令来安装模块了 js cnpm install [name]
每个项目的根目录下面,一般都有一个package.json文件,定义了这个项目所需要的各个模块,已经项目的配置信息,npm install
命令根据这个配置文件,自动下载所需的模块,也就是配置项目所需的运行和开发环境
package.json 文件就是一个json文件,该对象的每一个成员就是当前项目的一项设置。
package.json 文件可以手工编写,也可以使用npm init
命令自动生成。
npm init
package.json中各个属性的意义:
https://github.com/yulongge/Vampire/blob/master/blog/package.json.md
管理依赖是一个复杂的软件开发过程中必会遇到的问题。
在Node.js项目开发的时候,我们也经常需要安装和升级对应的依赖。虽然 npm 以及语意化的版本号 (semantic versioning, semver) 让开发过程中依赖的获取和升级变得非常容易, 但不严格的版本号限制,也带来了版本号的不确定性.
npm shrinkwrap 可以按照当前项目 node_modules 目录内的安装包情况生成稳定的版本号描述
//A
{
"name": "A",
"version": "0.1.0",
"dependencies": {
"B": "<0.1.0"
}
}//B{
"name": "B",
"version": "0.0.1",
"dependencies": {
"C": "<0.1.0"
}
}//C
{
"name": "C",
"version": "0.0.1"
}
你的项目只依赖于A,于是npm install会得到这样的目录结构。
A@0.1.0
`-- B@0.0.1
`-- C@0.0.1
如果这时候B发布了新版本,你再执行npm install的时候。
A@0.1.0
`-- B@0.0.2
`-- C@0.0.1
所以我们需要锁定版本,保证所在的环境下安装得到稳定的结果。
我们需要手动的执行npm shrinkwrap
可以在项目中得到一个npm-shrinkwarp.json文件
{
"name": "A",
"version": "0.1.0",
"dependencies": {
"B": {
"version": "0.0.1",
"dependencies": {
"C": {
"version": "0.0.1"
}
}
}
}
}
shrinkwarp命令会根据目前安装在node_modules的文件情况锁定依赖版本,在项目中执行npm install
的时候,npm 会检查在根目录下有没有npm-shrinkwrap.json
文件,如果有,则使用它来确定安装各个包的版本号信息。
Node REPL(Read Eval Print Loop:读取-求值-输出-循环):交互式解析器
在终端输入node,就会进入REPL
node
>
官网的文档很全,不需要多说什么
http://nodejs.cn/api/
JavaScript 中有一个特殊的对象,称为全局对象(Global Object),它及其所有的属性都可以在程序的任何地方访问,即全局变量。
所有的全局变量都是global对象的属性,global最根本的作用是作为全局变量的宿主。
在node.js中不会有全局变量,因为用户代码都是属于当前模块的。。
Node.js采用模块化结构,按照CommonJs规范定义和使用模块。模块与文件是一一对应关系,即加载一个模块,实际上就是加载对应的一个模块文件。
requre命令用于指定加载模块,加载时可以省略脚本文件的后缀名。
var server = require('./server.js');
//或
var server1 = require('./server');
require 方法参数:
var bar = require('bar');
有时候,一个模块本身就是一个目录,目录中包含多个文件,这时候,Node在package.json文件中,寻找main属性所指明的模块入口文件。
{
"name": "bar",
"main": "./lib/bar.js"
}
//等同于
var bar = rquire('bar/lib/bar.js');
如果模块目录中没有package.json文件,node.js会尝试在模块目录中找index.js,或index.node文件进行加载。
模块一旦被加载以后,就会被系统缓存。如果第二次加载该模块,则会返回缓存中的版本,这意味着模块实际上只会执行一次。如果希望模块执行多次,则可以让模块返回一个函数,然后多次调用。
如果只是在服务器运行JavaScript代码,用处并不大,因为服务器脚本语言已经有很多种,Node.js的用处在于,它本身还提供了一系列功能模块,与操作系统互动。这些核心的功能模块,不用安装就可以使用。
核心模块都在Node的lib子目录中,为了提高运行速度,他们安装时都会被编译成二进制文件,核心模块总是最优先加载的,如果你自己写了一个HTTP模块,require('http')加载的还是核心模块。
不了解网络编程的程序员不是好前端,而NodeJS恰好提供了一扇了解网络编程的窗口。通过NodeJS,除了可以编写一些服务端程序来协助前端开发和测试外,还能够学习一些HTTP协议与Socket协议的相关知识,这些知识在优化前端性能和排查前端故障时说不定能派上用场。 - http - https
var http = require('http');http.createServer(function (request, response) {
response.writeHead(200, { 'Content-Type': 'text-plain' });
response.end('Hello World\n');
}).listen(8080);
var express = require('express');
var app = express();app.get('/', function (req, res) {
res.send('Hello World');
})var server = app.listen(8081, function () { ...})
让前端觉得如获神器的不是NodeJS能做网络编程,而是NodeJS能够操作文件。小至文件查找,大至代码编译,几乎没有一个前端工具不操作文件。换个角度讲,几乎也只需要一些数据处理逻辑,再加上一些文件操作,就能够编写出大多数前端工具。
fs.open(path, flags[, mode], callback) //打开文件
fs.stat(path, callback) //获取文件信息
fs.writeFile(file, data[, options], callback) //写入文件
fs.read(fd, buffer, offset, length, position, callback) //写入文件
fs.close(fd, callback) //关闭文件
var fs = require("fs");// 异步读取
fs.readFile('input.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log("异步读取: " + data.toString());
});// 同步读取
var data = fs.readFileSync('input.txt');
console.log("同步读取: " + data.toString());console.log("程序执行完毕。");
在 Node.js 模块库中有很多好用的模块。接下来我们为大家介绍几种常用模块的使用。