node起步(初级node教程-02)

我们在上一节中了解了什么是node以及简单的node安装和事件式编程。呵呵。。。今天内容是

什么是模块?

什么是包?

如果我写好包了怎么发布出去给别人用?

我写好js脚本后怎么找问题,(怎么调试问题)

怎么实现远程调试?

最后一个就是调试有没有其他的现成的工具可供我们使用

最厚的问题我就在这里答了吧,因为我也没用IDE调试的,在这里就不细说了,因为还得上传老多IDE的使用图片感觉挺麻烦就不再累赘的描述了,我就在这里简单的说下了

当然调试js的IDE也是有的比如eclipse添加chrome Developer插件  插件地址http://chromedevtools.googlecode.com/svn/update/dev/

我希望你带着这几个问题去看我这篇博客这样就很容易接受这里所讲的内容了

五.模块和包

Node.js 提供了 require 函数来调用其他模块,而且模块都是基于

文件的,机制十分简单。Node.js 的模块和包机制的实现参照了 CommonJS的标准,但并未完全遵循。

1什么是模块

模块是 Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个

Node.js 文件就是一个模块,这个文件可能是 JavaScript 代码、 JSON 或者编译过的 C/C++ 扩展。

在前面章节的例子中,我们曾经用到了 var http =require(‘http‘), 其中 http

是 Node.js 的一个核心模块,其内部是用 C++ 实现的,外部用 JavaScript封装。我们通过

require函数获取了这个模块,然后才能使用其中的对象。

 

2块创建及加载模块

让我们以一个例子来了解模块。创建一个 module.js 的文件,内容是:

//module.js
var name;
exports.setName = function(thyName) {
name = thyName;
};
exports.sayHello = function() {
console.log('Hello ' + name);
};
//在同一目录下创建 getmodule.js,内容是:
//getmodule.js
var myModule = require('./module');
myModule.setName('BYVoid');
myModule.sayHello()

单次加载

上面这个例子有点类似于创建一个对象,但实际上和对象又有本质的区别,因为

require不会重复加载模块,也就是说无论调用多少次 require, 获得的模块都是同一个。

我们在 getmodule.js 的基础上稍作修改:

//loadmodule.js
var hello1 = require('./module');
hello1.setName('BYVoid');
var hello2 = require('./module');
hello2.setName('BYVoid 2');
hello1.sayHello();

运行后发现输出结果是 Hello BYVoid 2,这是因为变量 hello1 和 hello2 指向的是

同一个实例,因此 hello1.setName 的结果被 hello2.setName 覆盖,最终输出结果是

由后者决定的。

覆盖exports

有时候我们只是想把一个对象封装到模块中,例如:

//singleobject.js
function Hello() {
var name;
this.setName = function (thyName) {
name = thyName;
};
this.sayHello = function() {
console.log('Hello ' + name);
};
};
exports.Hello = Hello;

此时我们在其他文件中需要通过 require(‘./singleobject‘).Hello来获取

Hello 对象,这略显冗余,可以用下面方法稍微简化:

//hello.js
function Hello() {
var name;
this.setName = function(thyName) {
name = thyName;
};
this.sayHello = function() {
console.log('Hello ' + name);
};
};
module.exports = Hello;
这样就可以直接获得这个对象了:
//gethello.js
var Hello = require('./hello');
hello = new Hello();
hello.setName('BYVoid');
hello.sayHello();

3创建包

包是在模块基础上更深一步的抽象, Node.js 的包类似于 C/C++ 的函数库或者 Java/.Net

的类库。它将某个独立的功能封装起来,用于发布、更新、依赖管理和版本控制。 Node.js 根

据 CommonJS 规范实现了包机制,开发了 npm来解决包的发布和获取需求。

Node.js 的包是一个目录,其中包含一个 JSON 格式的包说明文件 package.json。严格符

合 CommonJS 规范的包应该具备以下特征:

q package.json 必须在包的顶层目录下;

q 二进制文件应该在 bin 目录下;

q JavaScript 代码应该在 lib 目录下;

q 文档应该在 doc 目录下;

q 单元测试应该在 test 目录下。

