Javascript Requirejs-通过不同的模块共享相同的依赖关系

Javascript Requirejs-通过不同的模块共享相同的依赖关系,javascript,requirejs,frontend,r.js,Javascript,Requirejs,Frontend,R.js,想象一下这个项目: utils.js module1/controllers.js 模块1/services.js module2/controllers.js 模块2/services.js utils.js define([], function(){ /* My utils functions */ }); module1/controllers.js define(['../utils'], function(utils){ /* Module1 stuff */ }); d

想象一下这个项目:

  • utils.js
  • module1/controllers.js
  • 模块1/services.js
  • module2/controllers.js
  • 模块2/services.js
utils.js

define([], function(){  /* My utils functions */ });
module1/controllers.js

define(['../utils'], function(utils){  /* Module1 stuff */ });
define(['../utils'], function(utils){  /* Module2 stuff */ });
module2/controllers.js

define(['../utils'], function(utils){  /* Module1 stuff */ });
define(['../utils'], function(utils){  /* Module2 stuff */ });
这在非优化上下文中非常有效,因为utils.js只下载一次,无论是从module1还是module2下载。但是,我需要优化每个模块并将其打包到一个JS文件中

为了实现这一点,我在每个模块中添加了一个main.js文件,例如:

module1/main.js

define(['./controllers', './services.js'], function(){});
现在我开始玩优化工具,这是我的app.build.js

...
modules: [
        { name: "module1/main" },
        { name: "module2/main" },
    ]
...
好的,我得到了我想要的行为,但是我看到两个模块都包含utils.js代码。这种行为是正确的,因为您不能保证装载顺序

因此,以下是我的问题:

  • 是否存在任何智能解决方案
  • 如果这不能跳过,有人知道requirejs在引擎盖下是如何工作的吗?这种策略会产生任何问题吗

  • 不确定您是如何“玩”优化工具的,但以下是当我有一个基本库(就像我所有的主干扩展)和一个或两个视图时如何处理它:

    基本库:类似于“Base.js”

    define([
    'foo',
    'bar',
    'baz'
    ]);
    
    第x页的代码:让我们说“x.js”

    define([
        'foo',
        'bar'
    ], function () {
    
    });
    
    根据需要设置“libraryBuild.js”文件和“build.js”文件-两者的区别在于build.js,您将“base.js”中定义的所有文件设置为“empty”

    libraryBuild.js

    ({
        baseUrl: ".",
        name: "base",
        out: "base-built.js"
    })
    
    build.js

    ({
        baseUrl: ".",
        paths: {
            foo: "empty:",
            bar: "empty:",
            baz: "empty:"
        }
    })
    
    现在,运行优化两次(我已经将requirejs作为一个全局包通过npm安装,所以我可以直接调用r.js-否则它将是
    node../path/to/r.js

    r.js-o libraryBuild.js

    r.js-o build.js name=x out=x-optimized.js
    (请注意,您可以将此应用于整个项目,而不仅仅是单个文件..但这是目前更好的示例)

    您应该注意到,“x-optimized.js”文件不包含在base-build.js中设置的代码

    那么,在你的页面中

    <script>
    require.config({
        paths: {
            base: "base-built"
        }
    });
    require(['base'], function () {
        require(['x'], function (x) {
            //The stuff you'd normally do when X is included
        })
    });
    </script>
    
    
    require.config({
    路径:{
    基地:“基地建成”
    }
    });
    require(['base'],function(){
    require(['x'],函数(x){
    //当X包含在内时,你通常会做的事情
    })
    });
    

    我相信有更好的方法可以做到这一点,但这至少可以起作用并保持文件大小较小。

    最后,我使用构建脚本中的排除选项得到了答案:

    ...
    modules:[
      { name: 'utils' },
      { name: 'module1/main', exclude: ['utils'] }
      { name: 'module2/main', exclude: ['utils'] }
    ]
    ...
    

    通过这种方式,我为UTIL创建了一个单独的模块,并避免使用“exclude”选项将其包含在其他模块代码中。此方法强制您手动编写此类“全局”依赖项,但它很有效:)

    谢谢您的回复,Stephen,但我不确定这是我想要的……我已用更多信息编辑了我的问题:)