Node.js历险记之剑未配好,已出江湖

标签: node.js
567人阅读 评论(0) 收藏 举报
分类:

这里写图片描述
打开微信扫一扫,关注微信公众号【码农故事多】

转载请注明出处:http://blog.csdn.net/gamer_gyt/
博主微博:http://weibo.com/234654758
Github:https://github.com/thinkgamer


写在前边的话

    其实我个人对于接受新知识是有点抵触的,当然这里的新知识指的是除了大数据范畴之前的,就比如说nodejs,但是由于种种原因,我决定还是学习下吧,顺便在这个过程中把javascript也好好学习一番,至于我为什么抵触大数据之外的东西,是因为我觉得人应该有棱角,知识和技术也一样,如果你什么都会,但是什么都不精那就没意思了。
    其实这一段时间一直有看elk的技术栈,在kibana的二次开发中,如果涉及到后台服务,那么nodejs就逃避不了了,当然还有难搞的js,反正我是很头疼。


Node.js是什么?

    js是脚本语言,脚本语言都需要一个解析器才能运行。对于写在HTML页面里的JS,浏览器充当了解析器的角色。而对于需要独立运行的JS,NodeJS就是一个解析器。
    每一种解析器都是一个运行环境,不但允许JS定义各种数据结构,进行各种计算,还允许js使用运行环境提供的内置对象和方法做一些事情。例如运行在浏览器中的js的用途是操作DOM,浏览器就提供了document之类的内置对象。而运行在Node.js中的JS的用途是操作磁盘文件或搭建HTTP服务器,Node.js就相应提供了fs、http等内置对象。


Node.js部署和简单使用

1:安装nvm

nvm是node.js版本管理工具,其全程是Node Version Manager,其实现是通过shell脚本,安装起来也比较方便
方法1:

curl https://raw.github.com/creationix/nvm/v0.4.0/install.sh | sh

方法2:

wget -qO- https://raw.github.com/creationix/nvm/v0.4.0/install.sh | sh

以上脚本会把nvm库clone到~/.nvm,然后会在~/.bash_profile, ~/.zshrc或~/.profile末尾添加source,安装完成之后,你可以用nvm –help 来查看其使用方法

2:安装nodejs

目前node官网上得最新版本为7.6.0
安装:

nvm install v7.6.0

当然这里得版本号是你可以选择得,你也可以安装多个版本得node,然后通过nvm use 来选择你要使用得node版本,如果你不知道你现在使用得node版本,你可以通过以下命令来查看

$node -v
v7.6.0

3:npm介绍使用

npm是随同node.js一起安装得包管理工具,能解决Node.js代码部署上得很多问题,常用得使用场景有:

  • 允许用户从NPM服务器上下载别人编写的第三方包到本地使用
  • 允许用户从NPM服务器下载并安装别人编写得命令杭程序到本地使用
  • 允许用户将自己编写的包或者命令程序上传到npm服务器供别人使用

由于新版得node.js已经集成了npm,在使用nvm install node-version之后, 可以使用npm -v来测试是否安装成功

$ npm -v
4.1.2

当然这里如果你使用的不是新版的npm,你可以使用下面的命令来升级npm

sudo npm install npm -g

npm install得时候有时候需要翻墙,这个时候就可以使用cnpm来替代npm,cnpm安装方式是:

npm install cnpm -g –registry=https://registry.npm.taobao.org

npm安装package分两种方式:本地安装和全局安装,区别是是否有 -g 标示,比如说:

npm install express //本地安装
npm install express -g //全局安装

其区别是:

  • 本地安装将安装包放在./node_moudles下,如果没有该目录, 会生成一个目录。
  • 全局安装是将安装包放在 /usr/local 下或者 你的node目录,你可以直接在命令行里调用。

你可以通过以下命令来查看你安装了那些全局包

npm ls -g

npm卸载,更新,搜索模块

npm uninstall express
npm update express
npm search express

npm 发布模块
(1):执行npm init ,按要求填写相应的信息,之后会在当前目录生成一个package.js的文件
(2):在npm 资源库中注册用户(使用邮箱注册)

$ npm adduser
Username:
Password:
Email: (this IS public) thinkgamer@163.com

(3):发布模块

npm publish

(4):如果你以上步骤都对,你就可以使用npm install 来安装你上传的模块

4:nodejs创建一个简单的项目

vim server.js,加入以下内容,然后执行node server.js

