首页 文章

用于comsumption的自定义Javascript应用程序与require.js:如何避免与优化时的现有库冲突?

提问于
浏览
1

我正在试图找出一种模式来加载Backbone,jQuery和Underscore等公共库的具体版本,以便在任何设计用于插入任何网站的Javascript应用程序中使用它们,而不会与这些库的现有版本冲突 . 使我的代码模块化的首选库是require.js .

该应用程序将被称为Bobby :-)

如果我不将它优化为单个文件,我的代码正在运行 . 将Bobby作为单个Javascript文件提供服务会很好,该文件可以包含在网站的HTML代码中的任何位置 .

我注意到了:我是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文件

bootstrap.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文件放在一个具体的地方 .

我能做什么?谢谢!

P.D . :如果您发现它有用,请随意使用此模式...

1 回答

  • 1

    经过一段时间的睡眠后,我今天早上醒来时想起了 async HTML属性的存在,所以我测试了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>
    

    无论如何,我接受建议代码的建议和答案 .

相关问题