1

バックボーン、jQuery、アンダースコアなどの一般的なライブラリの具体的なバージョンをロードして、それらのライブラリの既存のバージョンと競合することなく、任意の Web サイトにプラグインするように設計された Javascript アプリケーションでそれらを使用するパターンを見つけようとしています。コードをモジュール化するために選んだライブラリはrequire.jsです。

アプリはボビーと呼ばれます:-)

単一のファイルに最適化しなければ、私のコードは機能しています。サイトの HTML コードのどこにでも含めることができる単一の Javascript ファイルとして Bobby を提供するとよいでしょう。

私はそれに気づきました:私はrequire.jsの初心者です。

ディレクトリ構造

ファイルは次のように編成されています。

bobby
  public
    js
      app -> My custom JS
        bobby.js
        core.js

      lib -> 3rd party JS
        backbone.js
        jquery-1.9.1-min.js
        require.js
        underscore.js

      bootstrap.js -> Main file for require.js
      build.js -> To create js/bobby.js

    index.html -> uses non-optimized version
    index2.html -> uses optimized version (js/bobby.js)

HTML ファイル

index.html

ここでは、サイトのライブラリが自分のバージョンで上書きされないようにしています。

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Bobby</title>
  <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
  <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.3/underscore-min.js"></script>
  <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.10/backbone-min.js"></script>

  <script type="text/javascript" src="js/lib/require.js" data-main="js/bootstrap.js"></script>

  <script type="text/javascript">
  jQuery(function($){
    console.log("Host's jQuery: " + $.fn.jquery); // Should be 1.7.2
    console.log("Host's Underscore: " + _.VERSION); // Should be 1.4.3
    console.log("Host's Backbone: " + Backbone.VERSION); // Should be 0.9.10
    console.log("Host's Backbone's jQuery: " + Backbone.$.fn.jquery);
  });
  </script>
</head>
<body>
  <p>HOLA!</p>
</body>
</html>

このファイルをロードすると、コンソール ログは正しくなります。

Host's jQuery: 1.7.2 index.html:23
Host's Underscore: 1.4.3 index.html:24
Host's Backbone: 0.9.10 index.html:25
Host's Backbone's jQuery: 1.7.2 index.html:26
Bobby's jQuery: 1.9.1 bobby.js:3
Bobby's Underscore: 1.4.4 bobby.js:4
Bobby's Backbone: 1.0.0 bobby.js:5

index2.html

これが問題のバージョンです。このファイルは最適化されたバージョンを使用しています。それ以外の:

<script type="text/javascript" src="js/lib/require.js" data-main="js/bootstrap.js"></script>

それは使用しています:

<script type="text/javascript" src="js/bobby.js"></script>

また、コンソール ログは正しくありません。

Host's jQuery: 1.9.1 index2.html:14
Host's Underscore: 1.4.4 index2.html:15
Host's Backbone: 1.0.0 index2.html:16
Host's Backbone's jQuery: 1.9.1 index2.html:17
Bobby's jQuery: 1.9.1 bobby.js:11
Bobby's Underscore: 1.4.4 bobby.js:11
Bobby's Backbone: 1.0.0 bobby.js:11

ただし、コンソールでこれを実行すると:

$.fn.jquery => "1.7.2"
bobby.$.fn.jquery => "1.9.1"

大丈夫です。以下と同じ:

Backbone.VERSION => "0.9.10"
bobby.B.VERSION => "1.0.0"

と:

_.VERSION => "1.4.3"
bobby._.VERSION => "1.4.4"

js/bobby.js が含まれた直後に実行されるスクリプトでのみ失敗します。そのスクリプトは、不適切なバージョンのライブラリ (サイトのものではなく外部) を使用しています。

JS ファイル

ブートストラップ.js

これが最初にロードされると想定されるため、ここですべてのサードパーティ ライブラリに対して noConflict() を呼び出します。

require(['app/core', 'app/bobby'], function(core, bobby) {
    core._.noConflict();
    core.$.noConflict(true);
    core.B.noConflict();

    bobby.initialize();
});

app/core.js

define(['lib/underscore', 'lib/jquery-1.9.1.min', 'lib/backbone'], function(){
    Backbone.$ = jQuery;
    return {
        _: _,
        $: jQuery,
        B: Backbone
    };
});

app/bobby.js

define(['app/core'], function(core){
    var initialize = function() {
        console.log("Bobby's jQuery: " + core.$.fn.jquery);
        console.log("Bobby's Underscore: " + core._.VERSION);
        console.log("Bobby's Backbone: " + core.B.VERSION);

        core.$('body').html('Bobby initialized!');

        window.bobby = core._.extend(window.bobby || {options: {}}, core);
    };

    return {
        'initialize': initialize
    };
});

最適化されたバージョン

npm と build.js ファイルを介してグローバルにインストールされた r.js を使用します。

cd bobby/public/js
r.js -o build.js

そしてそれは与えます:

Tracing dependencies for: /path/to/bobby/public/js/bobby.js
Uglifying file: /path/to/bobby/public/js/bobby.js

/path/to/bobby/public/js/bobby.js
----------------
/path/to/bobby/public/js/lib/require.js
/path/to/bobby/public/js/lib/underscore.js
/path/to/bobby/public/js/lib/jquery-1.9.1.min.js
/path/to/bobby/public/js/lib/backbone.js
/path/to/bobby/public/js/app/core.js
/path/to/bobby/public/js/app/bobby.js
/path/to/bobby/public/js/bootstrap.js

build.js

既存の require.js ライブラリとの競合を避けるために、bob内に名前空間を含めました。

({
    baseUrl: ".",
    out: "bobby.js",
    paths: {
        requireLib: 'lib/require'
    },
    include: ["requireLib", "bootstrap"],
    namespace: "bob"
})

助けが必要

bobby.js は初期化後にうまく機能し、グローバルを元のライブラリに返しますが、実行すると機能しません。

<script type="text/javascript">
jQuery(function($){
  ...
});
</script>

最適化された bobby.js ファイルをロードした直後。

この考えは、サイトの所有者に bobby.js ファイルを具体的な場所に配置することを強制するものではありません。

私に何ができる?ありがとう!

PD: このパターンが役に立つと思ったら、自由に使ってください...

4

1 に答える 1

1

少し寝た後、今朝目が覚めたらasyncHTML 属性の存在を思い出していたので、Google がトラッキング コードをロードするために使用しているのと同じスニペットをテストしたところ、うまくいきました。

<script type="text/javascript">
  (function() {
    var bb = document.createElement('script');
    bb.src = 'js/bobby.js';
    bb.setAttribute('async', 'true');
    document.documentElement.firstChild.appendChild(bb);
  })();
</script>

とにかく、提案されたコードに対する提案と回答を受け入れています。

于 2013-04-08T07:36:08.593 に答える