Requirejs - 通过不同的模块共享相同的依赖项

时间:2013-06-06 16:09:08

标签: javascript requirejs frontend r.js

想象一下这个项目的脚手架:

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

utils.js

define([], function(){  /* My utils functions */ });

模块1 / controllers.js

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

模块2 / controllers.js

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

这在非优化上下文中非常有效,因为utils.js只下载一次,无论是来自module1还是module2。但是,我需要在JS文件中优化和打包每个模块。

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

模块1 / main.js

define(['./controllers', './services.js'], function(){});

现在我开始使用优化工具,这是我的app.build.js

...
modules: [
        { name: "module1/main" },
        { name: "module2/main" },
    ]
...

好的,我得到了我想要的行为,但我发现这两个模块都包含了utils.js代码。这种行为是正确的,因为您无法保证加载顺序。

所以,这些是我的问题:

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

2 个答案:

答案 0 :(得分:4)

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

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

这样我就为utils创建了一个独立的模块,并避免使用“exclude”选项将其包含在其他模块代码中。此方法强制您手动编写此类“全局”依赖项,但它可以工作:)

答案 1 :(得分:1)

不确定你是如何“玩”优化工具的,但是当我有一个基础库(就像我的所有主干扩展),然后是一两个视图时,我就是这样处理的:

基础库:类似'base.js'

define([
'foo',
'bar',
'baz'
]);

第x页的代码:让我们说'x.js'

define([
    'foo',
    'bar'
], function () {

});

根据需要设置'libraryBuild.js'文件和'build.js'文件 - 两者之间的差异在build.js中,你将把'base.js'中定义的所有文件设置为'空'。

libraryBuild.js

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

build.js

({
    baseUrl: ".",
    paths: {
        foo: "empty:",
        bar: "empty:",
        baz: "empty:"
    }
})

现在,运行两次优化(我通过npm安装了requirejs作为全局包,所以我可以调用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-built.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>

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