转自:http://segmentfault.com/a/1190000000728401javascript
Node.js 提供了exports
和 require
两个对象,其中 exports
是模块公开的接口,require
用于从外部获取一个模块的接口,即所获取模块的 exports
对象。
接下来咱们就来建立hello.js
文件,代码以下:html
exports.world = function() { console.log('Hello World'); }
在以上示例中,hello.js
经过 exports
对象把 world
做为模块的访问接口,在 main.js
中经过 require('./hello')
加载这个模块,而后就能够直接访 问main.js
中 exports
对象的成员函数了。前端
require
方法接受如下几种参数的传递:java
http、fs、path等,原生模块。 ./mod或../mod,相对路径的文件模块。 /pathtomodule/mod,绝对路径的文件模块。 mod,非原生模块的文件模块。
咱们以计算圆的周长和面积的两个方法为例:node
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
调用模块:mysql
var circle = require("./circle.js");//require经过引入模块文件,找到exports对象提供的接口 console.log("The area of a circle of radius 4 is " + circle.area(4));
编写稍大一点的程序时通常都会将代码模块化。在NodeJS
中,通常将代码合理拆分到不一样的JS文件中,每个文件就是一个模块,而文件路径就是模块名。nginx
在编写每一个模块时,都有require、exports、module
三个预先定义好的变量可供使用。
模块名可以使用相对路径(以./
开头),或者是绝对路径(以/或C:
之类的盘符开头)。另外,模块名中的.js
扩展名能够省略。git
a>优势: 可维护性 1.灵活架构,焦点分离 2.方便模块间组合、分解 3.方便单个模块功能调试、升级 4.多人协做互不干扰 可测试性 1.可分单元测试 b>缺点: 性能损耗 1.系统分层,调用链会很长 2.模块间通讯,模块间发送消息会很耗性能
包管理 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
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。github
socket.io
一个是基于Nodejs架构体系的,支持websocket
的协议用于时时通讯的一个软件包。socket.io
给跨浏览器构建实时应用提供了完整的封装,socket.io
彻底由javascript
实现。web
cheerio
是一个为服务器特别定制的,快速、灵活、封装jQuery核心功能工具包。Cheerio包括了 jQuery核心的子集,从jQuery库中去除了全部DOM不一致性和浏览器不兼容的部分,揭示了它真正优雅的API。Cheerio工做在一个很是简 单,一致的DOM模型之上,解析、操做、渲染都变得难以置信的高效。基础的端到端的基准测试显示Cheerio大约比JSDOM快八倍(8x)。 Cheerio封装了@FB55兼容的htmlparser,几乎可以解析任何的 HTML 和 XML document。
Hexo
是一个简单地、轻量地、基于Node
的一个静态博客框架。经过Hexo
咱们能够快速建立本身的博客,仅须要几条命令就能够完成。
发布时,Hexo
能够部署在本身的Node
服务器上面,也能够部署github
上面。对于我的用户来讲,部署在github
上好处颇多,不只能够省 去服务器的成本,还能够减小各类系统运维的麻烦事(系统管理、备份、网络)。因此,基于github
的我的站点,正在开始流行起来….
Bower 是 twitter
推出的一款包管理工具,基于nodejs
的模块化思想,把功能分散到各个模块中,让模块和模块之间存在联系,经过 Bower 来管理模块间的这种联系。
javascript
语言的执行环境是"单线程"(single thread)。
所谓"单线程",就是指一次只能完成一件任务。若是有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。
这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无 响应(假死),每每就是由于某一段Javascript
代码长时间运行(好比死循环),致使整个页面卡在这个地方,其余任务没法执行。
大部分 Web 应用的瓶颈都在 I/O
, 即读写磁盘,读写网络,读写数据库。使用怎样的策略等待这段时间,就成了改善性能的关键点
为了解决这个问题,Javascript
语言将任务的执行模式分红两种:同步(Synchronous)和异步(Asynchronous)。
"同步模式"就是上一段的模式,后一个任务等待前一个任务结束,而后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的;"异步模式"则彻底不一样, 每个任务有一个或多个回调函数(callback
),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执 行,因此程序的执行顺序与任务的排列顺序是不一致的、异步的。
"异步模式"很是重要。在浏览器端,耗时很长的操做都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操做。在服务器端,"异步模式"甚至是惟一的模式,由于执行环境是单线程的,若是容许同步执行全部http
请求,服务器性能会急剧降低,很快就会失去响应。
mac系统中的进程与线程
从图中咱们能够看出,一个进程能够包括多个线程,进程就比如工程里的车间,线程就是这个车间的工人,在引入线程的操做系统中,一般都是把进程做为分配资源的基本单位,而把线程做为独立运行和独立调度的基本单位。因为线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提升系统内多个程序间并发执行的程度。
线程和进程的区别在于,子进程和父进程有不一样的代码和数据空间,而多个线程则共享数据空间,每一个线程有本身的执行堆栈和程序计数器为其执行上下文。多线程主要是为了节约CPU时间,发挥利用,根据具体状况而定。线程的运行中须要使用计算机的内存资源和CPU。
模块:一个实现某些特定功能的文件,以实现模块化编程。经过require(模块名)引入模块.
—模块中的功能(如:变量,函数)经过赋给exports
对象的某个属性提供给调用者使用。
模块是可重用的代码库。好比用来与数据库交互的模块、支持web开发的模块以及经过web套接字协助通讯的模块
在Node中使用模块是很是方便的,在 JavaScript
代码中能够直接使用全局函数 require()
来加载一个模块。例如,咱们可使用require("http")
来加载node
中自带的http服务器模块,
包是一个文件夹,它将模块封装起来,用于发布、更新、依赖管理和版本控制。经过package.json
来描述包的信息:入口文件,依赖的外部包等等。经过npm install
命令来安装包,并经过require
使用包。
在开发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>更新
name - 包的名称
version - 包的版本
description - 包的描述
homepage - 包主页
author - 包的做者
contributors - 贡献者到包的名字
dependencies - 依赖关系的列表。NPM自动安装全部在这里的包node_module文件夹中提到的依赖关系。
repository - 包的库类型和URL
main - 包的入口点
keywords - 关键字
npm install module-name -save 自动把模块和版本号添加到dependencies部分 npm install module-name -save-dve 自动把模块和版本号添加到devdependencies部分
Node.js
的异步机制是基于事件的,I/O
是输入输出的意思,指的是计算机和人或者数据处理系统之间的通讯。能够将I/O
想成是数据在一次输入和一次输出之间的移动。
每个 I/O
就是一次请求,全部的磁盘 I/O
、网络通讯、数据库查询都以非阻塞的方式请求,返回的结果由事件循环来处理。以下图所示:
Node.js
进程在同一时刻只会处理一个事件,完成后当即进入事件循环检查并处理后面的事件。这样作的好处是,CPU 和内存在同一时间集中处理一件事,同时尽量让耗时的 I/O 操做并行执行
在这里,我推荐你们使用webstorm
进行node.js
的开发,方便又快捷,比起cmd,或者Mac下的终端都好用太多了。
至于node的安装你们就自行百度吧,这里就不赘述了,看下webstorm
下的node编程界面吧:
咱们只须要在编写好的node代码界面按鼠标右键,而后点击Run就行啦,方便又快捷吧
下面是node的输出界面:
在Mac
系统下进行web开发,我推荐你们使用的三款工具是:coda2这些是目前我已经的最好的开发工具了,你们不妨试试哪一个更符合本身的口味。
在webstorm
进行node开发须要先配置必定的文件,你们就自行百度吧,由于个人webstorm
已经配置好了,因此无法截图给你们看步骤了,大概步骤是,在mac系统下是先点击顶部栏的webstorm
,而后点击perference
,而后点击Node.js and NPM
,而后在右侧点击configure配置,最后大概会是下面这个样子:
windows
系统下和这个流程步骤大概类似啊,我使用的版本是8.0.4的。
在js编程中,咱们最好给每一个变量都添加上var关键字,以避免污染全局命名空间,提升代码的耦合风险。
console
用于向标准输出流standout
(stdout)和标准错误流(stderr)输出字符。
console.log()
向标准输出流打印字符并以换行符结束,其接受多个参数,将以相似C语言的printf()
格式输出
console.log(__dirname)输出文件目录
计算代码运行时间
console.time(label) console.timeEnd(label)
咱们只需在开始和结束那里给一样一个标签便可,中间放你想要计算执行时间的任何代码。
__filename
和__dirname
console.log(__filename);// /Users/hwax/Desktop/My Project/avalon/hello.js console.log(__dirname);// /Users/hwax/Desktop/My Project/avalon __filename:开发期间,该行代码所在的文件。 __dirname:开发期间,该行代码所在的目录。
合并参数获得一个标准化的路径字符串
path.join('/foo', 'bar', 'baz/abc') // returns '/foo/bar/baz/abc'
首先在终端输入:
trigkit4:~ trigkit4$ vi index.js
进入vim
后输入i
,进入编辑模式,而后输入:
var http = require('http'); http.createServer(function(req,res){ res.writeHead(200,{'Content-Type':'text/plain'}); res.end("Hello World\n"); }).listen(8124,"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
的包的根目录结构以下:
.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