var http = require('http')
http.createServer(function (request, response){
    response.writeHead(200,{'Content-Type': 'text/plain'});
    response.end('Hello Thinkgamer,My blog is <a href="http://blog.csdn.net/gamer_gyt">Blog</a>\n')
}).listen(8888);
console.log('server as http://127.0.0.0.1:8888');

浏览器可看到:
这里写图片描述

分析代码:
第一行:引入node.js自带的http模块,并且赋值给http变量
接下来:调用createServer函数,返回一个对象,该对象有listen方法,指定服务器监听得端口号

5:Node.js REPL交互式解释器

通过node 进入

~$ node
>

常用的REPL命令:

ctrl + c - 退出当前终端。
ctrl + c 按下两次 - 退出 Node REPL。
ctrl + d - 退出 Node REPL.
向上/向下 键 - 查看输入的历史命令
tab 键 - 列出当前命令
.help - 列出使用命令
.break - 退出多行表达式
.clear - 退出多行表达式
.save filename - 保存当前的 Node REPL 会话到指定文件
.load filename - 载入当前 Node REPL 会话的文件内容。


Node.js的模块化

    编写稍微大一点的程序时都会将代码模块化,在Nodejs中,一般将代码合理的拆分到不同的JS文件中,每一个文件就是一个模块,而文件路径就是模块名,在编写每个模块时,都有require,export,module三个预先定义好的变量可供使用。

1:require

require函数用于在当前模块中加载和使用别的模块,传入一个模块名,返回一个模块导出对象,模块名可使用相对路径(./开头),或者绝对路径(/ 或者C:之类的盘符开头),另外模块名中的.js扩展名可以省略。例如

var foo1 = require(‘./hello’)
var foo2 = require(‘./hello.js’)

两者保存的是同一个模块导出的对象

2:exports

exports是当前模块的导出对象,用于导出模块共有方法和属性,别的模块通过require函数使用当前模块时得到的就是当前模块的导出对象,例如test.js

exports.hello=function(){
   console.log("hello, this is exports");
}

以上代码中,模块导出对象被替换为一个函数。
index.js内容如下:

var H = require('./test.js');
H.hello();

调用:

>node index.js
hello, this is exports

3:module

通过nodule对象可以访问到 当前模块的一些相关信息,但最多的用途是替换当前模块的导出对象。例如模块导出对象默认是一个普通对象,如果想改成一个函数的话,可以使用以下方式
test.js

module.exports=function(){
    var name;
    this.setName=function(new_name){
        name=new_name;
    };
    this.showName=function(){
        console.log(name);
    };
}

当然这个地方还可以这样写(test.js):

function Hello(){
    var name;
    this.setName=function(new_name){
        name=new_name;
    };
    this.showName=function(){
        console.log(name);
    };
};

module.exports=Hello;

index.js:

var Per = require('./test.js');
var p = new Per();
p.setName('thinkgamer');
p.showName();

调用:

>node index.js
thinkgamer

4:模块初始化

一个模块中的JS代码仅在模块第一次使用时执行一次,并在执行过程中初始化模块的导出对象,之后,缓存起来的导出对象被重复利用。

5:主模块

通过命令行参数传递给Nodejs以启动程序的模块被称为主模块,主模块负责调度组成整个程序的其他模块完成工作,例如通过以下命令来启动程序时,main.js就是主模块

$node main.js


Nodejs的代码组织

1:模块路径解析规则

(1) 内置模块

如果传递给require函数的是NodeJS内置模块名称,不做路径解析,直接返回内部模块的导出对象,例如require(‘fs’)。

(2) node_modules目录

NodeJS定义了一个特殊的node_modules目录用于存放模块。例如某个模块的绝对路径是/home/user/hello.js,在该模块中使用require(‘foo/bar’)方式加载模块时,则NodeJS依次尝试使用以下路径。

/home/user/node_modules/foo/bar
/home/node_modules/foo/bar
/node_modules/foo/bar

(3)NODE_PATH环境变量

与PATH环境变量类似,NodeJS允许通过NODE_PATH环境变量来指定额外的模块搜索路径。NODE_PATH环境变量中包含一到多个目录路径,路径之间在Linux下使用:分隔,在Windows下使用;分隔。例如定义了以下NODE_PATH环境变量:

NODE_PATH=/home/user/lib:/home/lib

当使用require(‘foo/bar’)的方式加载模块时,则NodeJS依次尝试以下路径。

/home/user/lib/foo/bar
/home/lib/foo/bar

2:包(package)

