库的依赖关系中的匿名define()模块会导致库的依赖项出现破坏

时间:2015-03-25 06:29:05

标签: javascript requirejs browserify amd

我正在开发一个用于许多Web应用程序的库。库本身不使用RequireJS - 它是在节点中编写的,然后与browserify捆绑在一起 - 但是,它的一些依赖项使用RequireJS填充程序来包含库。

我们发现,如果我们的库依赖于包含匿名定义模块的库(例如来自lodash的这个库),我们的dependents使用的RequireJS垫片会出现“不匹配的匿名define()”错误。源:

// Define as an anonymous module so, through path mapping, it can be
// referenced as the "underscore" module.
define(function() {
  return _;
});

我在这个问题上找到了RequireJS documentation;但是它的所有解决方案似乎都假设使用匿名模块导入库的库使用RequireJS,这不是这种情况。

我如何处理这个问题,以便下游库不需要进行任何特殊处理才能要求我们的库?理想情况下,如果我们不必为每个使用匿名模块定义的库添加自定义逻辑,那就太好了。

2 个答案:

答案 0 :(得分:1)

您可以尝试使用Browserify standalone选项和derequire捆绑您的应用。

也许你在lodash上使用derequire,然后使用standalone选项捆绑你的应用。

以下内容来自Browserify documentation

  

opts.standalone是非空字符串时,独立模块就是   用这个名字和a创建   umd包装器。您可以使用   使用字符串中的.在独立全局导出中命名空间   将名称作为分隔符。例如:'A.B.C'

     

请注意,在独立模式下,require()来自原始呼叫   源仍然存在,这可能会绊倒AMD加载器扫描   用于require()来电。你可以删除这些电话   derequire

     

$ npm install -g derequire $ browserify main.js --standalone Foo | derequire > bundle.js

     

opts.insertGlobalVars将被传递给   insert-module-globals   作为opts.vars参数。

     

opts.externalRequireName默认为'require'模式下的expose   但你可以用另一个名字。

     

请注意,如果文件不包含javascript源代码,那么您也是   需要为它们指定相应的变换。

     

所有其他选项都转发到   module-deps和   直接browser-pack

您还可以在http://www.forbeslindesay.co.uk/post/46324645400/standalone-browserify-builds

找到有关独立选项的精彩教程

答案 1 :(得分:0)

所以我最终做的是将requirejs优化器导入到browserify项目中,并通过requirejs优化器运行包含匿名定义模块的所有文件,然后通过browerify transform函数捆绑它们。 / p>

代码看起来像:

//Kept an explicit list of things to requirejs optimize, to avoid running every file through the optimizer
var modulesToRequireJSOptimize = ["lodash"];
var lib = browserify();
//...
lib.transform(requireJSOptimize, {global: true}); //global true to apply it to the modules

function requireJSOptimize(file) {
    var moduleName;
    //Determine if the file is one of the modules we need to optimize
    modulesToRequireJSOptimize.forEach(function(mod) {
        if(require.resolve(mod) === file) {
            moduleName = mod;
        }
    }
    if(!moduleName) {
         return through(); //do nothing
    }
    var end = function() {
        var pipe = this;
        var optimizerConfig = {
            name: moduleName
            optimize: "none" //don't minify
            paths: {}
            out: function(optimizedJS) {
                this.queue(optimizedJS);
                this.queue(null);
            }
         }
         //strip off .js
         optimizerConfig.paths[moduleName] = file.substr(0, file.length-3)
         requirejs.optimize(optimizerConfig, 
             function() {}, //success handled in optimizerConfig.out
             function(err) {} //handle err here
         );
    };
    return through(function () {}, end);
}

它并不漂亮,但它可以用于我们的目的。我建议其他人先尝试OweR ReLoaDeD的独立+取消,但我认为为了完整起见,我会分享我最终的解决方案。