宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取

模块

Node.js 提供了exports 和 require 两个对象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口,即所获取模块的 exports 对象。
接下来我们就来创建hello.js文件,代码如下:

exports.world = function) {console.log'Hello World');
}

在以上示例中,hello.js 通过 exports 对象把 world 作为模块的访问接口,在 main.js 中通过 require'./hello') 加载这个模块,然后就可以直接访 问main.js 中 exports 对象的成员函数了。

require方法接受以下几种参数的传递:

http、fs、path等,原生模块。
./mod或../mod,相对路径的文件模块。
/pathtomodule/mod,绝对路径的文件模块。
mod,非原生模块的文件模块。

我们以计算圆的周长和面积的两个方法为例:

var PI = Math.PI;
exports.area = function r) {return PI*r*r;
};//exports 是对象,向外提供了area方法接口exports.circumference = function r) {return 2*PI*r;
};

以上保存为circle.js,下方通过require调用模块:

var circle = require"./circle.js");//require通过引入模块文件,找到exports对象提供的接口
console.log"The area of a circle of radius 4 is " + circle.area4));

编写稍大一点的程序时一般都会将代码模块化。在NodeJS中,一般将代码合理拆分到不同的JS文件中,每一个文件就是一个模块,而文件路径就是模块名。

在编写每个模块时,都有require、exports、module三个预先定义好的变量可供使用。
模块名可使用相对路径(以./开头),或者是绝对路径(以/或C:之类的盘符开头)。另外,模块名中的.js扩展名可以省略。

模块化的优缺点:

a>优点:
可维护性
1.灵活架构,焦点分离
2.方便模块间组合、分解
3.方便单个模块功能调试、升级
4.多人协作互不干扰
可测试性
1.可分单元测试b>缺点:
性能损耗
1.系统分层,调用链会很长
2.模块间通信,模块间发送消息会很耗性能

Node.js常用模块和组件

 包管理 Package Management: NPM 框架 Framework: ExpressJS 模板 Template: Jade 中间件 Middleware: Connect WebSocket: Socket.io 数据库 Database: Mongo DB 选了个自己喜欢的) Mongoose as a MongoDB ORM) 调错 Debugging: Node Inspector 测试 Test: Mocha + should.js 控制无止境的内嵌回调 Control the Callback flow): Async

Node.js可以做什么?

Web开发:Express + EJS + Mongoose/MySQL

express 是轻量灵活的Nodejs Web应用框架,它可以快速地搭建网站。
Express框架建立在Nodejs内置的Http模块上,并对Http模块再包装,从而实际Web请求处理的功能。ejs是一个嵌入的Javascript模板引擎,通过编译生成HTML的代码。mongoose 是MongoDB的对象模型工具,通过Mongoose框架,可以进行访问MongoDB的操作。mysql 是连接MySQL数据库的通信API,可以进行访问MySQL的操作。

通常用Node.js做Web开发,需要3个框架配合使用,就像Java中的SSH。

Web聊天室IM):Express + Socket.io

socket.io一个是基于Nodejs架构体系的,支持websocket的协议用于时时通信的一个软件包。socket.io 给跨浏览器构建实时应用提供了完整的封装,socket.io完全由javascript实现。

Node.js知识点详解(一)基础部分-风君子博客

Web爬虫:Cheerio/Request

cheerio 是一个为服务器特别定制的,快速、灵活、封装jQuery核心功能工具包。Cheerio包括了 jQuery核心的子集,从jQuery库中去除了所有DOM不一致性和浏览器不兼容的部分,揭示了它真正优雅的API。Cheerio工作在一个非常简 单,一致的DOM模型之上,解析、操作、渲染都变得难以置信的高效。基础的端到端的基准测试显示Cheerio大约比JSDOM快八倍8x)。 Cheerio封装了@FB55兼容的htmlparser,几乎能够解析任何的 HTML 和 XML document。

Web博客:Hexo

Hexo 是一个简单地、轻量地、基于Node的一个静态博客框架。通过Hexo我们可以快速创建自己的博客,仅需要几条命令就可以完成。

