Node那些事之模块化

什么是模块化开发,及模块化开发的好处

  • 什么是模块化开发: 把一些功能类似的代码,封装到一个单独的文件中去,这些单独抽离出来的代码,就能够提供各种各样好用的功能.这种通过代码功能分割文件的方式就叫做模块化开发.
  • 好处: 保证了每个文件的功能(职能)单一.需要什么特定的功能,就直接调用某一个特定的模块.这样对将来程序开发和维护都有好处

Node中如何实现模块化开发

在Node中主要通过三个东西实现模块化开发:

  • module: 表示一个模块,在Node中最常见的模块就是一个一个的JS文件.
  • require: 作用是加载其他模块用的.在一个JS文件中如果想要引用其他JS文件的成员,就需要使用require.
  • exports: 在Node的模块中,如果要这个模块向外暴露一些成员,以供其它JS模块使用,那么就要使用exports

Node中的模块化主要是为了解决JS文件之间的相互依赖关系

Node中模块的分类

Node有三部分组成:ECMAScript + 核心API + 第三方包

核心API

  • 什么是核心API: 由Node官方将一些常用的功能模块编译成二进制的执行文件,然后集成到Node的安装包中.在我们安装完Node之后,也同时安装了这些功能模块.
  • 如何使用核心模块: 使用require(“核心模块名称”)如下例
    1
    const XXX = require("XXX");

第三方模块

  • 什么是第三方模块: 除了官方提供的核心模块之外,我们在日常开发中也许还有一些使用频率很高的功能代码.而这些功能就被一些厉害的团队、个人、公司打包成可复用的模块.并通过NPM官网托管出去,供其他人下载使用.

  • 如何使用第三方模块:

    1. 先使用npm下载这个模块.
    2. 使用require导入你所下载的第三方模块.你导入模块的名字就是你安装时的名字.
    3. 通过查阅官方文档,使用你所下载的第三方模块

    注意:无论是核心模块还是第三方模块,都是通过 标识符名称 来引用这个模块的.

用户模块

  • 什么是用户模块: 自己所写的JS文件,统统属于用户模块
  • 用户模块向外导出成员的两种方式:
    1. 使用global这个全局对象,将你想要导出的成员挂载到这个对象上面.但是这种方法有两个缺陷.
      • 会造成全局变量污染
      • 不知道所引用的成员是谁导出的.
        所以一般情况下我们使用下面这种方式.
    2. 使用exports来导出需要暴露的成员

exports和module.exports

  1. 通过module.exports可以使用 . 的形式追加属性,也可以使用 = 直接赋值的形式导出成员
  2. exports只能通过 . 的形式追加属性,不能使用 = 直接赋值的形式
  3. 在一个module中,最终向外暴露的成员,以module.exports指向的对象为准.
  4. 在一个module中,不要混合使用module.exportsexports.

Node中的模块加载规则

优先从缓存中加载

  • 加载核心模块: 优先从缓存中加载,如果缓存中没有再去执行加载核心模块
  • 加载自己的模块: 优先从缓存中加载,如果缓存中没有,再去执行加载自己的模块.
    用户模块的查找规则:
    不过不写后缀名,则先严格按照给定的文件名去查找模块并加载.如果找不到,则按照一定的规则顺序去查找加载带后缀名的同名文件.如下例:

    1
    index -> index.js -> index.json -> index.node
  • 第三方的模块查找规则:

    1. 首先查看项目的跟目录下有没有node_modules这个文件夹.
    2. 查找node_modules文件夹中有没和第三方模块名称一致的文件夹.
    3. 在模块对应的文件夹中,查找有没有package.json这个文件
    4. package.json文件中查找有没有main属性.
    5. 如果有main属性,并且main属性指向的路径存在,那么就尝试加载这个路径指定的文件
    6. 如果package.json文件中,没有main属性,或者main属性指向的路径不存在,或者干脆就没有package.json文件.那么,就会尝试加载模块根目录中的index相关文件:index.js -> index.json -> index.node
    7. 如果在node_modules文件中找不到对应的模块文件夹,或者在项目根目录中就没有node_modules这个文件夹.则会向上一层的文件夹中查找,查找规则同上.
    8. 如果上一层文件夹得目录中也没有找到,则再向上一层文件夹中去找,直到找到当前项目所在的盘符根目录为止.
    9. 如果找到盘符根目录还没有找到,则报错:cannot find module ***

关于模块化

  • Node中的模块化基于common.js,其特点是有所的依赖项同步加载.
  • common.js由于是一个同步加载规范,所以不适合浏览端使用.于是浏览端有了异步模块加载机制AMD规范.
  • 在ES6中已推出了语言规格上的模块化方案.

我的个人网址: http://www.wangyiming19950222.com