New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
模块的加载启动 #260
Comments
有任何问题,欢迎留言交流。 |
请教一下,我使用combo服务合并了各个模块,但是在主文件通过require来调用接口却调用不到,在console里输入 seajs.cache查看各个模块的exports为null,文件是有加载了的。 然后测试的时候,除了require('../../../ued/tool/jquery')的exports为object外,其它文件的exports都变成nul了, 我调用popLogin.js插件里的exports出来的popLogin方法会报 Uncaught TypeError: Cannot call method 'popLogin' of null 或者想调用popbox.js里exports出来的pop方法也会报 Uncaught TypeError: Cannot call method 'pop' of null 这个问题纠结了很久,没合并之前是可以调用的,合并之后就出现问题了 |
合并之前要打包。 参考: #426 |
@sourcebank 这个只有开发者模式且开启了 sourceMap 时才会请求,是浏览器主动请求的。不会影响普通用户,忽略就好。 2.2 版本会把 map 文件去掉。 |
@lifesinger 这个 jquery 的是 jquery 自己的。 |
@lepture 嗯,确实是jQuery自己的,做了个demo在没有用seajs的情况下,也出现了 |
@sourcebank,唉,问了没人回答,今天自己找到了答案,那就自问自答吧 |
刚才又验证了一下,使用script标签先加载seajs后加载Raphael就有问题,反之则没有 |
@sourcebank raphael 需要封装成 CMD 模块, 请问你是用的 http://assets.spmjs.org/gallery/raphael/2.1.0/raphael-debug.js 这个吗 |
👍 @lizzie 我只是在原来的基础上使用define将代码进行了包装,然后将Raphael绑定到exports上,结果证明不行。 |
@sourcebank 因为 raphael 中有对 module define 这种处理, 其中一个 module.exports = eve, 没有暴露到全局, 到接下来的逻辑, 没取到 eve 值, 导致报错. 你细看下代码就知道了. 至于怎么封装, raphael 比较特殊, 得另外处理下, 具体你看 这里 另外, 请提的问题到相关的仓库 issue 中. 这个应该提到 cmdjs/gallery 中! |
@lizzie 又出现了问题,同样的代码在新建的测试页面里能运行,但放到项目中就不行了,说是找不到Raphael,但Raphael文件已经加载 在require Raphael的地方设了断点,发现运行后返回的为null |
他自动弄好的,你下载来就能用了 |
如果我用jqueryui插件或者其他的插件是不是都要封装以后才可以用呢? |
不封装的话引用不到。 |
那怎么封装啊?我初学者。 在 2013-12-13 12:00:01,tltwuyu notifications@github.com 写道: 不封装的话引用不到。 — |
@lzbSun 「初学者」不是借口,文档看完了没 seajs.org |
请问玉伯,我们有一个这样的逻辑:
其中 first.js 和 seconed.js 被压缩合并成了 first.js ,就是说first.js里含有两个first和second两个模块。 而开发环境的时候,我们需要替换为本地文件进行调试。所以给alias加一个 second.js 的路径。
由于第三个文件是一系列页面的js,这样导致每个页面js都要加上一句判断开发环境决定是否加上对第二个文件的依赖。 我们希望能环保一些,只在一个地方加这个环境判断。比如在 first.js 中 考虑在first.js的回调函数最后用 require.async ,但是异步加载可能导致second.js和third.js加载顺序有问题,写法不合理。 请问有其他更好的办法么? |
社区有女神出没 |
@Lynn-cc 有个地方没看懂
third.js 无法 require 到 second 模块?从依赖上看,third.js 只依赖 jquery 和 first,不依赖 second,为什么 third.js 里又会 require second 呢? 能否将这三个文件里面的 require 和 require.async 通过示例代码也展现出来?以便一起来想想怎么优化。 |
@lifesinger
|
从2.0.0升级到2.1.1以后,发现通过data-config和data-main来加载配置文件和主入口文件已经不行了,是不是去掉这个功能了 |
data-config / main 去掉很久了。升级文档里有说明。 2014/1/6 lvshuang notifications@github.com
王保平 / 玉伯(射雕) |
我从2.0.0切到2.1.1, 但是发现config里面写的别名不起作用! 暂时切回了2.0.0。但是在做dailog的时候发现第一次加载的时候, 我的模块会被执行两次, 注册的函数在触发时也执行了两次。 普通页面则正常。 define(function(require, exports, module) {
window.$ = window.jQuery = require('jquery');
require('bootstrap');
require('toastr');
require('./common/bootstrap-modal-hack.js');
exports.load = function(name) {
// console.log('执行两次');// will trigger twice
require.async('./controller/' + name + '.js?' + window.app.version, function(controller){
if ($.isFunction(controller.run)) {
controller.run();
}
});
};
window.app.load = exports.load;
if (app.controller) {
exports.load(app.controller);
}
// var Widget = require('arale.widget');
// $(function(){
// Widget.autoRenderAll();
// });
}); dailogHTML页面加载模块 <script type="text/javascript">
app.load('question/tag-modal');
</script> 模块内容: define(function(require, exports, module) {
var AutoComplete = require('jquery.autocomplete');
exports.run = function() {
$('#autocomplete').autocomplete({
autoFocus: true,
minLength: 1,
source: function(request, response) {
$('#autocomplete').data('url');
$.get($('#autocomplete').data('url'), {'term' : encodeURI(request.term)}, function(remoteResponse) {
response(remoteResponse);
}, 'json');
},
select: function(event, ul) {
var tagIds = $('input[name="tagIds"]').val();
tagIds = tagIds.split('|');
if ($.inArray(ul.item.value.toString(), tagIds) > -1) {
return false;
}
tagIds.push(ul.item.value.toString());
$('.tag-list').append('<li class="tag">' + ul.item.label + '<span class="close" data-id="' + ul.item.value + '" title="移除此标签">x</span></li>');
$('input[name="tagIds"]').val(tagIds.join('|'));
$('#autocomplete').val('');
}
});
$('.tag-list').on('click', '.close', function(e) {
e.stopPropagation();
var self = $(this);
var tagIds = $('input[name="tagIds"]').val();
tagIds = tagIds.split('|');
var newTagIds = new Array();
$(tagIds).each(function(index, value) {
if (value != self.data('id')) {
newTagIds.push(value.toString());
}
});
self.parents('.tag').remove();
$('input[name="tagIds"]').val(newTagIds.join('|'));
});
$('button[type="submit"]').click(function() {
var form = $('form.tag-edit');
$.post(form.attr('action'), form.serialize(), function(response){
if (response.status == 'ok') {
toastr.success('修改成功', '编辑标签');
$('#edit-modal').modal('hide');
} else {
toastr.error(response.message, '编辑标签');
}
}, 'json');
return false;
});
};
}); 模块里的内容在第一次加载的时候都会执行两次, 提交表单也会执行两次,但是第二次打开dailog就正常了, 印象中好像遇到过这个问题, 大概记得是javascript的加载机制, 但是具体是什么想不起来了。无奈javascript烂, 昨天看了一个晚上也没找到问题, 不知道是不是seajs2.0.0的BUG。希望有人帮助下, 非常谢谢! |
你的代码里本来就执行了两次,一次是在 main.js 里: if (app.controller) {
exports.load(app.controller);
} 一次是在 html 页面上: app.load('question/tag-modal'); |
@afc163 define(function(require, exports, module) {
window.$ = window.jQuery = require('jquery');
require('bootstrap');
require('toastr');
require('./common/bootstrap-modal-hack.js');
exports.load = function(name) {
require.async('./controller/' + name + '.js?' + window.app.version, function(controller){
if ($.isFunction(controller.run)) {
controller.run();
}
});
};
window.app.load = function(name) {
app.controller = null;
console.log('aaaaaaa');
exports.load(name);
};
// if (app.controller) {
// exports.load(app.controller);
// }
// var Widget = require('arale.widget');
// $(function(){
// Widget.autoRenderAll();
// });
}); if (app.controller) { |
很抱歉,没有时间帮你定位问题呢。太忙了。 希望你能先自己分析下,最好单独提 issue,放在这些文档的回复里,很容易被遗忘掉。 |
今天才看到这个issue, 问题已经解决, 是因为我使用bootstrap的modal时, hack了它的函数注册事件,导致事件注册了两次!! require('./common/bootstrap-modal-hack.js');
// 事件引发点 因此引发了此问题。 谢谢 @lifesinger @afc163 的热心帮忙 |
如何引用其他域名的js require("http://localhost:81/js/jquery.js");
//jquery已经CMD化,在localhost:81下的页面调用没问题 总是返回null |
@geekerzhou 应该不会 |
@army8735 发现seajs和jquery.js如果是来自同一个域的就没问题,如果seajs在localhost而jquery在localhost:81就不行 |
特地试了下确实可以,远程目录都可以何况换个端口。看看网络请求调试下。 |
你好,我问下,设置了seajs 的base路径,同时define了一个模块ID为haha |
define(function(require, exports, module){ 你好,我在执行上面这段代码时,发现在ie9下会先弹出step1,再弹出step2,其他版本的浏览器都正常,即先弹出step2,再弹出step1。 |
最近正在学习SeaJS 请问有什么好一点的资料么?有木有课本之类的啊 |
@terrytang66 seajs没有专门的书籍,但是有人写博客,也有官方文档。自己在网上搜下,多看看官方文档,http://my.oschina.net/centerLife/blog/138251 这是我之前写的博客,是对于老版的seajs的。你可以看看。 |
@lichunqiang 果断隐了 |
@lvshuang 🎱 哈哈 |
谢谢分享~~ @lvshuang @lichunqiang |
模块的加载启动
Sea.js 是一个模块加载器,模块加载器需要实现两个基本功能:
模块定义规范的实现
这就是
define
,require
,exports
,module
的实现。具体实现细节,有兴趣的可以看 Sea.js 的源码:seajs/src。可以按照 Gruntfile.js 中声明的合并顺序阅读,核心是module.js
文件。define
等方法的具体使用,请阅读:CMD 模块定义规范模块系统的启动
有了
define
等模块定义规范的实现,我们可以开发出很多模块。但光有一堆模块不管用,我们还得让它们能跑起来。首先就是启动问题。比如在 Node 中,启动很简单:
这就是启动。
再举一个例子,操作系统的启动:大家都知道的,按一下开机键就好。
在 Sea.js 里,要启动模块系统很简单:
seajs.use
Function
用来在页面中加载模块。
seajs.use
seajs.use(id, callback?)
通过
use
方法,可以在页面中加载任意模块:use
方法还可以一次加载多个模块:callback
参数可选,省略时,表示无需回调。与 DOM ready 的关系
注意:
seajs.use
与DOM ready
事件没有任何关系。如果某些操作要确保在DOM ready
后执行,需要使用jquery
等类库来保证,比如:sea.js 的引入
在调用
seajs.use
之前,需要先引入sea.js
文件,推荐直接使用script
标签同步引入:为了满足某些场景下的性能优化需求,也可以将
sea.js
的源码内嵌:注意:代码内嵌时,需要通过
seajs.config
手动配置base
路径。最佳实践
seajs.use
理论上只用于加载启动,不应该出现在define
中的模块代码里。在模块代码里需要异步加载其他模块时,推荐使用require.async
方法。sea.js
时,可以把sea.js
与其他文件打包在一起,可提前合并好,或利用 combo 服务动态合并。无论哪一种方式,为了让sea.js
内部能快速获取到自身路径,推荐手动加上id
属性:加上
seajsnode
值,可以让sea.js
直接获取到自身路径,而不需要通过其他机制去自动获取。这对性能和稳定性会有一定提升,推荐默认都加上。小结
seajs.use
是模块加载器必备的一个接口。在seajs
上,还有用于配置的config
方法、方便调试的cache
等接口,这些会在接下来的文档中详细阐述。The text was updated successfully, but these errors were encountered: