美文网首页
Node.js 模块化

Node.js 模块化

作者: 北piao青年 | 来源:发表于2020-06-29 21:54 被阅读0次

    Node.js采用的是CommonJs规范,在NodeJS中,一般将代码合理拆分到不同的JS文件中,每一个文件就是一个模块,而文件路径就是模块名。在编写每个模块时,都有require、exports、module三个预先定义好的变量可供使用。

    Node.js中模块的分类:

    • 核心模块(已经封装好的内置模块);
    • 自己定义的模块;
    • 第三方的模块(npm下载下来的);

    require

    require函数用来在一个模块中引入另外一个模块。传入一个模块名,返回一个模块导出对象。用法:let cc = require("模块名") ,其中模块名可以用绝对路径也可以用相对路径,模块的后缀名.js可以省略。例如:

    let cc1 = require('./main.js')
    let cc2 = require('home/src/main.js')
    let cc3 = require('./main')
    

    require()函数用两个作用:

    • 执行导入的模块中的代码;
    • 返回导入模块中的接口对象;

    exports

    exports对象用来导出当前模块的公共方法或属性,别的模块通过require函数使用当前模块时得到的就是当前模块的exports对象。用法:exports.name,name为导出的对象名。例子:

    exports.add = function () {
      let i = 0
      console.log(++i)
    }
    

    导出一个add方法供其他模块使用

    其实exports类似于ES6中的export的用法,用来导出一个指定名字的对象。

    <a name="nq5sp"></a>

    module.exports

    module.exports用来导出一个默认对象,没有指定对象名,常见于修改模块的原始导出对象。比如原本模块导出的是一个对象,我们可以通过module.exports修改为导出一个函数。如下:

    module.exports = function () {
      console.log('hello world!')
    }
    

    <a name="R8ssw"></a>

    模块的初始化

    一个模块中的JS代码仅在模块第一次被使用时执行一次,并且在使用的过程中进行初始化,之后缓存起来便于后续继续使用。

    主模块

    通过命令行参数传递给NodeJS以启动程序的模块被称为主模块。主模块负责调度组成整个程序的其它模块完成工作。例如通过以下命令启动程序时,main.js就是主模块。

    $ node main.js // 运行main.js启动程序,main.js称为主模块
    

    完整实例:在项目中我们有个hello.js文件,里面定义了一个求和的函数

    var a = 1;
    function add () {
      return ++a;
    }
    exports.add = add
    

    我们在项目的主模块 main.js中引入hello.js

    var add1 = require('./hello')
    var add2 = require('./hello')
    console.log(add1.add())
    console.log(add2.add())
    

    该程序运行的结果如下:

    $ node main.js
    

    我们可以看到hello.js并没有别引入两次而初始化两次,说明模块只会在执行的过程中被初始化一次。

    <a name="tOnaO"></a>

    module.exports和exports的区别

    Node中,每个模块都有一个exports接口对象,我们需要把公共的方法或者字符串挂载在这个接口对象中,其他的模块才可以使用。

    Node.js中只有模块作用域,默认两个模块之间的变量,方法互不冲突,互不影响,这样就导致一个问题,我们怎样使用加载进来的模块中的方法呢?这就需要在另外一个模块exports接口对象中挂载模块中公共的方法。

    <a name="EBCCc"></a>

    exports

    我们在a.js中有以下代码:

    let foo = 'hello'
    function add (x, y) {
      return x+y
    }
    exports.add = add // 在接口对象中挂载公共的add方法
    exports.foo = foo // 在接口对象中挂载foo属性
    

    此时,在b.js中如果需要使用add方法,只需引入a.js即可。b.js代码如下:

    let a = require('./a.js')  // a.js和b.js在同级目录下,注意:同级目录必须加“./”
    console.log(a.add(20,30)) // 使用a.js中的add方法
    

    相反,如果我们没有在a.jsexports接口对象中挂载add方法,那么这里就得不到结果。

    module.exports

    对于1中的例子,我们同样可以利用module.exports来写,只需把暴露的方式改成如下:

    module.exports.add = add  
    module.exports.foo = foo
    

    <a name="qfbTv"></a>

    总结

    exports.a = a;
    module.exports.b = b;
    //系统默认exports指向了module.exports, 系统会先找module.exports这个对象
    //exports = module.exports;
    
    //使用exports时,只能单个设置属性;
    //使用module.exports可以单个设置属性,也可以整个赋值
    
    1. Node中每个模块都有一个module对象,module对象中的有一个exports属性为一个接口对象,我们需要把模块之间公共的方法或属性挂载在这个接口对象中,方便其他的模块使用这些公共的方法或属性。
    2. Node中每个模块的最后,都会return: module.exports
    3. Node中每个模块都会把module.exports指向的对象赋值给一个变量exports,也就是说:exports = module.exports
    4. module.exports = XXX,表示当前模块导出一个单一成员,结果就是XXX。
    5. 如果需要导出多个成员时必须使用exports.add = XXX; exports.foo = XXX;或者使用module.exports.add = XXX; module.export.foo = XXX;

    相关文章

      网友评论

          本文标题:Node.js 模块化

          本文链接:https://www.haomeiwen.com/subject/hvtzfktx.html