发布时,Hexo可以部署在自己的Node服务器上面,也可以部署github上面。对于个人用户来说,部署在github上好处颇多,不仅可以省 去服务器的成本,还可以减少各种系统运维的麻烦事系统管理、备份、网络)。所以,基于github的个人站点,正在开始流行起来….

前端包管理平台: bower.js

Bower 是 twitter 推出的一款包管理工具,基于nodejs的模块化思想,把功能分散到各个模块中,让模块和模块之间存在联系,通过 Bower 来管理模块间的这种联系。

单线程

javascript语言的执行环境是"单线程"(single thread)。
所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。

这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无 响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。

大部分 Web 应用的瓶颈都在 I/O, 即读写磁盘,读写网络,读写数据库。使用怎样的策略等待这段时间,就成了改善性能的关键点

同步与异步

为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。

"同步模式"就是上一段的模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的;"异步模式"则完全不同, 每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执 行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

"异步模式"非常重要。在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,"异步模式"甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。

进程与线程

mac系统中的进程与线程

Node.js知识点详解(一)基础部分-风君子博客

从图中我们可以看出,一个进程可以包括多个线程,进程就好比工程里的车间,线程就是这个车间的工人,在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度。

区别

线程和进程的区别在于,子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈和程序计数器为其执行上下文。多线程主要是为了节约CPU时间,发挥利用,根据具体情况而定。线程的运行中需要使用计算机的内存资源和CPU。

Node.js知识点详解(一)基础部分-风君子博客

模块和包

模块

模块:一个实现某些特定功能的文件,以实现模块化编程。通过require(模块名)引入模块.
—模块中的功能(如:变量,函数)通过赋给exports对象的某个属性提供给调用者使用。

模块是可重用的代码库。比如用来与数据库交互的模块、支持web开发的模块以及通过web套接字协助通信的模块

如何使用模块?

在Node中使用模块是非常方便的,在 JavaScript 代码中可以直接使用全局函数 require) 来加载一个模块。例如,我们可以使用require"http")来加载node中自带的http服务器模块,

包是一个文件夹,它将模块封装起来,用于发布、更新、依赖管理和版本控制。通过package.json来描述包的信息:入口文件,依赖的外部包等等。通过npm install命令来安装包,并通过require使用包。

package.json

在开发Node.js应用程序的时候,一个一个模块的安装显然很耗时,又或是忘了安装某个模块怎么办?npm允许开发人员使用package.json文件来指定在应用程序中要用的模块,并且通过单个命令来安装它们:

npm install

package.json文件仅包含以特定格式表示的项目信息。一个最小的package.json文件会是这样:

{"name" : "example 1","version": "0.0.2","dependencies":{"underscore":"~1.2.1"}
}

使用package.json文件意味着我们无需记忆应用程序会依赖于哪些模块,其他开发人员会发现,可以很简单地安装你的应用程序

npm install <name>安装nodejs的依赖包
npm install <name> -g  将包安装到全局环境中
npm install <name> --save  安装的同时,将信息写入package.json中
npm init  会引导你创建一个package.json文件,包括名称、版本、作者这些信息等
npm remove <name>移除
npm update <name>更新 

Package.json的属性

name - 包的名称version - 包的版本description - 包的描述homepage - 包主页author - 包的作者contributors - 贡献者到包的名字dependencies - 依赖关系的列表。NPM自动安装所有在这里的包node_module文件夹中提到的依赖关系。repository - 包的库类型和URLmain - 包的入口点keywords - 关键字npm install module-name -save 自动把模块和版本号添加到dependencies部分
npm install module-name -save-dve 自动把模块和版本号添加到devdependencies部分

异步式 I/O 与事件驱动

Node.js 的异步机制是基于事件的,I/O 是输入输出的意思,指的是计算机和人或者数据处理系统之间的通信。可以将I/O 想成是数据在一次输入和一次输出之间的移动。

每一个 I/O就是一次请求,所有的磁盘 I/O、网络通信、数据库查询都以非阻塞的方式请求,返回的结果由事件循环来处理。如下图所示:

Node.js知识点详解(一)基础部分-风君子博客

