我试图找出一种模式来加载像 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 文件
索引.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
假设这是第一次加载的内容,所以我在这里为我所有的第 3 方库调用 noConflict()。
require(['app/core', 'app/bobby'], function(core, bobby) {
core._.noConflict();
core.$.noConflict(true);
core.B.noConflict();
bobby.initialize();
});
应用程序/core.js
define(['lib/underscore', 'lib/jquery-1.9.1.min', 'lib/backbone'], function(){
Backbone.$ = jQuery;
return {
_: _,
$: jQuery,
B: Backbone
};
});
应用程序/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 全局安装的 r.js 和 build.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
构建.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:如果你觉得这个模式有用,请随意使用...