每天一篇文章来记录记录自己的成长吧。大二,该静心了。加油~

好了,废话不多说,今天说说nodejs中的模块化.(注:此文为自己对书nodejs实战的总结)

nodejs一个重要的特性就是模块化,模块就是node.js对常用功能进行分组的方式。而且,node无需真正辨别模块到底是我们自己编写的还是从外部仓库中获取的。这样我们只需要一个额外的json文档和一两行代码,我们就能引用别人的代码或者别人引用我们的代码,是不是很酷~。

好,下面我们来编写一个简单的模块:

exports.hello_world = function(){
console.log("Hello World");
}

我们用mymodule.js文件来保存这段代码,exports对象是一个特殊的对象,在每个我们创建的文件中由Node的文件系统创建,当我们引用这个模块时,会作为require函数的值返回。它被封装在每个模块的module对象中,用来暴露函数,变量或类。使用模块的方法也很简单,代码如下:

var mm = require('./mymodule');
mm.hello_world();

这样我们可以通过exports对象来暴露任何我们想要暴露的函数和类。当我们频繁的从模块中返回对象时,我们会有两种使用的核心模式:

第一种就是我们的工厂模式,看下面一段代码:

function Hello(lang){
this.language = lang;
this.greet() = function(){
switch(this.language){
case "en" :return "Hello1";break;
case "de" :return "Hello2";break;
case "jp" :return "Hello3";break;
default:return "No speaka that language";break;
}
}
} //现在我们用工厂模式来返回我们Hello类的实例
exports.create_Hello = function(lang){
return new Hello(lang);
}

这种模式的有点事模块可以通过exports对象来暴露其他的函数和类。

第二种模式就是构造函数模式,即直接模式,现在我们函数不变,用构造函数代码就应是这样:

module.exports = Hello;

注意我们在使用的时候就应该把代码变一下:

var hello = require("./mymodule");
var lang = "en";
var obj = new hello(lang);
obj.greet();

但记住在这里我们真正唯一暴露的是一个类的构造函数。这和我们面向对象的思想很接近,但是有个缺点就是我们不能让模块暴露更多的东西。所以我们经常会用的是我们的工厂模式。

关于exports和module.exports的区别大家来看这个网址:https://cnodejs.org/topic/52308842101e574521c16e06.

我们知道了想要在一个文件中引入模块我们只需使用require函数即可,注意我们引入的模块对于引入他们的模块时私有的。如果a.js加载http模块,那么b.js是无法加载这个模块的,除非b也引入了http模块。

下面看看Node.js是怎样来查找模块的,其实规则很简单:

1.当请求的是内置模块(如http和fs)时,node会直接使用这些模块

2.当请求的模块一路径符(如./  ../  /)开始时,node会找到指定的目录并且加载他,如果没有在模块名中指定.js扩展名,那么node会首先查找基于同名文件夹的模块,如果没有找到,那么他会添加扩展名.js .json和.node,并尝试一次加载这些模块(带node扩展名的模块会被编译成附加模块)

3.如果没有路径符,node会在当前文件夹的node_modules/子文件夹下查找模块。如果找到,则加载该模块,否则,node会以自己的方式在当前位置的路径树下寻找mode_modules/文件夹,如果还失败,那么他会在一些默认的地址下进行搜寻,如/usr/lib和/usr/local/lib文件夹.

4.如果还没找到就抛出错误.

以前我们在引用文件时很容易进入引用文件死循环,但是在node中却不会这样。比如我在a.js中引入b.js,在b.js中引入a.js,在main.js中引入a.js,这个在node 中的执行顺序是先加载main.js,然后运行 引入a.js,再引入b.js,然后node会检测到循环并返回一个指向a.js的对象,但是不会再执行此代码。

我们知道node.js的每个文件都是一个含有module和exports对象的模块,这个模块也可以很复杂:包含一个目录用来保存模块的内容和一个包含包信息的文件。如果我们想要编写一系列的支持文件,并将模块的功能拆散到多个js文件中,甚至包含单元测试,那么我们可以这么来写:

1.创建一个文件夹来存放模块的内容

2.添加一个名为package.json的文件到文件夹中。文件至少包含当前模块的名字和一个主要的JS文件(用来一开始加载该模块)

3.如果Node没有找到package.json文件或者没有指定主JS文件,那他就会查找index.js(或者是编译后的附加模块index.node)

当然模块的内容不止这么一点点,剩下的以后再补充吧。