Node.js 对包的要求并没有这么严格,只要顶层目录下有 package.json,并符合一些规范即可。当然为了提高兼容性,我们还是建议你在制作包的时候,严格遵守 CommonJS

作为文件夹的模块 

模块与文件是一一对应的。文件不仅可以是 JavaScript 代码或二进制代码,还可以是一

个文件夹。最简单的包,就是一个作为文件夹的模块。下面我们来看一个例子,建立一个叫做 somepackage的文件夹,在其中创建 index.js,内容如下:

//somepackage/index.js
exports.hello = function() {
console.log('Hello.');
};
//然后在 somepackage 之外建立 getpackage.js,内容如下:
//getpackage.js
var somePackage = require('./somepackage');
somePackage.hello();

运行 nodegetpackage.js,控制台将输出结果 Hello.。

我们使用这种方法可以把文件夹封装为一个模块,即所谓的包。包通常是一些模块的集

合,在模块的基础上提供了更高层的抽象,相当于提供了一些固定接口的函数库。通过定制

package.json,我们可以创建更复杂、更完善、更符合规范的包用于发布。

package.json

 

在前面例子中的 somepackage 文件夹下,我们创建一个叫做 package.json 的文件,内容如

下所示:

{

"main" : "./lib/interface.js"

}

然后将 index.js 重命名为 interface.js 并放入 lib 子文件夹下。以同样的方式再次调用这个包,依然可以正常使用。

Node.js 在调用某个包时,会首先检查包中 package.json 文件的 main 字段,将其作为

包的接口模块,如果 package.json或 main 字段不存在,会尝试寻找 index.js 或 index.node 作为包的接口。package.json 是 CommonJS 规定的用来描述包的文件,完全符合规范的 package.json 文件应该含有以下字段。

q name:包的名称,必须是唯一的,由小写英文字母、数字和下划线组成,不能包含

空格。

q description:包的简要说明。

q version:符合语义化版本识别①规范的版本字符串。

q keywords:关键字数组,通常用于搜索。

q maintainers:维护者数组,每个元素要包含 name、 email (可选)、 web (可选)

字段。

q contributors:贡献者数组,格式与maintainers相同。包的作者应该是贡献者

数组的第一个元素。

q bugs:提交bug的地址,可以是网址或者电子邮件地址。

q licenses:许可证数组,每个元素要包含 type (许可证的名称)和 url (链接到许可证文本的地址)字段。

q repositories:仓库托管地址数组,每个元素要包含 type(仓库的类型,如 git )、

url

q dependencies:包的依赖,一个关联数组,由包名称和版本号组成。

下面是一个完全符合 CommonJS规范的 package.json 示例:

{
"name": "mypackage",
"description": "Sample package for CommonJS. This packagedemonstrates the required
elements of a CommonJS package.",
"version": "0.7.0",
"keywords": [
"package",
"example"
],
"maintainers": [
{
"name": "Bill Smith",
"email": "[email protected]",
}
],
"contributors": [
{
"name": "BYVoid",
"web": "http://www.byvoid.com/"
}
],
"bugs": {
"mail": "[email protected]",
"web": "http://www.example.com/bugs"
},
"licenses": [
{
"type": "GPLv2",
"url": "http://www.example.org/licenses/gpl.html"
}
],
"repositories": [
{
"type": "git",
"url": "http://github.com/BYVoid/mypackage.git"
}
],
"dependencies": {
"webkit": "1.2",
"ssl": {
"gnutls": ["1.0", "2.0"],
"openssl": "0.9.8"
}
}
}

4.包管理器

Node.js包管理器,即npm是 Node.js 官方提供的包管理工具,它已经成了 Node.js 包的标准发布平台,用于 Node.js 包的发布、传播、依赖控制。 npm 提供了命令行工具,使你可以方便地下载、安装、升级、删除包,也可以让你作为开发者发布并维护包

获取一个包

Node.js包管理器,即npm是 Node.js 官方提供的包管理工具①,它已经成了 Node.js包的标准发布平台,用于 Node.js包的发布、传播、依赖控制。 npm 提供了命令行工具,使你可以方便地下载、安装、升级、删除包,也可以让你作为开发者发布并维护包。

