from limu:
接下来说说我对于约定以及当前seajs这些约定的看法.
最近工作原因深入了解了下RoR,约定很多,敏捷开发那本书看下去非常顺畅,但是遇到一个问题,当我回过头来回忆的时候,却发现自己根本记不住几项约定,需要不断的翻书寻找才能使用下去.
我发现看seajs文档遇到同样的问题,一节节看下去很通畅,但当昨天我做10个seajs的测试用例时,遇到了同样的问题,拿不准约定,要反反复复回去翻文档.
所以从整个约定层面来看,我觉得不一定越多越好,现在看起来约定最成功的是完全改变了前端写法的jquery,但其实jquery的约定并不多(操作结果集,可以链式调用,如何添加工具函数,如何扩展结果集)
from yubo:
非常同意,一起努力,来寻找 seajs 的最佳约定。
from limu:
seajs海纳百川,我觉得更要亲民一些,让各个层次的开发者顺畅的使用.declare,load,exports,module,require已经不少了.我觉得最难上手的是下面这个约定:
/*** a.js 的 module.declare 里 ***/
module.load('./b');
// => http://cdn.com/path/to/js/b.js
/*** test.html ***/
module.load('./b');
// => http://example.com/path/to/html/b.js
JS和css不一样,JS一直是行内脚本和外链脚本没有任何区别,把行内脚本迁移到外链脚本文件中,或反过来都不需要做任何调整.这相当于浏览器对JS的约定.
from yubo:
这是一个很好的问题,至今 CommonJS 社区也无很好的解决方案。因为 require 接受 relative id,这势必导致和 context 相关。也就是说,在独立js页面和内嵌到页面,context 会发生变化,从而语义有变。
在 FlyScript 里,为了避免这一问题,甚至强制使得 module.declare 仅能在 js 文件里才能
调用,在页面里,将这个接口隐藏掉了。也就是增强一个强约定:
模块代码必须写在独立文件里!
让 relative id 和 context 相关的好处是:关注点分离,让js模块开发者不必关心页面环境,只要关注自身即可。比如:
sub/sub/a.js
sub/sub/b.js
无论 a.js 和 b.js 放在什么目录,只要保持同级,在 a.js 里调用 b.js 时,都是:
require('./b')
在打包、移动等各种情况下,无需修改代码。
有利有弊,或许 seajs 应该和 flyscript 一样,使得 module.declare 仅能在 js 脚本里调用?
如果要内嵌,则需要去掉包裹层以及修改 require, exports 等代码?
CommonJS 1.0 的模块,也只能是以文件形式存在,直接内嵌,exports 互相覆盖,也明显有问题。
两难的问题,必须取舍。我倾向于让 module.declare 只能在 js 文件里出现。
内嵌只在特殊页面做性能优化时需求,这种情况下,就不推荐用模块方式组织,直接裸写。
from limu:
seajs引入了上面这个约定之后,情况发生了变化,而且这个变化挑战了常规想法.比如我在测试的时候想在html页面内先declare,然后load直接使用,却不知道如何做.
<script>
module.declare("./a",function(require,exports,module){
});
module.load("./a",function(a){
});
</script>
上面这段脚本,load还是会去请求.a.js. 可能我的写法不对,但是文档中没有相关的交代.换句话说,如果我在要求js全部内联的首页,该如何去做.
其实这个还可以回到约定和配置的问题,如果seajs提供了完善的配置方案能够代替这个约定的话,即使选择了seajs,但团队内也会要求大家不采用这个约定,
from yubo:
上面已经讨论,纠结。或许页面中就不应该出现 module.declare