Node.js 进程在同一时刻只会处理一个事件,完成后立即进入事件循环检查并处理后面的事件。这样做的好处是,CPU 和内存在同一时间集中处理一件事,同时尽可能让耗时的 I/O 操作并行执行

Node.js知识点详解(一)基础部分-风君子博客

开始node编程

在这里,我推荐大家使用webstorm进行node.js的开发,方便又快捷,比起cmd,或者Mac下的终端都好用太多了。

至于node的安装大家就自行百度吧,这里就不赘述了,看下webstorm下的node编程界面吧:
我们只需要在编写好的node代码界面按鼠标右键,然后点击Run就行啦,方便又快捷吧

Node.js知识点详解(一)基础部分-风君子博客

下面是node的输出界面:

Node.js知识点详解(一)基础部分-风君子博客

Mac系统下进行web开发,我推荐大家使用的三款工具是:coda2这些是目前我已经的最好的开发工具了,大家不妨试试哪个更符合自己的口味。

webstorm进行node开发需要先配置一定的文件,大家就自行百度吧,因为我的webstorm已经配置好了,所以没法截图给大家看步骤了,大概步骤是,在mac系统下是先点击顶部栏的webstorm,然后点击perference,然后点击Node.js and NPM,然后在右侧点击configure配置,最后大概会是下面这个样子:

Node.js知识点详解(一)基础部分-风君子博客

windows系统下和这个流程步骤大概相似啊,我使用的版本是8.0.4的。

全局变量

在js编程中,我们最好给每个变量都添加上var关键字,以免污染全局命名空间,提高代码的耦合风险。

console

console用于向标准输出流standout(stdout)和标准错误流stderr)输出字符。

console.log)向标准输出流打印字符并以换行符结束,其接受多个参数,将以类似C语言的printf()格式输出

Node.js知识点详解(一)基础部分-风君子博客

console.log__dirname)输出文件目录

计算代码运行时间

    console.timelabel)console.timeEndlabel)

Node.js知识点详解(一)基础部分-风君子博客

我们只需在开始和结束那里给同样一个标签即可,中间放你想要计算执行时间的任何代码。

__filename__dirname

    console.log__filename);// /Users/hwax/Desktop/My Project/avalon/hello.jsconsole.log__dirname);// /Users/hwax/Desktop/My Project/avalon__filename:开发期间,该行代码所在的文件。
__dirname:开发期间,该行代码所在的目录。

path.join[path1],[path2],[…])

合并参数得到一个标准化的路径字符串path.join'/foo', 'bar', 'baz/abc')
// returns
'/foo/bar/baz/abc'  

运行hello world程序

首先在终端输入:

trigkit4:~ trigkit4$ vi index.js

进入vim后输入i,进入编辑模式,然后输入:

var http = require'http');
http.createServerfunctionreq,res){res.writeHead200,{'Content-Type':'text/plain'});res.end"Hello World\n");
}).listen8124,"127.0.0.1");
console.log"Server running at http://127.0.0.1:8124/");

然后按ESC,退出编辑模式,输入:w保存,再输入:q退出

然后接着在终端输入如下命令:

trigkit4:~ trigkit4$ node index

可以看到终端输出了:

Server running at http://127.0.0.1:8124/

然后打开浏览器,输入地址即可看到输出hello world

Node.js包目录

一般一个Node.js的包的根目录结构如下:

 .gitignore —— 从git上忽略的文件清单.npmignore —— 不包括npm注册库中的文件清单LICENSE —— 包的授权文件README.md —— 以markdown格式编写的readme文件bin —— 保存包可执行文件的文件夹doc —— 保存包文档的文件夹examples —— 保存如何使用包的实例文件夹lib —— 保存包代码的文件夹man —— 保存包的手册页的文件夹package.json —— 描述包的json文件src —— 保存C/C++源文件的文件夹deps —— 保存包所用到的依赖文件夹test —— 保存模块测试的文件夹index.js —— 包的入口文件"scripts": {//“scripts”是一个由脚本命令组成的hash对象,他们在包不同的生命周期中被执行。key是生命周期事件,value是要运行的命令。"test": "node ./libuv/test.js"},
"main": "index.js",//包的入口文件,如不指定,则为根目录下的index.js