• Node.js学习一 —— 模块化


    模块化

    (题外话,此系列默认您已有一些JS基础以及代码经验,关于nodejs的冗余介绍都被省略了,就从模块化开始吧)

    加载模块

    ​ JS 并没有“脚本间贡献全局命名空间”这一特性。一旦JS代码被载入网页,就会添加进入全局命名空间。全局命名空间是被所有已载入的脚本所贡献的通用地址空间,这样不免会有一些安全问题、冲突以及一些难以跟踪和解决的一般性错误。

    ​ 不过,Node为服务器端的JS制定了一些规范,并且实现了CommonJS模块标准。这样,每个模块都拥有一个上下文来将其他模块隔离开,这意味着没有全局污染(根本就没有全局作用域)。

    如何加载模块

    ​ Node中可以用文件路径也可以用名称来引用模块。如果不是核心模块,使用名称引用的模块都会被映射成文件路径(即等价)。

    ​ 不管什么模块,都可以使用require函数 引入:

    var module = require('module_name')
    
    • 1

    ​ 导入一个模块将返回一个对象。该对象表示模块对外暴露的API,根据模块不同,该对象可能是任意的JS值:函数、对象…

    导出模块

    ​ 在Node中,CommonJS模块系统是文件之间共享对象、数据、函数等等之类的唯一方式。

    ​ 在Node中,文件和模块是一一对应的。

    ​ Feudalman.js文件:

    function feudalman(x,y) {
        function add (x,y) {
            return x + y;
        }
        function sub (x,y) {
            return x - y;
        }
    }
    
    module.exports = feudalman;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    ​ 重点在于最后一行:module是一个变量,表示模块自身。而module.exports表示导出的对象(可以是任意对象)。module初始被定义为一个空对象。

    ​ 还可以导出多个对象:

    module.exports.add = feudalman.add;
    module.exports.sub = feudalman.sub;
    
    • 1
    • 2

    ​ 此时如果需要使用,则这么写(同目录下文件):

    const mod = require('./Feudalman');
    const res1 = mod.add(1,1);
    const res2 = mod.sub(1,2);
    
    • 1
    • 2
    • 3

    加载模块

    ​ 引用模块的方式取决于模块类型——核心模块、第三方模块、本地模块。

    核心模块

    ​ 核心模块只能通过模块名引用。如果有同名模块,核心模块加载优先级更高。

    ​ 例如,如果想加载http模块:

    const http = require("http");
    
    • 1

    文件模块

    ​ 可以提供绝对路径从系统文件中加载非核心模块,如:

    const x = require('/home/node/my_module/my_module');
    
    • 1

    ​ 或者也可以使用相对路径定位项目中的模块,如上面引入Feudalman所写。

    ​ 注意,可以省略模块文件的拓展名.js,如果没有找到该文件,Node会在文件名后自己加上拓展名查找。

    加载文件夹模块

    ​ 还可以使用文件夹路径加载模块:

    const x = require('./myModule');
    
    • 1

    ​ Node会假定该文件夹是一个包,并试图查找配置文件package.json

    ​ 如果没有配置文件,会默认入口为index.js

    ​ 相反,如果存在配置,就会解析配置文件找到入口。这个后面会讲到。

    node_modules文价夹加载

    ​ 如果require传参不是上面的任何一种,那么Node就会尝试在当前目录下的node_modules下查找模块。如果没有找到,会自动去父级文件夹的node_modules中查找,直到根目录。

    ​ npm会自动帮你管理,所以不用操心包到底怎么放。

    缓存模块

    ​ 模块在首次加载时会被缓存起来,这意味着如果模块名能被解析为相同的文件名,那么每次调用require('myModule')都会返回同一模块。

    ​ 举个例子就能理解了:

    ​ 创建一个模块,内容为:

    console.log("init");
    module.exports = function () {
        console.log("export!");
    }
    console.log("exported!");
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ​ 然后加载一次模块:

    const myModule = require('./myModule');
    
    • 1

    ​ 会输出initexported

    ​ 而加载两次:

    const myModule = require('./myModule');
    const myModule = require('./myModule');
    
    • 1
    • 2
    最终发现打印结果和上面一模一样,也就是说,不会重复多次初始化同一个模块。
    
    • 1

    小结:

    1. Node取消了JS默认的全局命名空间,而用CommonJS系统代替。
    2. 不同的模块require的不同传参
    3. 如何引用并使用模块
    
    • 1
    • 2
    • 3
  • 相关阅读:
    连接云服务器Docker中的Mysql 详细图文操作(全)
    [附源码]Java计算机毕业设计SSM动漫周边e商城
    Mysql的存储引擎
    ElasticSearch之搜索词提示Sug
    js 中 Map 和 Set 的用法及区别
    JAVA后端服务端与移动端客户端高精度时间同步思路
    01-国产MCU兆易GD32实现矩阵按键扫描
    PHP:异常
    Flutter:改变手机状态栏颜色,与appBar状态颜色抱持一致
    程序员基本功代码
  • 原文地址:https://blog.csdn.net/qq_51574759/article/details/126707094