我正在创建我的第一个Bower组件.运行bower init
脚本后问我'这个包暴露了什么类型的模块?' 有这些选项:
这些选项有什么区别?
使用Require.JS和<script>
在DOM中创建元素之间的区别是什么?
我对Require.JS的理解是它提供了加载依赖项的能力,但这不能简单地通过创建一个<script>
加载必要的外部JS文件的元素来完成吗?
例如,假设我有函数doStuff()
,这需要函数needMe()
.doStuff()
在外部文件中do_stuff.js
,而needMe()
在外部文件中need_me.js
.
这样做Require.JS方式:
define(['need_me'],function(){
function doStuff(){
//do some stuff
needMe();
//do some more stuff
}
});
Run Code Online (Sandbox Code Playgroud)
只需创建一个脚本元素即可:
function doStuff(){
var scriptElement = document.createElement('script');
scriptElement.src = 'need_me.js';
scriptElement.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(scriptElement);
//do some stuff
needMe();
//do some more stuff
}
Run Code Online (Sandbox Code Playgroud)
这两项都有效.但是,第二个版本不要求我加载所有Require.js库.我真的没有看到任何功能差异......
在玩了AMD/RequireJS后,我想知道加载包含模板和CSS的UI模块是否是一个好主意,这样它们就完全独立于网页.
这听起来不错,但我没有看到这在野外实施,所以可能存在陷阱.
想想一些具有以下结构的UI模块:
myWidget
|--img
|--main.js
|--styles.css
+--template.tpl
Run Code Online (Sandbox Code Playgroud)
一个文件夹中的所有内容.看起来很不错.
main.js中的模块看起来像这样:
define(["TemplateEngine", "text!myWidget/template.tpl"], function(TemplateEngine, template) {
// Load CSS (Pseudo Code)
var cssUrl = "myWidget/styles.css";
appendToHead(cssUrl);
return function() {
return {
render: function(data) {
return TemplateEngine.toHtml(template, data);
}
}
}
});
Run Code Online (Sandbox Code Playgroud)
现在的问题是:
1.3.0 - 2012年1月11日从Underscore中移除了AMD(RequireJS)支持.如果您想将Underscore与RequireJS一起使用,您可以将其作为普通脚本加载,包装或修补您的副本,或下载分叉版本.
他们为什么要这样做?有人知道吗?因为他们仅在几个月前(10月)添加了它,并且据说 AMD(异步模块定义)远远优于CommonJS模块.
更新:截至2013年12月,再次受到支持.
我们正在使用Backbone,RequireJS和Handlebars构建一个非繁琐的Web应用程序,好吧,我只是很好奇.目前,我们的每个型号排序如下:
define(['Backbone', 'js/thing/a', 'js/thing/b', 'js/lib/bob'], function(a, b, bob) {
return Backbone.Router.extend({
// stuff here
});
});
Run Code Online (Sandbox Code Playgroud)
其中thing/a,thing/b都有自己的依赖关系,例如Handlebars模板等.现在发生的是在我的main.js中,所有"顶级"路由器都被加载并初始化; 每个顶级路由器都有一组依赖项(模型,视图等),每个依赖项都有自己的依赖项(模板,帮助程序,工具等).基本上,一个大树结构.
这种情况下的问题是整个树在页面加载时被解析并加载.我不介意每个人,因为我们最终将通过优化器运行它并最终得到一个大的单个文件(将RequireJS简化为基本上模块化框架).但是,我很好奇你是否可以按需加载视图和模板等内容.
还有就是"简化CommonJS的包裹解释说:" 在这里,所以我试过了:
define(function(require) {
Backbone = require('Backbone');
return Backbone.Router.extend({
doStuff: function() {
var MyView = require('js/myView');
new MyView().render();
}
});
});
Run Code Online (Sandbox Code Playgroud)
但是,看看Chrome的网络检查器,似乎RequireJS - 即使没有触发触发doStuff处理程序的路径 - 仍会加载myView
依赖项.问题:
require()
没有实际触发doStuff
路线的情况下寻找呼叫?Backbone.js文档建议以这种方式加载bootstrapped模型:
<script>
var Accounts = new Backbone.Collection;
Accounts.reset(<%= @accounts.to_json %>);
var Projects = new Backbone.Collection;
Projects.reset(<%= @projects.to_json(:collaborators => true) %>);
</script>
Run Code Online (Sandbox Code Playgroud)
但这是一种不能用于AMD方法的模式(使用require.js)
唯一可能的解决方案是声明存储JSON数据的全局变量,并在稍后的相关初始化方法中使用此变量.
有没有更好的方法来做到这一点(没有全局变量)?
我正在努力用requireJS加载gmaps api.这就是我尝试过的:
requirejs.config({
urlArgs: "noCache=" + (new Date).getTime(),
paths : {
"jquery": "vendor/jquery-1.8.2.min",
"bootstrap": "vendor/bootstrap.min",
"underscore": "libs/underscore-min",
"backbone": "libs/backbone-min",
"template": "libs/template",
"gmaps": "http://maps.google.com/maps/api/js?v=3&sensor=false"
},
shim: {
'backbone': {
deps: ['jquery', 'underscore'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
},
'bootstrap': {
deps: ['jquery']
},
'gmaps': {
deps: ['jquery']
},
'main':{
deps: ['jquery','gmaps']
}
}
});
require(["main"], function (main) {})
Run Code Online (Sandbox Code Playgroud)
但是当我尝试实例化我得到的地理编码器时,在main.js里面,undefined不是函数"错误.
var geocoder = new google.maps.Geocoder();
Run Code Online (Sandbox Code Playgroud)
任何想法我可能做错了什么?
有没有办法访问require.js的所有已加载模块?
背景:
我想init()
在加载所有这些函数后自动调用我的javascript-modules函数,请参阅require.js + backbone.js:如何构造具有初始化函数的模块?
如果没有require.js,我会遍历我自己的模块存储并调用每个init()
函数.
我现在想用require.js做这件事.我知道调用my_custom_init_function_favoritecolor_petname_love123
每个加载的模块(包括外部库)是危险的.我希望这比手动保持所有模块的列表(以及这些模块的要求)是最新的麻烦少.忘记一个模块init()比具有我的自定义函数名的第三方库更有可能(尽管后者可能更难调试).
或者有没有人更好地了解如何实现这一目标?
我是新来的学习道场和我所遇到的require()
和define()
功能,我不能让我的头周围其一.另外,我什么时候才能使用其中任何一个?一个小的演示或示例将是有益的.非常感谢!
我有一个heckuva时间过渡到Dojo和新的AMD结构,我真的希望有人可以对整个概念有所了解.过去几周我一直在Google上生活,试图找到关于不使用的信息,但是使用它的结构和设计模式趋势.
我觉得奇怪的是,对于一个相对复杂的javascript应用程序,例如需要创建和设置Dijits的主页面,创建的DOM元素等,我需要,因此使用,不同模块的TON否则在AMD系统之前的dojo命名空间中可用(或者,至少不分配给23个不同的vars).
例:
require(['dijit/form/ValidationTextBox', 'dijit/form/SimpleTextarea', 'dijit/form/CheckBox', 'dijit/Dialog', 'dijit/form/Form'])
require(['dojo/ready', 'dojo/parser', 'dojo/dom-style', 'dijit/registry', 'dojo/dom', 'dojo/_base/connect', 'dojo/dom-construct'],
function(ready, parser, style, registry, dom, event, construct){
//...etc
}
Run Code Online (Sandbox Code Playgroud)
这只是我正在处理的其中一个页面的一些模块.当然,有一种更好的,非破坏性的未来发布方式来访问这些方法,等等.我的意思是,我真的必须导入一个全新的模块才能使用byId()
吗?而另一个连接事件?最重要的是,通过必须在函数参数列表中分配变量名来创建的所有混乱只是看起来像这样的后退.
我想也许你require()
只在需要的时候才能使用模块,比如query
模块,但是如果我不止一次需要它,那么分配给它的变量很可能超出范围,我需要将它放入domReady!
或ready
调用. reaalllly .... ??!
这就是为什么我只能假设我对道场缺乏了解.
我真的已经查看并搜索并购买了书籍(虽然是AMD之前的一本),但这个图书馆真的让我为我的钱买单.我很欣赏任何人都能看到的光.
编辑示例
require(['dijit/form/ValidationTextBox'])
require(['dojo/ready', 'dojo/parser', 'dojo/dom-style', 'dijit/registry', 'dojo/dom', 'dojo/_base/connect', 'dojo/dom-construct'], function(ready, parser, style, registry, dom, event, construct){
/* perform some tasks */
var _name = new dijit.form.ValidationTextBox({
propercase : true,
tooltipPosition : ['above', 'after']
}, 'name')
/*
Let's say I …
Run Code Online (Sandbox Code Playgroud) js-amd ×10
javascript ×8
requirejs ×7
backbone.js ×2
dojo ×2
bower ×1
css ×1
ecmascript-6 ×1
es2015 ×1
node.js ×1