node模块加载机制

作者: 我就是L | 来源:发表于2017-03-22 21:36 被阅读51次
    • Node中存在一个module对象代表模块自身,拥有一个exports属性,一个文件就是一个模块。

    • 每个js文件可以独立一个环境是因为node自动封装了一层自执行

    (function (exports, module, __dirname, __filename, require) {
    });
    
    • 核心模块:Node提供的模块,在Node进程启动时直接加载进内存

    • 文件模块:用户编写的模块,运行时动态加载,需要完整经历路径分析文件定位编译执行

    • 模块每次被加载后都会缓存起来以供下次使用

    • 加载优先级 .js > .json > .node

    • question?

    • 文件A中定义的全局变量在文件B中是否可以访问?yes,当然可以访问

    • 文件循环依赖问题?循环依赖

    • exports=module.exports

    // -------- node.js core --------
    var module = {
      exports: {
      }
    };
    exports = module.exports;
    // -------- 下面正常写代码 --------
    exports.name = 'Alan';
    exports.test = function () {
      console.log('hi')
    };
    // 给导出的对象添加属性,直接这样就好了
    console.log(module) // { exports: { name: 'Alan', test: [Function] } }
    exports = {
      name: 'Bob',
      add: function (a, b) {
        return a + b;
      }
    }
    // 不过 ① exports 是一个引用,直接赋值给它,只是让这个变量等于另外一个引用
    console.log(exports) // { name: 'Bob', add: [Function] }
    // 并不会修改到导出的对象
    console.log(module) // { exports: { name: 'Alan', test: [Function] } }
    module.exports = {
      name: 'Bob',
      add: function (a, b) {
        return a + b;
      }
    }
    // ∵① 所以 只有通过 module.exports 才能真正修改到 exports 本身
    console.log(module) // { exports: { name: 'Bob', add: [Function] } }
    

    热更新
    如何在不重启进程的情况下更新执行代码?
    Node中即使把js文件修改了,由于require cache会有缓存,所以还是会执行旧代码,想要实现热更新首先就要更新require cache,但是如果有一些在文件更新时存有引用,则会被保留下来,依然还会有旧代码在执行....

    如果仅仅是更新配置文件呢?
    其实配置文件需要热更新的话完全可以存数据库,前端写个界面操作下即可。

    const path = require('path');
    const fs   = require('fs');
    const _    = require('lodash');
    function _require(_path, interval = 3000) {
        const _clone = function (tar, src) {
            for (var f in src) {
                if (src.hasOwnProperty(f)) {
                    console.log(f, '-->' + src[f])
                    tar[f] = src[f];
                }
            }
            for (f in tar) {
                if (!src.hasOwnProperty(f)) {
                    delete tar[f];
                }
            }
        };
        const absolutePath = path.resolve(_path);
        let module         = require(absolutePath);
        setInterval(function () {
            delete require.cache[absolutePath];//接触缓存中require对.js module的引用关系。
            const updateModule = require(absolutePath);//重新加载.js module模块
            _clone(module, updateModule)//老模块的导出对象与新数据建立引用关系
        }, interval);
        return module;
    }
    

    相关文章

      网友评论

        本文标题:node模块加载机制

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