我使用require JS并想知道使用CDN版本的jQuery的最佳方法.我听说1.7版本是"AMD",应该有所帮助,但找不到直接的例子.希望一些RequireJS大师可以帮助我.
我们在开发过程中喜欢RequireJS和AMD,我们可以编辑模块,在浏览器中点击重新加载,然后立即看到结果.但是,当需要将我们的模块连接到单个文件进行生产部署时,显然必须有一个AMD加载器仍然存在,无论该加载器是RequireJS本身还是其较小的合作伙伴"杏仁",如下所述:
http://requirejs.org/docs/faq-optimization.html#wrap
我的困惑是:为什么装载机是必需的?除非你有非常特殊的情况使你有必要require()在你的模块内部进行调用,否则似乎可以连接一系列AMD模块而不需要加载器.最简单的例子是一对模块,如下所示.
ModA.js:
define([], function() {
return {a: 1};
});
Run Code Online (Sandbox Code Playgroud)
ModB.js:
define(['ModA'], function(A) {
return {b : 2};
});
Run Code Online (Sandbox Code Playgroud)
鉴于这两个模块,似乎连接器可以简单地生成以下文本,而不会使生产服务器或浏览器承受RequireJS或Almond所需的额外带宽或计算.
我想象一个产生的连接器(我使用V形符号«,»来显示上面两个模块的片段插入位置):
(function() {
var ModA = «function() {
return {a: 1};
}»();
var ModB = «function(A) {
return {b : 2};
}»(ModA);
return ModB;
})();
Run Code Online (Sandbox Code Playgroud)
据我所知,这可以正确地重现AMD的语义,只需要少量的外来胶水JavaScript.有这样的连接器吗?如果没有,我会因为认为我应该写一个而变得愚蠢 - 是否真的很少有代码库由简单而干净的模块组成,define()并且永远不需要进一步的require()调用来启动以后的异步代码提取?
RequireJS 文档说,要支持旧版本的IE,您需要进行配置enforceDefine: true.
因此,如果您想支持Internet Explorer,捕获加载错误,并通过直接的define()调用或shim配置获得模块化代码,请始终将enforceDefine设置为true.有关示例,请参阅下一节.
注意:如果你设置enforceDefine:true,并且使用data-main =""来加载主JS模块,那么主JS模块必须调用define()而不是require()来加载它需要的代码.主JS模块仍然可以调用require/requirejs来设置配置值,但是对于加载模块,它应该使用define().
由于Twitter Bootstrap不是AMD模块,我需要使用它来使其工作.这是我配置它的方式;
<script type="text/javascript">
var require = {
paths: {
"bootstrap": "../bootstrap",
"jquery": "../jquery-1.8.2"
},
shim: {
"bootstrap": ["jquery"]
},
enforceDefine: true
};
</script>
Run Code Online (Sandbox Code Playgroud)
后来当我的模块想要bootstrap作为依赖项时,我仍然得到一条错误消息;
Error: No define call for bootstrap
Run Code Online (Sandbox Code Playgroud)
http://requirejs.org/docs/errors.html#nodefine
如果我理解正确的文档,enforceDefine应该忽略垫片,但事实并非如此.
我在这做错了什么?
我们可以通过给它命名来在requireJS中创建一个模块:
define("name",[dep],function(dep) {
// module definition
});
Run Code Online (Sandbox Code Playgroud)
或者我们可以创建一个不包括名称:
define([dep],function(dep) {
// module definition
});
Run Code Online (Sandbox Code Playgroud)
哪个是创建模块的更好方法?我知道RequireJS建议避免分配模块名称.
但我想知道我们在什么场景下做,而不必给模块命名.这会影响使用吗?每种方式的优点和缺点是什么?
我想使用一个单独的域作为JavaScript框架,它将创建一个基本需求配置,我可以从应用程序增加.
foo.example.com
main.js
lib/foo-specific.js
framework.example.com
framework.js <-- entry point
lib/jquery.js
lib/etc...
Run Code Online (Sandbox Code Playgroud)
最好的情况是,我希望能够要求'lib/foo-specific'和/或'lib/jquery',并且路径可以很好地解决,但是从我发现的,没有办法做到这一点,除非我为框架中的每个js文件使用特定的路径键/值.目前,我有一个自定义插件来加载具有不同基本URL的给定路径(例如fw!lib/jquery),但是如果我想使用该text!插件,它将无法工作,因为不支持插件链接.
有关我目前的内容,请参阅https://github.com/jpillora/js-framework,以及https://github.com/jpillora/prettyprinter了解用例.
有没有一个干净的方法来解决这个问题?或者实现多个基本URL?
注意:我也查看了多个require实例,但我认为这不会起作用,因为我希望应用程序能够访问框架的配置.
我可以伸展RequireJS为我的应用程序提供依赖注入多少?举个例子,假设我有一个我希望成为单身人士的模特.自执行getInstance()中不是单例 - 类型单例,而是上下文强制单例(每个"上下文"一个实例).我想做点什么......
require(['mymodel'], function(mymodel) {
...
}
Run Code Online (Sandbox Code Playgroud)
并让mymodel成为MyModel类的一个实例.如果我要在多个模块中执行此操作,我希望mymodel是相同的共享实例.
我已经通过制作mymodel模块成功完成了这项工作:
define(function() {
var MyModel = function() {
this.value = 10;
}
return new MyModel();
});
Run Code Online (Sandbox Code Playgroud)
这种用法是预期和常见的还是我滥用RequireJS?有没有更合适的方法可以使用RequireJS执行依赖注入?谢谢你的帮助.仍在努力抓住这一点.
我正在将我的观点和路由器分成带有require的单独文件.然后我有一个main.js文件来实例化路由器,并且还渲染我的默认视图.
我的路由器有视图('View /:id')和edit('Edit /:id')作为路由.在main.js中,当我实例化路由器时,我可以硬编码router.navigate('View/1',true)并且导航工作正常.在我的视图文件中,当我点击编辑链接时,我想调用router.navigate('View /'+ id,true),但我不知道该怎么做.
我成功调用了Backbone.history.navigate('View /'+ id,true),但我觉得我不应该依赖于全局Backbone对象.
我尝试传递({router:appRouter})到我的视图,所以我可以使用this.options.router.navigate(),但这对我不起作用.
如果你很好奇,我的应用程序中有一堆代码:
路由器:
define(['./View', './Edit'], function (View, Edit) {
return Backbone.Router.extend({
routes: {
'View/:id': 'view',
'Edit/:id': 'edit'
},
view: function (id) {
var model = this.collection.get(id);
var view = new View({ model: model });
view.render();
},
edit: function (id) {
var model = this.collection.get(id);
var edit = new Edit({ model: model });
edit.render();
}
});
});
Run Code Online (Sandbox Code Playgroud)
视图:
define(function () {
return Backbone.View.extend({
template: Handlebars.compile($('#template').html()),
events: {
'click .edit': 'edit'
},
render: …Run Code Online (Sandbox Code Playgroud) 当我使用慢速移动宽带时,我有时会得到:
Uncaught Error: Load timeout for modules: goog!maps,3,other_params:sensor=false_unnormalized2,goog!maps,3,other_params:sensor=false,async!http://www.google.com/jsapi
Run Code Online (Sandbox Code Playgroud)
我想提高类似用户的超时时间,就像我有时使用mbb一样.
我希望能够选择性地定义模块,然后在我的代码中使用或不使用它.我正在考虑的特殊情况是在调试/测试环境中加载模拟/存根模块,但不是在我上线时.这是一个例子:
在html文件中,可以选择加载js文件(伪代码):
//index.cshtml
...
<script src="/Scripts/lib/require.js"></script>
<script src="/Scripts/app/service_user.js"></script>
<script src="/Scripts/app/real_service.js"></script>
#if DEBUG
<script src="/Scripts/app/mock_service.js"></script>
#endif
Run Code Online (Sandbox Code Playgroud)
在上面,必须在调试版本中加载real_service和mock_service.
每个模块都将使用requirejs定义,例如:
//mock_service.js
define('mock_service', [],
function () {
...
});
//real_service.js
define('real_service', [],
function () {
...
});
Run Code Online (Sandbox Code Playgroud)
然后在使用该服务时,我想检查是否已经定义了mock_service:
//service_user.js
define(['require', 'real_service'],
function (require, real_service) {
if (require.isDefined('mock_service')) { // 'isDefined' is what I wish was available
var mock = require('mock_service');
mock.init(real_service);
}
...
});
Run Code Online (Sandbox Code Playgroud)
所以我的名义'isDefined'函数只会检查一个已定义给定名称(或名称?)的模块.然后在我的代码中,如果它被定义,我可以要求它并使用它.如果没有,那也没关系.
对我来说重要的是没有尝试加载可选模块.我可以尝试/捕获require语句,但这会导致尝试从服务器加载它,我不希望这样.
另一个选择是有一个我总是加载的存根定义,所以总是需要一个模拟,然后我可以询问它是否是真实的,但这似乎也是浪费.
require.js是否有任何一个深入到require.js,他们发现他们需要这个功能并制定了实施策略?
罗先生,提前谢谢你
在我们的项目中,我们使用RequireJS作为模块加载器.我们的一些模块会影响全局库,因此不会直接在它们被引用的模块中使用.
例:
define(['definitely/goingto/usethis/','just/referencingthis/forpackaging'], function(useThis) {
useThis.likeIPromised();
// the following call can only be made when the second required file is available
someGlobalAvailableVariable.someMethod();
});
Run Code Online (Sandbox Code Playgroud)
在JavaScript中编写模块时,这可以正常工作.但是,我们正在逐步将项目翻译为TypeScript.鉴于上面的示例,这会导致:
import useThis = module("definitely/goingto/usethis/");
import whatever = module("just/referencingthis/forpackaging");
useThis.likeIPromised();
// I've written a definition file so the following statement will evaluate
someGlobalAvailableVariable.someMethod();
Run Code Online (Sandbox Code Playgroud)
在将其编译为JavaScript时,编译器希望对您有所帮助,并删除任何未使用的导入.因此,这会破坏我的代码,导致第二个导入的模块不可用.
我目前的工作是包括一个冗余的任务,但这看起来很难看:
import whatever = module("just/referencingthis/forpackaging");
var a = whatever; // a is never ever used further down this module
Run Code Online (Sandbox Code Playgroud)
有谁知道是否有可能将TypeScript编译器配置为在编译期间不优化模块?
requirejs ×10
javascript ×6
amd ×2
almond ×1
backbone.js ×1
cdn ×1
jquery ×1
tsc ×1
typescript ×1