我们知道js模块的基本文件是单个js文件,但复杂些的模块往往由多个子模块组成,为了便于管理和使用,我们把由多个子模块组成的大模块称作包,并把所有子模块放在同一个目录下。

在组成一个包的所有子模块中,需要有一个入口模块,入口模块的导出对象被作为包的导出对象。例如有以下目录结构。

- /home/user/lib/
    - cat/
        head.js
        body.js
        main.js

其中cat目录定义了一个包,其中包含了3个子模块。main.js作为入口模块,其内容如下:

var head = require('./head');
var body = require('./body');
exports.create = function (name) {
    return {
        name: name,
        head: head.create(),
        body: body.create()
    };
};

在其它模块里使用包的时候,需要加载包的入口模块。接着上例,使用require(‘/home/user/lib/cat/main’)能达到目的,但是入口模块名称出现在路径里看上去不是个好主意。因此我们需要做点额外的工作,让包使用起来更像是单个模块。

index.js
当模块的文件名是index.js,加载模块时可以使用模块所在目录的路径代替模块文件路径,因此接着上例,以下两条语句等价。

var cat = require(‘/home/user/lib/cat’);
var cat = require(‘/home/user/lib/cat/index’);

这样处理后,就只需要把包目录路径传递给require函数,感觉上整个目录被当作单个模块使用,更有整体感。
package.json
如果想自定义入口模块的文件名和存放位置,就需要在包目录下包含一个package.json文件,并在其中指定入口模块的路径。上例中的cat模块可以重构如下。

- /home/user/lib/
    - cat/
        + doc/
        - lib/
            head.js
            body.js
            main.js
        + tests/
        package.json

其中package.json内容如下。

{
    "name": "cat",
    "main": "./lib/main.js"
}

如此一来,就同样可以使用require(‘/home/user/lib/cat’)的方式加载模块。NodeJS会根据包目录下的package.json找到入口模块所在位置。

3:工程目录

以编写一个命令行程序为例,一般我们会同时提供命令行模式和API模式两种使用方式,并且我们会借助三方包来编写代码。除了代码外,一个完整的程序也应该有自己的文档和测试用例。因此,一个标准的工程目录都看起来像下边这样。

- /home/user/workspace/node-echo/   # 工程目录
    - bin/                          # 存放命令行相关代码
        node-echo
    + doc/                          # 存放文档
    - lib/                          # 存放API相关代码
        echo.js
    - node_modules/                 # 存放三方包
        + argv/
    + tests/                        # 存放测试用例
    package.json                    # 元数据文件
    README.md                       # 说明文件

其中部分文件内容如下:

/* bin/node-echo */
var argv = require('argv'),
    echo = require('../lib/echo');
console.log(echo(argv.join(' ')));
/* lib/echo.js */
module.exports = function (message) {
    return message;
};
/* package.json */
{
    "name": "node-echo",
    "main": "./lib/echo.js"
}

以上例子中分类存放了不同类型的文件,并通过node_moudles目录直接使用三方包名加载模块。此外,定义了package.json之后,node-echo目录也可被当作一个包来使用。


下一篇: Node.js历险记之express框架入门篇

0
0

猜你在找
【直播】机器学习&深度学习系统实战(唐宇迪)
【直播】Kaggle 神器:XGBoost 从基础到实战(冒教授)
【直播回放】深度学习基础与TensorFlow实践(王琛)
【直播】计算机视觉原理及实战(屈教授)
【直播】机器学习之凸优化(马博士)
【直播】机器学习之矩阵(黄博士)
【直播】机器学习之概率与统计推断(冒教授)
【直播】机器学习之数学基础
【直播】TensorFlow实战进阶(智亮)
【直播】深度学习30天系统实训(唐宇迪)
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    Thinkgamer微博
    个人微信,一起交流!

     扫一扫,关注我




    个人资料
    • 访问:645460次
    • 积分:8497
    • 等级:
    • 排名:第2207名
    • 原创:211篇
    • 转载:22篇
    • 译文:2篇
    • 评论:240条
    个人简介
    姓名:Thinkgamer

    Github:https://github.com/thinkgamer

    主攻:云计算/python/数据分析

    程度:熟悉/熟悉/熟悉

    微信:gyt13342445911

    Email:thinkgamer@163.com

    工作状态:在职ing

    心灵鸡汤:只要努力,你就是下一个大牛...

    hadoop/spark/机器学习群:279807394(大神建的群,蹭个管理员)

    欢迎骚扰........
    博客专栏
    最新评论