requireJS为何不会多次加载同一个文件?怎么理解内部机制?

发布于 2022-09-04 04:45:19 字数 964 浏览 22 评论 0

文件目录如下:

root-|index.html
     |require.js
     |main.js
     |jquery.min.js
     |math.js

index.html:

<head>
  <script type="text/javascript" src="require.js" data-main="main" defer async="true"></script>
</head>

main.js:

require.config({ 
  paths: { 
    "jquery": "jquery.min", 
    "math": "math"
  } 
}); 
require(['jquery','math'], function ($,math){ 
    console.log('main'); 
}); 

math.js:

define(['jquery'],function($){
    console.log('math');
    var add = function(a,b){
        return a+b;
    };
    return{
        add: add
    };
});

在浏览器的Network可以看到加载js的情况:
图片描述

疑问:
main.js模块依赖了jquery模块和math模块,由于异步我视为开了两个线程;第二个math线程又依赖了jquery模块,为何没有再一次请求该资源?requireJS内部机制是怎样的?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小…红帽 2022-09-11 04:45:19

如果你有时间去看看 sea 或者 requirejs 的源码就能明白,其实原理并不复杂。

如果没有显式的指定名称,你的源文件路径(含目录和文件名)就是模块的名称。当然它内部会进行一些处理,使名称能唯一对应一个模块的定义。

那么模块的定义是一个 function,这个 function 实际是一个 factory(工厂模式,不明白的话就去搜下),这个 factory 在需要使用的时候(require("xxxx") 的时候)才有可能会被调用。为什么是有可能?因为如果检查到已经调用过,已经生成了模块实例,就直接返回模块实例,而不再次调用工厂方法了。

这个过程大概是这样的(非常简化的,只是个示意,加载和依赖都忽略了,想了解详情自己去看源码)

class Module {
    constructor(name, factory) {
        this.name = name;
        this.factory = factory;
        this.instance = null;
    }
}

// 非常简化的 define 方法(不要问我依赖的问题)
function define(factory) {
    const name = "";    // 根据源码路径之类的来计算
    // allModules 是框架维护的一个模块字典
    allModules[name] = new Module(name, factory);
}

// 非常简化的 require 方法
function require(name) {
    const module = allModules[name];
    if (!module.instance) {
        const moduleInst = { exports: {} };
        // 如果 factory 有返回值就用返回值赋给 module.instance
        // 否则就用 moduleInst 赋给它
        module.instance = module.factory(moduleInst.exports, moduleInst) || moduleInst;
    }

    return module.instance;
}

对于加载的外部模块也说,也是一样的。尤其是像 jQuery 这些,在写源码的时候已经考虑了兼容 AMD 的问题,所以可以很好的用于 requirejs 依赖加载。

情深缘浅 2022-09-11 04:45:19

不要意思,没用过requireJS,模块化直接从CommonJS开始的。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文