本文同步自我的个人博客:http://www.52cik.com/2015/12/14/learn-node-modules-module.html

上一篇讲了模块是如何被寻找到然后加载进来的,这篇则是如何导出属性方法以及自定义模块后缀等一系列模块问题。

exports 对象

这是最常见的对象了,以往导出都是这样写的。

// a.js
exports.bar = '属性';
exports.fn = function () { return '方法' }; // b.js
var a = require('./a');
console.log(a.bar); // 属性
console.log(a.fn()); // 方法

一直都是这么用非常简单,但是不能直接用对象覆盖他,如下代码是不对的。

// a.js
exports = {
bar: '属性',
fn: function () { return '方法' }
}; // b.js
var a = require('./a');
console.log(a.bar); // undefined
console.log(a.fn()); // 报错

为什么不能直接覆盖呢,因为 exports 只是 module.exports 对象的引用。

module.exports 对象

如果要导出一整个对象或者构造函数之类的,就需要用到 module.exports 对象了。

// a.js
module.exports = {
bar: '属性',
fn: function () { return '方法' }
}; // b.js
var a = require('./a');
console.log(a.bar); // 属性
console.log(a.fn()); // 方法

导出构造函数:

// klass.js
function klass () {}
klass.prototype.say = function () { return '我是klass' };
module.exports = klass; // b.js
var Klass = require('./klass');
var klass = new Klass();
console.log(klass.say()); // 我是klass

module 其他属性

module 还有些其他属性,简单说下吧。

  • module.id 模块id,往往是模块路径
  • module.children 子模块
  • module.filename 模块路径
  • module.loaded 是否加载完毕
  • module.parent 父模块
  • module.paths 各级 node_modules 目录路径

require 函数

说模块,当然离不开 require 函数,除了加载模块之外,他还有一些其他用法。

  • require.resolve 不会加载执行,只会返回模块的绝对路径。
  • require.cache 缓存所有已经加载的模块,如果你要更新模块就要删除这里的缓存。
var a = require('./a');
var p = require.resolve('./a'); // 得到模块路径 delete require.cache[p]; // 删除模块缓存

虽然不清楚什么时候用,但是至少是这么用的,删除缓存后,下次加载这个模块,就会重新加载模块文件了。

require.extensions 自定义模块后缀

还有个 require.extensions 非常好用的属性,但遗憾的是官方提示弃用了这个属性,不过值得庆幸的是,这个属性永远不会被移除,只是不推荐使用而已。

我第一次注意到这个属性是在 ejs 源码里,当时很好奇这是个什么东西,去翻了下官方文档,发现捡到宝了。后来又发现 node 命令行下的 babel 模块也注册了自定义模块,后缀分别是 .es, .es6, .jsx,可以直接 require('./a.es6') 或者是 require('./a.jsx') 得到编译好的 js 代码。

好了,不说废话了,来看个官方简单例子吧。

require.extensions['.json'] = function(module, filename) {
var content = fs.readFileSync(filename, 'utf8');
try {
module.exports = JSON.parse(content);
} catch (err) {
err.message = filename + ': ' + err.message;
throw err;
}
};

这是 node 源码的 json 模块实现,我只是删除了一个 stripBOM 函数,为了方便大家理解。

当然官方不推荐这样做是有道理的,官方推荐编译为兼容的 js 代码模块运行,性能更佳,而不应该采用这样的自定义模块实现。

不过看用途而定了,有时候也不一定追求极致的性能。