Node.js中的模块化的更多相关文章

  1. 在node.js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查

    Sequelize是一个基于promise的关系型数据库ORM框架,这个库完全采用JavaScript开发并且能够用在Node.JS环境中,易于使用,支持多SQL方言(dialect),.它当前支持M ...

  2. 如何在Node.js中合并两个复杂对象

    通常情况下,在Node.js中我们可以通过underscore的extend或者lodash的merge来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢? 例如我有以下两个object: ...

  3. Node.js中的Session,不要觉得简单哦。

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,博客地址为http://www.cnblogs.com/jasonnode/ .学习网站上有对应 ...

  4. Node.js 中MongoDB的基本接口操作

    Node.js 中MongoDB的基本接口操作 连接数据库 安装mongodb模块 导入mongodb模块 调用connect方法 文档的增删改查操作 插入文档 方法: db.collection(& ...

  5. 在node.js中使用COOKIE

    node.js中如何向客户端发送COOKIE呢?有如下两个方案: 一.使用response.writeHead,代码示例: //设置过期时间为一分钟 var today = new Date(); v ...

  6. 初步揭秘node.js中的事件

    当你学习node.js的时候,Events是一个非常重要的需要理解的事情.非常多的Node对象触发事件,你能在文档API中找到很多例子.但是关于如何写自己的事件和监听,你可能还不太清楚.如果你不了解, ...

  7. Node.js权威指南 (10) - Node.js中的错误处理与断言处理

    10.1 使用domain模块处理错误 / 272 10.1.1 domain模块概述 / 272 10.1.2 创建并使用Domain对象 / 274 10.1.3 隐式绑定与显式绑定 / 276 ...

  8. Node.js中的URL

    Node.js中的URL 什么是URL URL是Uniform Location Resource的缩写,翻译为"统一资源定位符",也就是描述资源位置的固定表示方法.被URL描述的 ...

  9. mysql语句在node.js中的写法

    总结一下mysql语句在node.js中的各种写法,参考了npm网站mysql模块给的实例. 查询 select //1 db.query('select * from tuanshang_users ...

随机推荐

  1. [vsftp]500 OOPS: cannot change directory

    这个报错需要检查 1./etc/passwd 用户的主目录 2./etc/vsftpd/vuser_conf 下每个用户的local_root 3.每个用户目录给ftpuser加上rwx权限,一定要有 ...

  2. django中时区设置

    通过django中的models更新数据库的DateTimeField字段,发现有错误,于是更改了: TIME_ZONE = 'Asia/Shanghai' 结果,还是不正确,于是把: USE_TZ ...

  3. 6 个优秀的开源 OCR 光学字符识别工具

    转自:http://sigvc.org/bbs/thread-870-1-1.html 纸张在许多地方已日益失宠,无纸化办公谈论40多年,办公环境正限制纸山的生成.而过去几年,无纸化办公的概念发生了显 ...

  4. c++11 中的 move 与 forward

    [update: 关于左值右值的另一点总结,请参看这篇] 一. move 关于 lvaue 和 rvalue,在 c++11 以前存在一个有趣的现象:T&  指向 lvalue (左传引用), ...

  5. 进制格式转换 c#

    Console.WriteLine());//即17是十六进制位 得到的结果是23 得到十进制数 将字符串转换成二进制 public static string mdFiveGet(string md ...

  6. Yii cookie 的使用方法

    设置cookie: //首先新建cookie$cookie = new CHttpCookie('mycookie', 'this is my cookie');//定义cookie的有效期$cook ...

  7. Shiro使用总结

    Shiro已经添加到项目中,现阶段管理两个功能: 1.身份验证:(已经能够满足现阶段需求) 2.权限管理: 权限管理,需要在界面中加一些标签,后台角色.资源的管理也需要整理好,然后在前端添加管理. 1 ...

  8. tostring格式化输出

    C 货币 2.5.ToString("C") ¥2.50 D 十进制数 25.ToString("D5") 00025 E 科学型 25000.ToString ...

  9. Nginx 下无法读取session 导致 thinkphp验证码错误

    打开php配置文件 php.ini 使用搜索命令 whereis php.ini 一般在:/etc/php.ini 目录下 使用vim命令打开 找到: session.save_path 找到php保 ...

  10. Cookie禁用了,Session还能用吗?

    Cookie与Session,一般认为是两个独立的东西,Session采用的是在服务器端保持状态的方案,而Cookie采用的是在客户端保持状态的方案.Cookie分为两种,一种可以叫做session ...