web-dev-qa-db-ja.com

RequireJS相対パス

私は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関数を使用してaまたはインライン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');
});

しかし、それは私が望むものではありません。これは非常に基本的なユースケースのように思われ、相対パスがどのように機能するかを誤解していると思います。

ありがとう

31
Szymon Rozga

相対IDは、IDが解決されるモジュールIDに関連して解決されます。 AMD spec の_module id format_セクションを参照してください。

相対依存関係IDを正しいコンテキスト/スコープにフレーム化するには、2つの方法があります。

コールを定義する

定義呼び出しは、「モジュール」の開始/定義です。 define()呼び出し内で要求されるすべての依存関係は、そのモジュールの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
)
_

上記のどちらの場合でも、define()呼び出しで定義されたモジュールIDに対して_./child_が解決されます。両方の場合のモジュールIDは_hand/named/module_であり、_./child_は_hand/named/child_に解決されます(明らかに、取得するときが来ると「.js」)

「スコープ」が必要

require呼び出しのスコープをオーバーライドして、グローバルからローカルに変更できます。実際には、名前requireをオーバーライド/保持する必要はありません。これは、変更内容の意味です。 require機能は、特定のモジュールに対して「ローカル」になります。

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

そこで、結果Aで「グローバル」requireを使用し続けます-これは親スコープにアタッチされています。 _./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
            })
        }
    }
)
_

私の好みは、すべての相対リソースをdefine呼び出し内に配置することです。それらが相対的なものであることが明確であるため、それらを明示的かつ明快にします。

28
ddotsenko

Require configで「パッケージ」を使用します。ここであなたの質問に対する有効な答え topic

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

パッケージ内では、相対パスを使用できます。

26
Dmitry Masley