• CommonJS模块化



    一、Node.js模块化

    1.node.js模块类型

      node.js模块类型常见的分为三块:

    内置模块:如fs、http模块等。。
    用户自定义模块:用户自己编写的js文件
    第三方模块:如通过npm包管理工具导入的第三方由node.js内置模块封装出来的,用以提高开发效率的

    2.加载模块

    require()方法

      使用require()方法,用以加载各种模块进行使用

    // 加载内置文件系统模块fs
    const fs = require('fs');
    
    // 加载用户自定义模块
    const ownModule = require('./ownModule.js');
    
    // 加载通过npm安装的第三方日期模块dayjs
    const dayjs = require('dayjs');
    

    3.向外共享模块作用域中的成员

    module对象

      在每个用户自定义模块的.js文件中都有一个module对象,它里面存储了该模块有关的信息。
      通过在自己创建的文件customModule.js中打印module对象输出如下信息:

    PS C:\Users\林木木\Desktop\node\模块化\自定义模块> node .\customModule.js
    Module {
      id: '.',
      path: 'C:\\Users\\林木木\\Desktop\\node\\模块化\\自定义模块',
      exports: {},
      filename: 'C:\\Users\\林木木\\Desktop\\node\\模块化\\自定义模块\\customModule.js',
      loaded: false,
      children: [],
      paths: [
        'C:\\Users\\林木木\\Desktop\\node\\模块化\\自定义模块\\node_modules',
        'C:\\Users\\林木木\\Desktop\\node\\模块化\\node_modules',
        'C:\\Users\\林木木\\Desktop\\node\\node_modules',
        'C:\\Users\\林木木\\Desktop\\node_modules',
        'C:\\Users\\林木木\\node_modules',
        'C:\\Users\\node_modules',
        'C:\\node_modules'
      ]
    }
    

      可见每个自定义模块的module对象中都包含id(模块标识符)、loaded(模块是否加载完成)、path(模块的搜索路径)等属性,我们将重点信息放在它的exports属性上

    module.exports对象

      module的exports属性也是一个对象,我们可以通过module.exports对象,将自定义模块内的部分成员共享出去,供外界使用

    在模块customModule.js中定义如下:

    // 该成员和方法不打算共享出去,具有模块作用域,只能在该模块内访问,避免全局污染
    let fruit = "Apple";
    function sayName(f) {
      return f
    }
    sayName(fruit);
    
    // 该成员和方法将在后面共享出去
    let hobby = 'basketball';
    function sayHobby(h) {
      return h;
    }
    sayHobby(hobby);
    
    // 通过mudule.exports,向外共享成员hobby及方法sayHobby
    module.exports = {
      hobby,
      sayHobby
    }
    '
    运行

    在外部通过require()方法加载该模块:

    const customModule = require('./customModule.js');
    console.log(customModule);      // { hobby: 'basketball', sayHobby: [Function: sayHobby] }
    

    exports对象

      Node提供了exports对象,在默认情况下,exports和module.exports指向同一个对象

    console.log(exports === module.exports);    // true
    '
    运行

      But:最终共享的结果,以module.exports指向的对象为准

    在模块exportsObj.js中定义如下:

    // exports和module.exports指向同一个对象,最终以module.exports暴露的对象为准
    exports.address = 'zzuli';
    exports.sayAddress = function () {
        return this.address;
    }
    module.exports = {
        name: 'lmm'
    }
    '
    运行

    在外部通过require()方法加载该模块:

    const exportObj = require('./exportsObj.js');
    console.log(exportObj);     // { name: 'lmm' }
    

    4.module.exports与exports的使用误区

      若执意要在同一模块中同时使用module.exports和exports两个对象,共享模块内成员时,将有一下几种情况:

    情况一:

    // 向外共享 { gender: '男', age: '21'};
    exports.username = 'lmm';
    module.exports = {
        gender: '男',
        age: 21
    }
    '
    运行

    解释:重写了module.exports对象,也就是module.exports指向了另外一个对象,而exports仍旧指向原来的对象,此时两者不指向同一个对象,根据最终共享的结果,以module.exports指向的对象为准,向外共享 { gender: ‘男’, age: ‘21’}

    情况二:

    // 向外共享 { address: 'zzuli'};
    module.exports.address = 'zzuli';
    exports = {
        height: '172',
        weight: '130'
    }
    '
    运行

    解释:重写了exports对象,也就是exports指向了另外一个对象,而module.exports仍旧指向原来的对象,此时两者不指向同一个对象,根据最终共享的结果,以module.exports指向的对象为准,向外共享 { address: ‘zzuli’}

    情况三:

    // 向外共享 { hobby: 'code', good: 'PingPong'};
    exports.hobby = 'code';
    module.exports.good = 'PingPong'
    '
    运行

    解释:此时两者都未重写,仍然指向同一个对象根据最终共享的结果,以module.exports指向的对象为准(此时也包括exports指向的对象),向外共享{ hobby: ‘code’, good: ‘PingPong’}

    情况四:

    // 向外共享 { sport: 'basketball', fruit: 'Apple', drink: 'Cola'};
    exports = {
        sport: 'basketball',
        fruit: 'Apple'
    }
    module.exports = exports;
    module.exports.drink = 'Cola';
    '
    运行

    解释:重写了exports对象后exports指向新的对象,但后续又修改了module.exports指向的对象为exports指向新的对象,因此二者仍然指向同一个对象,同理,根据最终共享的结果,以module.exports指向的对象为准(此时也包括exports指向的对象),向外共享{ sport: ‘basketball’, fruit: ‘Apple’, drink: ‘Cola’}

    由此建议:不要再同一个模块中同时使用module.exports对象和exports对象

    二、CommonJS模块化规范

      Node.js遵循了CommonJS模块化规范:规定了模块的特征和各模块之间如何相互依赖
    CommonJS规定:

    1.每个模块内部,module变量代表当前模块
    2.module变量是一个对象,它的exports属性(module.exports)是对外的接口;
    3.通过require()加载某个模块,其实是加载该模块的module.exports属性

  • 相关阅读:
    iptables mark 相关用法及使用举例
    江苏移动基于OceanBase稳步创新推进核心数据库分布式升级
    maven的pom.xml文件显示被删除
    (十六)51单片机——红外遥控
    spring5.0 源码解析(day04)registerBeanPostProcessors(beanFactory);
    【UI测试】内容及流程
    亚马逊云科技的AI新引擎,如何助力企业应对“乌卡时代”?
    PHP:命名空间必知必会
    Chapter 09 - NSUndoManager (C#实现 + 全网原创)
    【羊了个羊】什么!第二关难如上青天,能不能简单版??
  • 原文地址:https://blog.csdn.net/m0_53375764/article/details/127037780