这篇文章本来是想模块导入导出和事件循环一起写的,但是感觉一起写的话会太长了,所以就分开两篇文章写吧。下一篇会重点介绍一下js中的事件循环,js代码到底是以何种顺序去执行的呢?我相信你看懂了事件循环再去看node对你的帮助是非常大的。

讲模块系统之前先认识一下node.js中的全局对象。

node.js的全局对象

  众所周知的是在浏览器中的老大哥是谁,它就是window,this指向的也是window,那么在node中的全局对象就不是window了,而是global,可以在命令行中去看一下,想学习node的应该已经安装了node环境,如果还没有安装可以去node中文网去找到你对应的操作系统和版本去下载,如果node命令不是全局还需要配置一下环境变量,现在window操作系统安装上node之后应该就自动配置完成了。

  打开命令行,输入 node 回车,然后输入 this 或者global就可以看到全局对象。你会看到好多东西,但是他比window对象是少太多太多了。

  在JavaScript中,使用script标签去引入js文件的话,那么在js文件中的全局变量都会挂载到window对象下面,在各个文件中都可以共享它那个变量,比如jQuery,你引入了一个jQuery文件,那么在其它的文件当中,你是可以访问到$这个变量的。

  而在node.js中是如何实现文件之间的的引入呢,就不得不提及到commonjs了。

common.js

  查阅资料是这么说的:JavaScript是一种强大的面向对象语言,它有很多快速高效的解释器。官方JavaScript标准定义的API是为了构建基于浏览器的应用程序。然而,并没有定义一个用于更广泛的应用程序的标准库。CommonJS API定义了很多普通应用程序(主要指非浏览器的应用)使用的API,从而填补了这个空白。它的终极目标是提供一个类似Python,Ruby和Java的标准库。这样的话,开发者可以使用CommonJS API编写应用程序,然后这些应用可以运行在不同的JavaScript解释器和不同的主机环境中。在兼容 CommonJS 的系统中,你可以使用JavaScript开发服务器端JavaScript应用程序、命令行工具、图形界面应用程序和Hybrid混合应用程序。
 
  通俗易懂的来说就是 CommonJS就是为了js的表现来指定来指定规范,因为js没有模块功能所以CommonJs应运而生,它的出现,目的就是为了让js在其他环境也能执行,而不仅仅局限于浏览器。

  CommonJs是一种规范,Node.js就是这种规范的实现。

引入模块require

  全局变量在所有模块中均可使用。讲道理我们理解的require就是一个全局变量, 但是官方文档说的是此变量虽然看起来像全局变量,但实际上不是。 它们的作用域只在模块内。那我也不管它了,它的实现大概也就是像那种在文件中的一个函数把require传进来,像下面这样。

  具体的讲解:CommonJs模块规范,我们知道每个模块文件中存在着require、exports、module这3个变量,但是它们在模块文件中并没有定义,那么从何而来呢?甚至在Node的API文档中我们知道每个模块中还有__filename、__dirname这两个变量的存在,它们又是从何而来的呢?

  事实上,在编译的过程中,Node.js对获取的JavaScript文件内容进行了头尾包装。在头部添加了(function(exports,require,module,__filename,__dirname){\n,在尾部添加了\n});一个正常的JavaScript文件被包装成了如下的样子。

(function (exports,require,module,__filename,__dirname) {
exports.a = 1;
exports.fn = function () {
console.log(1);
};
});

 如图为global的全局变量

  具体的使用方法

let obj = require('./2.js');
console.log(obj);

  值得注意的是:  1.   ./代表的是当前目录下,然后是2.js,需要注意的是,如果引入的是本地的文件,那么一定要带上路径。

  2. 如果后缀名是js文件的话是可以省略的。

  3.有一些模块是不需要带路径的,它们称之为核心模块,何为核心模块

    第一种是安装好node就有的一些模块,另外一种是用npm安装依赖的那些在node_modules文件夹下面的

  4.模块的加载机制: 文件名 > 文件名.js >文件名.json>文件名.node

  与前端浏览器会缓存静态脚本文件以提高性能一样,Node对引入过的模块都会进行缓存,以减少二次引入时的开销。不同的地方在于,浏览器仅仅缓存,而Node缓存的是编译和执行之后的对象。

  安装好node就有的一些模块可以去node中文网的文档左侧都是,比如这些都是。

  

导出模块 module.exports

  先看下面的例子,运行app.js,具体操作为命令行打开到当前的目录下, 运行  node app.js

app.js

let obj = require('./2.js');
console.log(obj); // 1

2.js

module.exports = 1;

  app.js文件中引入的是2.js文件,然后 2.js文件通过module.exports来赋值为1,require的话还有一点就是他会去寻找引入进来文件的module.export,然后把那个1赋值给了obj,打印出来 1。

  module也是一个全局变量,它和require一样,但实际上不是。 它们的作用域只在模块内。导出模块可能有的人见过下面的写法。

2.js

exports.a = 1;

app.js代码同样不改变,打印出来的东西是  {a: 1};

其实exports是module.exports的一个引用, exports 也是一个全局变量,和上面require,module一样,作用域只在模块内。

导出模块的话你可能会想到这样做

 module.exports = {}; //在内部的话这个东西默认等于{}

  //所以你想到了导出的话可以这样
module.exports = {
  a: 1,
  b: function(){},
  c: 'name'
}

如果你这样做的话就是不正确的

 //这样做是不正确的
