【问题标题】:Anonymous define() module in library's dependencies causes breakage for library's dependents库依赖项中的匿名 define() 模块导致库依赖项损坏
【发布时间】:2015-05-28 17:21:41
【问题描述】:

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

我们发现,如果我们的库依赖于包含匿名定义模块的库,例如来自 lodash来源:

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

我在这个问题上找到了RequireJS documentation;但它的所有解决方案似乎都假设使用匿名模块导入库的库正在使用 RequireJS,而这里并非如此。

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

【问题讨论】:

    标签: javascript requirejs browserify amd


    【解决方案1】:

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

    也许您在 lodash 上使用了 derequire,然后使用 standalone 选项捆绑您的应用程序。

    以下来自Browserify documentation

    opts.standalone 是非空字符串时,独立模块是 用那个名字和一个 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.externalRequireNameexpose 模式下默认为'require' 但您可以使用其他名称。

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

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

    您还可以在 http://www.forbeslindesay.co.uk/post/46324645400/standalone-browserify-builds 找到关于独立选项的好教程

    【讨论】:

    • 我将其标记为“最佳答案”,尽管我尚未对其进行测试。我找到了我刚刚发布的替代解决方案; (尽管很丑)并且不需要寻找替代解决方案,除非我们发现当前解决方案存在问题。但我会假设这是更正确的做法,除非我听到其他情况。
    【解决方案2】:

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

    代码看起来像:

    //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 的独立+derequire,但我想为了完整起见,我会分享我的最终解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-13
      • 2019-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-27
      • 1970-01-01
      相关资源
      最近更新 更多