在同一页面中加载两次时需要JS冲突

requirejs conflict when loading twice in the same page

本文关键字:两次 冲突 JS 一页 加载      更新时间:2023-09-26

我正在将requirejs加载到这样的页面中:

<script src="components/requirejs/require.js" data-main="js/main"></script>

然后,我在外部脚本上的函数中还有另一个requirejs代码,我将其加载到同一页面中(因为它是使用requirejs的小部件)。问题是第二个要求是从第一个需求中获取配置。在我看来,全局范围存在冲突,我不理解,因为requirejs代码被封装到函数中。

有什么难点吗?

requirejs 加载两次到同一页面而不会搞砸事情的最佳方法是什么?

大约一年前,我实际上遇到了类似的问题,我设法解决了这个问题。

你需要的是需要JS的上下文。 在需要运行的页面上,弹出开发工具并键入以下内容:

require.s.contexts

您应该看到的是一个具有一个属性的对象,_:这是默认上下文。 您需要的是运行两个完全独立的 require 实例或两个上下文。 一小部分示例代码,您可以将其替换为:

var requireContextOne = require.config({
    context: 'contextOne',
    baseUrl: 'whatever',
    /* THE REST OF YOUR FIRST CONFIG */
});
var requireContextTwo = require.config({
    context: 'contextTwo',
    baseUrl: 'whatever',
    /* THE REST OF YOUR SECOND CONFIG */
});
//Start both your contexts
(function(){
    //Remember to pass "require" as the first variable, otherwise you'll get all sorts of errors!
    requireContextOne(['require', 'topModule'], function(require, topModule){
        topModule.initialize();
    });
    //Your second context - even if you load the same module, it will be a separate "instance" from the one used in the first context
    requireContextTwo(['require', 'topModule'], function(require, topModule, anotherModule){
        topModule.initialize( anotherModule.start() );
    });
})();

现在,如果您在控制台中运行require.s.contexts,您将看到您有两个上下文:"上下文一"和"上下文二"。 此外,如果您键入类似 require.s.contexts.contextOne.defined 的内容,则可以查看该特定上下文已加载的所有模块。

编辑了对@jplozano评论的长镜头建议回应

//Your widget's main file
define(function() {
    var widgetRequireContext = require.config({
        context: 'myWidget',
        baseUrl: 'whatever',
        /* THE REST OF YOUR WIDGET CONFIG */
    });
    //Note that I use "requirejs", not "require," to ensure we keep the reference to global variable
    widgetRequireContext(['require', 'submodule/a', 'submodule/b'], function(requirejs, subA, subB){
        /* THE REST OF YOUR MAIN MODULE CODE IS WRAPPED IN HERE */
    });
});

不要加载 require.js两次。如果您的库内部具有AMD模块,则可以附带杏仁的嵌入式副本.js则可以代替。杏仁是为这种用法而设计的,它是由与Require.js相同的作者设计的。

这将允许您在全局级别拥有模块(由 Require.js 加载),并且这些模块本身可以在内部由内部/私有模块组成。