exports = {
a: 1,
b: function(){},
c: 'name'
}; // 正确的做法应该是这样
exports.a = 1;
exports.b = function () {};
exports.c = 'name'; // 因为exports是module.exports的一个引用,重新给exports赋值的话只会改变exports的值,而require引入的话寻找的是模块中的module.exports

  可能有的人会这样想,我直接写到global对象下面去不就可以引入了吗,为什么还需要用exports这种东西呢?具体写法如下

app.js

let obj = require('./2.js');
console.log(global.obj);
console.log(global.obj2);

2.js

global.obj = {
a: 'name',
b: function () {
console.log('1111')
}
};
global.obj2 = '狗蛋';

  怎么说呢,这样做是可以的,但是不推荐把所有的东西都写到global下面,会污染global对象,还是推荐使用exports去进行模块之间的导入导出。

  

  模块的导入导出的操作非常简答,但是对一些概念性的东西理解之后我相信会更好,当然require还有好多原理没有讲到,如果有兴趣的可以查阅资料继续学习,我相信如果只是使用的话掌握到现在的程度已经是可以的了,想继续深入的可以看看  朴灵写的 深入浅出Node.js 这本书。

  如果你看了我的文章有了一些收获我会非常高兴的,由于能力有限,文章有的部分解释的不到位,希望在以后的日子里能慢慢提高自己能力,如果不足之处,还望指正。

Node.js模块导入导出的更多相关文章

  1. [vue]js模块导入导出export default

    webstrom调试未授权问题解决 分es6语法和node语法 参考 参考 - export default s1 1.仅能出现1次default 2.导入时候可以随便命名 3,导出时候不必写{} - ...

  2. js模块导入/导出大全

    说明 module.exports与exports是CommonJS的规范 export与export default是es6规范 require 是 AMD规范引入方式 import是es6的一个语 ...

  3. Node.js模块

    每一个Node.js都是一个Node.js模块,包括JavaScript文件(.js).JSON文本文件(.json)和二进制模块文件(.node). mymodul.js function Hell ...

  4. Node Js模块讲解

    Node JS模块 所谓的Node JS模块其实就是指Node JS package,即nodejs包. 一 什么是NodeJS模块? 在说这个问题之前,我们有必要提出一个概念,即模块规范. 现阶段J ...

  5. 如何发布一个自定义Node.js模块到NPM(详细步骤)

    咱们闲话不多说,直接开始! 由于我从没有使用过MAC,所以我不保证本文中介绍的操作与MAC一致. 文章开始我先假定各位已经在window全局安装了Node.js,下面开始进行详细步骤介绍: 本文本着, ...

  6. 编写原生Node.js模块

    导语:当Javascript的性能需要优化,或者需要增强Javascript能力的时候,就需要依赖native模块来实现了. 应用场景 日常工作中,我们经常需要将原生的Node.js模块做为依赖并在项 ...

  7. 编写原生的Node.js模块

    导语:当Javascript的性能遭遇瓶颈,或者需要增强Javascript能力的时候,就需要依赖native模块来实现了. 应用场景 日常工作中,我们经常需要将原生的Node.js模块做为依赖并在项 ...

  8. Node.js模块封装及使用

    Node.js中也有一些功能的封装,类似C#的类库,封装成模块这样方便使用,安装之后用require()就能引入调用. 一.Node.js模块封装 1.创建一个名为censorify的文件夹 2.在c ...

  9. 10、Node.js模块系统

    ##################################################################################介绍Node.js模块系统为了让No ...

随机推荐

  1. JAVA基础—线程池

    推荐文章java多线程基础 线程池概述 为什么要使用线程池 1.服务器创建和销毁工作线程的开销很大 2.如果频繁的创建和销毁线程会导致频繁的切换线程,因为一个线程被销毁后,必然要把CPU转让给另一个已 ...

  2. [Swift]LeetCode524. 通过删除字母匹配到字典里最长单词 | Longest Word in Dictionary through Deleting

    Given a string and a string dictionary, find the longest string in the dictionary that can be formed ...

  3. docker for mac 创建私有仓库

    拉取镜像 docker pull registry 运行registry run -d -p : -v /Users/huangenai/docker/registry:/var/lib/regist ...

  4. 【斐波那契数列】java探究

    题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). n<=39 解析 (1)递归方式 对于公式f(n) = f(n-1) + f(n ...

  5. Java序列化和反序列化,你该知道得更多

    序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象的状态,重新 ...

  6. [八]基础数据类型之Double详解

    Double 基本数据类型double  的包装类 Double 类型的对象包含一个 double 类型的字段   属性简介 用来以二进制补码形式表示 double 值的比特位数 public sta ...

  7. 一键解决 go get golang.org/x 包失败

    问题描述 当我们使用 go get.go install.go mod 等命令时,会自动下载相应的包或依赖包.但由于众所周知的原因,类似于 golang.org/x/... 的包会出现下载失败的情况. ...

  8. 找到bug的根源,问五次为什么

    在学习<问题分析与解决>时学到了一种找到问题根源的方法——问五次为什么.具体内容是:当遇到一个问题,不要只看当前答案,要继续往下问,为什么,连问五次,就能够找到更深层次的问题.最近在复盘b ...

  9. Oracle闪回表

    Oracle闪回技术 场景:测试环境数据库的表数据被误删除. 解决思路:使用闪回表技术 原理 闪回技术是Oracle强大数据库备份恢复机制的一部分,在数据库发生逻辑错误的时候,闪回技术能提供快速且最小 ...

  10. 消息队列中间件(三)Kafka 入门指南

    Kafka 来源 Kafka的前身是由LinkedIn开源的一款产品,2011年初开始开源,加入了 Apache 基金会,2012年从 Apache Incubator 毕业变成了 Apache 顶级 ...