node 学习笔记 - Modules 模块加载系统 (2)的更多相关文章

  1. node 学习笔记 - Modules 模块加载系统 (1)

    本文同步自我的个人博客:http://www.52cik.com/2015/12/11/learn-node-modules-path.html 用了这么久的 require,但却没有系统的学习过 n ...

  2. thinkphp学习笔记9—自动加载

    原文:thinkphp学习笔记9-自动加载 1.命名空间自动加载 在3.2版本中不需要手动加载类库文件,可以很方便的完成自动加载. 系统可以根据类的命名空间自动定位到类库文件,例如定义了一个类Org\ ...

  3. abp vnext2.0之核心组件模块加载系统源码解析与简单应用

    abp vnext是abp官方在abp的基础之上构建的微服务架构,说实话,看完核心组件源码的时候,很兴奋,整个框架将组件化的细想运用的很好,真的超级解耦.老版整个框架依赖Castle的问题,vnext ...

  4. 第三章:模块加载系统(requirejs)

    任何一门语言在大规模应用阶段,必然要经历拆分模块的过程.便于维护与团队协作,与java走的最近的dojo率先引入加载器,早期的加载器都是同步的,使用document.write与同步Ajax请求实现. ...

  5. Openstack本学习笔记——Neutron-server服务加载和启动源代码分析(三)

    本文是在学习Openstack过程中整理和总结.因为时间和个人能力有限.错误之处在所难免,欢迎指正! 在Neutron-server服务载入与启动源代码分析(二)中搞定模块功能的扩展和载入.我们就回到 ...

  6. Node学习笔记之模块实现

    一.模块分类 由Node提供的模块,称为核心模块:部分核心模块在Node源代码的编译过程中,编译进了二进制执行文件.在node进程启动时,该部分就直接加载进内存,文件定位和编译执行的步骤可以省略掉,并 ...

  7. JS框架设计之加载器所在路径的探知一模块加载系统

    1.要加载一个模块,我们需要一个URL作为加载地址,一个script作为加载媒介,但用户在require是都用ID,我们需要一个将ID转换为URL的方法,思路很简单,强加个约定,URL的合成规则是为: ...

  8. JS框架设计之模块加载系统

    任何语言一到大规模应用阶段,必然要拆封模块,有利于维护和团队协作,与Java走得最近的dojo率先引进了加载器,使用document.write与同步Ajax请求实现,后台dojo以JSONP的方法来 ...

  9. YUI笔记 1 模块加载

    我们通常开发js程序就是使用<script>标签把脚本引入到页面中进行开发,如果是简单的逻辑还好,但是如果是比较庞大的大规模js开发,可能会出现下面的问题: 1.  <script& ...

随机推荐

  1. SQL Server(五)——常用函数

    1.数学函数:操作一个数据,返回一个结果 --取上限ceiling select code,name,ceiling(price) from car ; --取下限 floor select floo ...

  2. 0003 64位Oracle11gR2不能运行SQL Developer的解决方法

    "应用程序开发"下的"SQL Developer"双击不可用,出现“Windows正在查找SQLDEVELOPER.BAT"的提示,如下图: 搜索博客 ...

  3. SQL语句查询某表的所有字段及数据类型

    SQL语句查询某表的所有字段及数据类型 SELECT name AS column_name , TYPE_NAME(system_type_id) AS column_type , max_leng ...

  4. jQuery 3.0 的变化

    时隔 3 个月,jQuery 团队终于发布了 3.0 Alpha 版本.有两个版本 jQuery compat 3.0 和 jQuery 3.0. jQuery compat 3.0 对应之前的 1. ...

  5. [转]使用Oracle SQL Developer 17410 提示无法从套接字获取更多数据如何解决

    本文转自:http://m.educity.cn/ite/1121475.html 将oracle?安装目录下的Network/admin/listener.ora文件中的 (PROGRAM = ex ...

  6. 转载:学习Entity Framework 中的Code First

    看完觉得不错,适合作为学习资料,就转载过来了 原文链接:http://www.cnblogs.com/Wayou/archive/2012/09/20/EF_CodeFirst.html 这是上周就写 ...

  7. Zookeeper C API 指南四(C API 概览)(转)

    上一节<Zookeeper C API 指南三(回调函数)>重点讲了 Zookeeper C API 中各种回调函数的原型,本节将切入正题,正式讲解 Zookeeper C API.相信大 ...

  8. UESTC 33 Area --凸包面积

    题意: 求一条直线分凸包两边的面积. 解法: 因为题意会说一定穿过,那么不会有直线与某条边重合的情况.我们只要找到一个直线分成的凸包即可,另一个的面积等于总面积减去那个的面积. 怎么得到分成的一个凸包 ...

  9. javascript里面foreach遍历函数介绍,以及跟jquery里面each的区别

    foreach是把数组从头到尾遍历一遍,有三个参数分别是:数组元素,数组索引,数组本身.如果是一个参数,就是数组元素. var data=[1,2,3,4,5,6]; var sum=0; data. ...

  10. zepto阻止事件冒泡

    $("#model_frame").on("click",function(){ $(this).hide(); console.log($(this)); } ...