1. 获取一个包

使用 npm 安装包的命令格式为:

npm [install/i] [package_name]

例如你要安装 express,可以在命令行运行:

$ npm install express

或者:

$ npm i express

随后你会看到以下安装信息:

[email protected]_modules\express

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected]

├──[email protected] ([email protected])

├──[email protected] ([email protected])

├──[email protected] ([email protected], [email protected])

├──[email protected] ([email protected], [email protected], [email protected], [email protected],[email protected])

├──[email protected] ([email protected], [email protected])

├──[email protected] ([email protected], [email protected])

└──[email protected] ([email protected], [email protected])

此时 express 就安装成功了,并且放置在当前目录的 node_modules子目录下。 npm 在获取 express 的时候还将自动解析其依赖,并获取其他包的支持。

本地模式和全局模式

npm在默认情况下会从http://npmjs.org搜索或下载包,将包安装到当前目录的node_modules、子目录下。

在使用 npm 安装包的时候,有两种模式:本地模式和全局模式。默认情况下我们使用 npm nstall命令就是采用本地模式,即把包安装到当前目录的 node_modules 子目录下。Node.js的 require 在加载模块时会尝试搜寻 node_modules子目录,因此使用 npm 本地模式安装的包可以直接被引用。

为什么要使用全局模式呢?多数时候并不是因为许多程序都有可能用到它,为了减少多

重副本而使用全局模式,而是因为本地模式不会注册 PATH 环境变量。举例说明,我们安装supervisor是为了在命令行中运行它,譬如直接运行 supervisor script.js,这时就需要在 PATH环境变量中注册 supervisor。 npm 本地模式仅仅是把包安装到 node_modules 子目录下,其中的 bin 目录没有包含在 PATH 环境变量中,不能直接在命令行中调用。而当我们使用全局模式安装时, npm 会将包安装到系统目录, 譬如 /usr/local/lib/node_modules/,
同时 package.json 文件中 bin 字段包含的文件会被链接到 /usr/local/bin/。 /usr/local/bin/ 是在PATH 环境变量中默认定义的,因此就可以直接在命令行中运行 supervisorscript.js

总而言之,当我们要把某个包作为工程运行时的一部分时,通过本地模式获取,如果要

在命令行下使用,则使用全局模式安装

创建全局连接

如果你是个较真的人,非得要引用安装在全局下的模块的话,那要怎么办呀!不可我再从全局复制一份到本地吧!!这样做少的情况下可以如果多的情况下会让你恶心死。。。

值得庆幸的是npm为我们提过了一个命令,npm  link,这个命令会在我们本地node_modules下创建一个引用全局的一个快捷连接符号噢噢,这样你就像引用本地模块式的require了是不是很爽啊!!!!!!

噹噹噹噹噹。。。。。。。。我们现在如果自己写了一个包我想让别人也用那就需要发布包咯噢噢,那要怎么发布包呢!!!!!

包的发布

