33

我是 RequireJS 的新手。我在 Knockout.js 中编写了许多自定义绑定,并希望使用模块将它们拆分。

目前我的代码布局是:

/
  default.html
  js
    code.js
    require-config.js 
    lib
      /require.js
      bridge
        bridge.js
        bindings1.js
        bindings2.js
        bindings3.js

我想从 default.html 加载 bridge.js 并将其加载到所有绑定文件中。我尝试使用 require 函数使用或内联 js 加载 bridge.js。

我的 require-config 非常简单:

require.config({
    baseUrl: '/'
});

在 bridge.js 中,我在使用相对路径加载文件时遇到问题。我试过了:

require(['./bindings1', './bindings2', './bindings3'], function () {
    console.log('loaded');
});

但这只是使用路径 baseUrl + 'bindings1.js',例如。我在 bridge.js 中尝试了各种迭代。我唯一的成功是如果我写了整个路径:

require(['js/bridge/bindings1', 'js/bridge/bindings2', 'js/bridge/bindings3'], function () {
    console.log('loaded');
});

但这不是我想要的。这似乎是一个非常基本的用例,我想我可能误解了相对路径的工作原理。

谢谢

4

2 回答 2

30

相对 ID 是相对于在其中解析 ID 的模块 ID 解析的。请参阅AMD 规范module id format部分。

有两种方法可以将相对依赖 ID 构建到正确的上下文/范围中:

定义调用

定义调用是“模块”的开始/定义。在调用内请求的所有依赖项的define()范围都在该模块的 ID 内/相对于该模块的 ID。例子:

// does not matter what the file name is.
define(
    'hand/named/module'
    , ['./child']
    , factoryFunction
)

或者

// inside of 'hand/named/module.js' file.
define(
    ['./child']
    , factoryFunction
)

在上述两种情况下,都会根据调用./child定义的模块 ID 进行解析。两种情况下的define()模块 id 都被解析为(+ '.js' 显然,到时候得到它)hand/named/module./childhand/named/child

“范围”要求

您可以require通过覆盖将调用范围从全局更改为本地。您实际上不需要覆盖/保留 name require,这是它所做更改的含义。要求功能成为特定模块的“本地”。

// inside 'hand/named/module.js' file
define(
    ['require']
    , function(myLocalRequire){
        require('./child', function(){
            // outcome A
        })
        myLocalRequire('./child', function(){
            // outcome B
        })
    }
)

在结果 A 中,您继续使用“全局”要求 - 附加到父范围的要求。您./child解析为 baseURL + '/child'

结果 B 是本地范围的,与模块 id 相关联,hand/named/module因此./child被解析为hand/named/child

@CristiPufu 建议使用require仅在该函数范围内的本地对象覆盖全局变量:

// inside 'hand/named/module.js' file
define(
    ['require']
    , function(require){
        return function(){
            // here we have access only to "local" require,
            // since in the function declaration you decided to
            // override the 'require' variable with new object.
            // All code outside of this function will use global require.
            require('./child', function(){
                // outcome B
            })
        }
    }
)

我的偏好是将所有相关资源放在definecall 中。使它们明确而有趣,因为很清楚它们与什么相关。

于 2013-01-29T18:32:53.660 回答
26

在需要配置中使用“包”。这是您问题主题的有效答案

require.config({
packages: [
{ 
    name: 'packagename',
    location: 'path/to/your/package/root',  // default 'packagename'
    main: 'scriptfileToLoad'                // default 'main' 
}]
   ... some other stuff ...
});

在包内部,您将能够使用相对路径。

于 2014-03-21T16:06:11.023 回答