如何规避RequireJS加载全局模块?

Web*_*ner 7 javascript amd global-variables dynamic-script-loading requirejs

我正在尝试从书签中加载JS文件.JS文件有这个包装模块的JS:

(function (root, factory) {
    if (typeof module === 'object' && module.exports) {
        // Node/CommonJS
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(factory);
    } else {
        // Browser globals
        root.moduleGlobal = factory();
    }
}(this, function factory() {
    // module script is in here

    return moduleGlobal;
}));
Run Code Online (Sandbox Code Playgroud)

因此,如果网页使用RequireJS,则脚本在加载时不会导出全局.为了解决这个问题我暂时设置definenull,加载脚本,然后重置define为其原始值:

function loadScript(url, cb) {
    var s = document.createElement('script');
    s.src = url;
    s.defer = true;
    var avoidRequireJS = typeof define === 'function' && define.amd;
    if (avoidRequireJS) {
        var defineTmp = define;
        define = null;
    }
    s.onload = function() {
        if (avoidRequireJS) define = defineTmp;
        cb();
    };
    document.body.appendChild(s);
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,但在我看来,当应用程序的其他部分可能依赖于它时,更改全局变量可能会有问题.有没有更好的方法来解决这个问题?

Dhe*_*.S. 5

您可以取出使用脚本XMLHttpRequestjQuery.ajax或新的FetchAPI。

这将允许您define在执行脚本之前操作脚本并重新分配。两种选择:

  1. 通过使用以下内容包装脚本,让模块导出一个全局变量:

    (function(define){ ... })(null);
    
    Run Code Online (Sandbox Code Playgroud)
  2. 通过将脚本包装为自己处理模块导出:

    (function(define, module){ ... })((function() {
        function define(factory) {
            var exports = factory();
        }
        define.amd = true;
        return define;
    })());
    
    Run Code Online (Sandbox Code Playgroud)

然后,您可以使用新<script>元素或eval.

请注意,在使用 XHR 时,您可能必须解决CORS问题。