首先我们要创建一个自己的包,nodejs都按commonjs标准来了那我们也不例外,我们首先创建一个package.json文件,如果你嫌手动创建麻烦,不要紧npm为我们出了一个命令叫npminit,这样我们在命令行内输入npm init,然后按照提示一步一步把版本号,包名称,写好最后会生成一个叫符合标准的package.json噢,然后创建一个lib文件夹 里边放一个index.js写上一句express.say=function(){console.log(“我要发布包了”); 这样我们手动创建的包就好了是不是很简单啊

然后我们就开始发布咯!在发布之前我们要获得一个帐号用于今后维护自己的包,使用npmadduser 根据提示输入用户名密码邮箱,等待帐号完成,完成后可以使用npmwhoami 测试是否已经取得帐号了。

接下来就可以在 package.json 所在目录下运行 npm publish稍等片刻就可以完成发布了。访问 http://search.npmjs.org/就可以找到自己刚刚发布的包了。如果你的包将来有更新,只需要在 package.json 文件中修改 version 字段,然后重新使用 npm publish 命令就行了。如果你对已发布的包不满意(比如我们发布的这个毫无意义的包),可以使用 npmunpublish 命令来取消发布

六调试

用命令方式调试

开发中难免会碰到bug,所以我想看下bug的所在位置那就需要调试了,我先说下nodejs内置的调试工具,当然也是基于命令行调试噢噢

前提是你新建一个自己的js脚本,在控制台输入node debug debug.js(debug.js是我要调试的脚本)将会打开了node.js的调试终端我们可以写一些命令来进入单步跟踪调试。

run 执行脚本,在第一行暂停

restart 重新执行脚本

cont, c 继续执行,直到遇到下一个断点

next, n 单步执行

step, s 单步执行并进入函数

out, o 从函数中步出

setBreakpoint(), sb() 在当前行设置断点

setBreakpoint(‘f()’), sb(...) 在函数f的第一行设置断点

setBreakpoint(‘script.js’, 20), sb(...) 在 script.js 的第20行设置断点

clearBreakpoint, cb(...) 清除所有断点

backtrace, bt 显示当前的调用栈

list(5) 显示当前执行到的前后5行代码

watch(expr) 把表达式 expr 加入监视列表

unwatch(expr) 把表达式 expr 从监视列表移除

watchers 显示监视列表中所有的表达式和值

repl 在当前上下文打开即时求值环境

kill 终止当前执行的脚本

scripts 显示当前已加载的所有脚本

version 显示V8 的版本

你会疑问后边的一个字母是不是多余啊!!!,一点也不多于,后边的一个字母或者两个字母的是前边单词的缩写,用缩写的方式也是好使的呵呵

远程调试

V8 提供的调试功能是基于 TCP 协议的,因此 Node.js 可以轻松地实现远程调试。在命

令行下使用以下两个语句之一可以打开调试服务器:

node--debug[=port] script.js

node --debug-brk[=port] script.js

node --debug 命令选项可以启动调试服务器,默认情况下调试端口是 5858,也可以

使用 --debug=1234 指定调试端口为 1234。使用 --debug 选项运行脚本时,脚本会正常执行,但不会暂停,在执行过程中调试客户端可以连接到调试服务器。如果要求脚本暂停执行等待客户端连接,则应该使用 --debug-brk选项。这时调试服务器在启动后会立刻暂停执行脚本,等待调试客户端连接。

node --debug 命令选项可以启动调试服务器,默认情况下调试端口是 5858,也可以

使用 --debug=1234 指定调试端口为 1234。使用 --debug 选项运行脚本时,脚本会正常执行,但不会暂停,在执行过程中调试客户端可以连接到调试服务器。如果要求脚本暂停执行等待客户端连接,则应该使用 --debug-brk选项。这时调试服务器在启动后会立刻暂停执行脚本,等待调试客户端连接。

当调试服务器启动以后,可以用命令行调试工具作为调试客户端连接,例如:

//在一个终端中

$node --debug-brk debug.js

debugger listening on port 5858

//在另一个终端中

$node debug 127.0.0.1:5858

connecting... ok

debug> n

break in /home/byvoid/debug.js:2

1 var a = 1;

2 var b = ‘world‘;

3 var c = function (x) {

4 console.log(‘hello ‘ + x + a);

debug>

事实上,当使用 node debug debug.js 命令调试时,只不过是用 Node.js命令行工

具将以上两步工作自动完成而已。

时间: 2025-01-04 06:03:46

node起步(初级node教程-02)的相关文章

node基础篇一:node介绍、node http、node event 课堂(持续)

最近工作一直很忙,没时间更新,谅解,这次准备更新一次node教程,本课堂将持续更新,每周坚持更新一到两章,希望对大家有一些小帮助吧: 一.首先什么是node? 1/Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. 2/Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效. 3/Node.js 的包管理器 npm,是全球最大的开源库生态系统. node安装不介绍了,官网直接安装即可,傻瓜式的下一步 ,在这就不耽误时间了: 二.node

一个master、一个node、查看node节点是ip

一个master.一个node.查看node节点是ip # 安装顺序:先在test1 上安装完必要组件后,就开始在 test2 上单独安装node组件,实现node功能,再返回来配置test1加入集群,实现node功能 # 本实验 test1 节点不做安装kubelet组件.只有安装启动了kubelet才会生成csr,kube-apiserver通过csr请求后才会成为一个node.所以是node节点单独安装 # 注意:准备了三台,这三台都做了环境准备,但是k8s集群只是使用了 test1.te

一个master、一个node、查看node节点是主机名

一个master.一个node.查看node节点是主机名 # 安装顺序:先在test1 上安装完必要组件后,就开始在 test2 上单独安装node组件,实现node功能,再返回来配置test1加入集群,实现node功能 # 本实验 test1 节点不做安装kubelet组件.只有安装启动了kubelet才会生成csr,kube-apiserver通过csr请求后才会成为一个node.所以是node节点单独安装 # 注意:准备了三台,这三台都做了环境准备,但是k8s集群只是使用了 test1.t

hidden node and exposed node problem

Exposed node problem In wireless networks, theexposed node problem occurs when a node is prevented from sending packets to other nodes because of a neighboring transmitter. Consider an example of 4 nodes labeled R1, S1, S2, and R2, where the two rece

会计基础教程(新纲) 初级会计电算化教程(新版) 法规与职业道德教程 初级会计实务教程

热门推荐电脑办公计算机基础知识教程 Excel2010基础教程 Word2010基础教程 PPT2010基础教程 五笔打字视频教程 Excel函数应用教程 Excel VBA基础教程 WPS2013表格教程 更多>平面设计PhotoshopCS5教程 CorelDRAW X5视频教程 Photoshop商业修图教程 Illustrator CS6视频教程 更多>室内设计3Dsmax2012教程 效果图实例提高教程 室内设计实战教程 欧式效果图制作实例教程 AutoCAD2014室内设计 Aut

001 -- Circle LinkList, list initiate, add a new node, delete a node, and List traverse

#include <studio.h> #include <stdlib.h> typedef struct CLinkList { int data; struct CLinkList *next ; } node; /*initiate a circle list*/ void ds_init(node **pNode) { int item; node *temp; node *target; printf("please input the value of th

Elasticsearch master node、 data node、 client node的区别与各自特点

es集群里的master node.data node和client node到底是怎么个意思,分别有何特点? master节点 主要功能是维护元数据,管理集群各个节点的状态,数据的导入和查询都不会走master节点,所以master节点的压力相对较小,因此master节点的内存分配也可以相对少些:但是master节点是最重要的,如果master节点挂了或者发生脑裂了,你的元数据就会发生混乱,那样你集群里的全部数据可能会发生丢失,所以一定要保证master节点的稳定性. data node 是负

Xcode5最初级的教程

相信IT男们,总会有那么一天希望自己捣鼓一个小App 让女朋友开心一下.那么就有了本文的开始的动机,话说带着兴趣做事情的时候进度是最快的也是最轻松的,这也是因为为什么有女朋友陪着的时候走多远的路脚都不会累. 好吧,那就开始了, 首先,为了开始你需要先去下载一个 Xcode .https://itunes.apple.com/us/app/xcode/id497799835?mt=12本文使用的 Xcode 是  iOS 7 版本发布后的 Xcode 5 .所以这将会使用到 iOS 7 全新的扁平

.NET程序员也学Node.js——初识Node.js

清明在石门休了八天假,一眨眼,4月又到中旬了...看到.NET在天朝彻底沦陷而又无能为力,我开始尝试去学习一些新的东西来充实自己,我自然是打死不会去学java的,没有为什么,于是乎,最近开始学习一些前端的开发技术,就让学习笔记来记录一下我的学习历程并同大家一起分享吧! 申明:我只是业余学着好玩的,顺便扩展一下视野,各位广大.NET同行不要被我带沟里去了,当然如果你想从事移动前端或者全栈开发的话还是有必要学习一下的. Node.js简介 Node.js 的推出,不仅从工程化的角度自动化掉更多琐碎费

JavaScript - Node.children和Node.childNodes的区别

写到这个也是因为群里的学长面试的时候遇到了这个问题,然后顺手分享了一下 首先是MDN里面对两个API的解释 children Node.children is a read-only property that returns a live HTMLCollection of the child elements of Node. childNodes The Node.childNodes read-only property returns a live collection of chil