• Node.js -- 模块化


    这里是引用

    1. 模块化介绍

    之前我们所编写的文件都是单个文件,这就会出现一些问题:

    1. 变量不能重复命名;
    2. 代码复用性差;
    3. 代码可维护性差

    怎么解决这些问题呢?
    就是使用Node.js 模块化!

    将一个复杂的程序文件依据一定规侧(规范)折分成多个文件的过程称之为模块化
    其中拆分出的每个文件就是一个模块,模块的内部数据是私有的,不过模块可以暴露内部数据以便其他模块使用(模块可以理解为功能,只能自己调用自己的功能,但是可以把功能展示给其他人,引导其他人来调用

    模块化项目:编码时是按照模块一个一个编码的,整个项目就是一个模块化的项目

    下面是模块化的一些好处:

    • 防止命名冲突
    • 高复用性
    • 高维护性

    2. 模块化初体验

    me.js

    // 声明一个函数
    function tiemo() {
        console.log('tiemo');
    }
    
    // 暴露数据
    module.exports = tiemo;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    index.js

    // 导入模块
    const tiemo = require('./me.js')
    
    // 调用函数
    tiemo()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3. 模块暴露数据

    1. module.exports 属性
      module.exports = tiemo; // 暴露单个数据;
      module.exports = {tiemo,chifan}; //暴露多个数据
    2. exports变量
      exports.tiemo = tiemo;
      exports.chifan = chifan;

    使用时有几点注意:

    • module.exports可以暴露任意数据
    • 不能使用exports=value的形式暴露数据,模块内部module与exports的隐式关系exports module.exports ={}

    因为存在module与exports的隐式关系exports
    module.exports ={};所以exports.tiemo = tiemo 就像是在给对象设置属性,所以在调用时是可以执行的。

    4. 导入文件(夹)模块

    在模块中使用require 传入文件路径即可引入文件

    const test = require('./me.js')
    
    • 1

    require 使用的一些注意事项:

    1. 对于自己创建的模块,导入路径时建议写相对路径,且不能省略./../;
    2. jsjson文件在导入时可以不用写后缀,c / c++ 编写的node 扩展文件也可以不写后缀,但是一般用不到;
      当出现两个文件名称一样,但是一个是js文件,一个是 json文件,那么会先导入js 文件内容
    3. 如果导入其他类型的文件,会以 js 文件处理;
    4. 如果导入的路径是个文件夹,则会首先检测该文件夹下package.json文件中main属性对应的文件,如果存在则导入,反之如果文件不存在会报错;
      如果main 属性不存在或者package.json 不存在,则会尝试导入文件夹下的index.js 和index.json ,如果还是没找到,就会报错
    5. 导入node.js 内置模块时,直接require 模块的名字即可,无需添加./../,例如:fs, http, path等

    5. 导入模块的基本流程

    这里我们将学习导入自定义模块的基本流程!

    1. 将相对路径转换为绝对路径,定位目标文件;
    2. 缓存检测;
    3. 读取目标文件代码;
    4. 包裹为一个函数并执行(自执行函数)。通过arguments.callee.toString()查看自执行函数;
    5. 缓存模块的值;
    6. 返回module.exports 的值
    // 这部分代码都是伪代码 不能执行 只能帮助理解
    function require (file) {
        // 1. 将绝对路径转换为相对路径 ,定位目标文件
        let absolutePath = path.resolve(__dirname, file)
        // 2. 缓存检测 如果之前执行过这个模块 那么直接会输出模块值 不会再进行下面的操作
        if (cashes[absolutePath]) {
            return caches[absolutePath];
        }
        // 3. 读取文件的代码
        let code = fs.readFileSync(absolutePath).toString();
        // 4. 包裹为一个函数 然后执行
        let module = {}
        let exports = module.exports = {}
        (function(exports,require,module,__filename,__dirname) {
            const test = {
                name: '大富翁'
            }
    
            module.exports = test;
    
            // 输出
            console.log(arguments.callee.toString());
        })(exports, require, module, __filename, __dirname)
        // 缓存结果
        caches[absolutePath] = module.exports
        // 返回module.exports 的值
        return module.exports
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    注:

    1. arguments.callee 指向函数arguments.callee.toString() 可以啊看到函数的代码体;
    2. 被包括起来的函数执行形式:
      (被包裹的函数)(函数实参)

    6. CommonJS 规范

    module.exportsexports以及require这些都是CommonJS模块化规范中的内容。
    而Node,js是实现了CommonJS模块化规范,二者关系有点像JavaScript与ECMAScript

  • 相关阅读:
    【LeetCode:2586. 统计范围内的元音字符串数 | 模拟】
    Facebook广告效果数据获取
    pandas基础语法
    【springboot+vue】原生小程序电子班牌系统 智慧校园云平台源码
    python3.8,torch1.10.2+cu113、torch-geometric 安装
    java 对比文件 md5实现秒传
    图文详解MapReduce工作机制
    基于SpringBoot的校园失物招领系统
    【C++】命名空间深度理解
    写论文的步骤有没有?正确的顺序是什么?
  • 原文地址:https://blog.csdn.net/2302_79523175/article/details/138184520