论坛首页 Web前端技术论坛

JSI的导入指令参数顺序调整意见征询

浏览 9727 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-02-10  
大为我今天思考了个jstg的雏形想法,不知道如何,提提你的意见吧~

http://bbs.ffsky.com/disp.aspx?ID=1655442&bid=17
0 请登录后投票
   发表时间:2008-02-10  
yeaha 写道
我认为jsi的核心价值就是非侵入性的解决了js库的依赖问题,其它的装饰引擎、DOC、IDE这些都或多或少有人在做,而jsi解决的依赖问题貌似很少有人在做(js层面上的,服务器端解决依赖的貌似多一些)

我用google搜索了"javascript dependency"关键字,仅仅发现一个叫JSLoad的有点意思,但是也不如jsi强大,所以在这一块上,最值得期待的就是jsi


如果你是说www.jsloader.com,那个东西不行,我看过了。
0 请登录后投票
   发表时间:2008-02-10  
jindw 写道

刚才和小张讨论了一下,更倾向于仍外一种方式

 

$import(path,colot,col)
 



即:

$import(path,
            callbackOrLazyLoadOrTarget)
$import(path,
            target,
            callbackOrLazyLoad)
 

 




API的改动,你是否要保持向前兼容?

 

我给点参考,pies旧版本的api(新版本的设计思路不同,略过)是这样的:

 

$import(uri:String):packageObject

$import(packageNamespace:PackageNamespace):packageObject

 

前者的例子如:

$import("http://www.example.com/scripts/lib/test/pkg1.js#ClassA,ClassB;ClassC,ClassD");

后者的例子如:

$import(pies.test.pkg1);

 

$import调用会返回容器,比如可以:

var my = $import(pies.test.pkg1);

var c = new my.ClassC();

 

这里源于一个与jsi不同的设计,就是一个package里会定义某些name是直接到global,某些是不会到global(这个设计是按照moz老的JS2草案和参考perl的module的),必须通过pkg = $import()调用来获得pkg对象。

此外,这里没有考虑异步加载的问题。


然而,在我完成旧pies之后,我逐渐觉得import到全局空间是存在一定问题的。这其实削弱了pies(或jsi或类似方案)的意义,因为全局空间上导入的名字总是越来越多。

 

理想状况是始终导入到target,强制使用者首先考虑import到一个容器的方式,而不是直接什么都码到全局空间。我考虑了这样一种API:

 

var my = $import(jsipkg1);

my.$import(jsipkg2);

my.$import(jsipkg3);

 

即在返回的容器上带有$import方法。这样,可以如此:

 

var my =

$import(jsipkg1).

$import(jsipkg2).

$import(jsipkg3);

 

当然这样存在一个问题,即无法判断是否导出到global。这也是我的用意,不允许直接导出到global,如果要导出到global,则必须通过某种显式声明。比如

$import(jsipkg1).

$import(jsipkg2).

$import(jsipkg3).

to(window);

 

 

后来,我转向了pies新的设计(其实也不新了,但是我设计完毕后一直没有全部实现,惭愧)完全抛弃了这个做法,因为所有的命名空间都是托管的,所以就没有这个问题了。

 

因为jsi现在也致力于core的部分,我建议jsi也可以考虑一下怎么降低import到全局空间的负面影响。

 

如果就现有的API来说,lazy参数其实无所谓,我一向认为import的语义最好不要包含异步loading的问题,也就是是否异步不要在import时指定(或许可以在定义module依赖时指定)。

 

其实可以考虑把target提前,即import path, target 改为 import target, path。此外就算要加上col,也不必一定需要指定target的。

这样API其实是:

 

$import (target:Object, path:String)

$import (path:String)

$import (path:String, onload:Function)

$import (path:String, lasy:Boolean)

$import (target:Object, path:String, onload:Function)

$import (target:Object, path:String, lazy:Boolean)

 

这个重载是可以区分的。

0 请登录后投票
   发表时间:2008-02-11  
huhu,谢谢hax的分析。
不过,我们一些想法差别还是挺大的。

关于导入全局空间带来的污染问题。
我不那么看重。
JSI再降低命名污染的问题上,已经作了比较有效的工作。
例:
当我们import("com.xxx.C1")时。
可能,我们真正装载的是C1,C2,C3.....C100。而真正出来的变量只有C1
就是说:JSI已经吧这种污染降低了很大一步,我认为就没有必要再坐到更加及至了,那样有可能影响易用性。

再者,纵使我们真的要同时使用两个同名的不同包内的变量。
我们显示的指定target就是了,毕竟这种情况非常少见。
0 请登录后投票
   发表时间:2008-02-11  
确实,异步装载,很少用到,我以前的想法是,写一个非常简单的内核,不要异步。
能后,在一个扩展脚本中。在原同步$import的基础上,重写它,让他支持异步和延迟。
不过,后来发现,这样做起来,代码量猛增。因为,同步装载是很多内部函数无法在外部重用。最后还是退回了原来的方式,写在一起。

不过,还好,这次重写之后的内核,简单了很多很多,而且我在新版本的JSA上支持一种新的功能。feature选择。

就是说,我吧一些可选的功能,用if("<featureKey>"){...}包起来,这样我在导出的时候,可以灵活选取需要的功能,同样可以轻松剔除掉可能用不上的异步模式。


仍外,延迟装载在浏览器上还是非常有效的,而一旦支持了延迟装载,异步装载就是一个顺带的副产品了。


仍外,也许大家都被一些eval脚本的调试费劲脑汁了吧。
在开发期间。使用JSI2延迟装载模式,脚本就不是eval出来的了,对于调试就非常方便。
既有了自动装载,冲突隔离,有可以准确定位源文件的错误位置。
0 请登录后投票
   发表时间:2008-02-11  
仍外,向后兼容,我现在基本不用考虑,除我之外,我还没见过谁在正式的项目中使用。
我可以放开手来修改。

身边的人,三言两语就可以吧这些改动说个清楚。
0 请登录后投票
   发表时间:2008-02-11  
确实jsvm就是导入的脚本没法调试,压根看不到错误的行数。麻烦,只能用眼睛看。有机会试试你这个。
0 请登录后投票
   发表时间:2008-02-13  
jindw 写道
huhu,谢谢hax的分析。
不过,我们一些想法差别还是挺大的。

关于导入全局空间带来的污染问题。
我不那么看重。
JSI再降低命名污染的问题上,已经作了比较有效的工作。
例:
当我们import("com.xxx.C1")时。
可能,我们真正装载的是C1,C2,C3.....C100。而真正出来的变量只有C1
就是说:JSI已经吧这种污染降低了很大一步,我认为就没有必要再坐到更加及至了,那样有可能影响易用性。

再者,纵使我们真的要同时使用两个同名的不同包内的变量。
我们显示的指定target就是了,毕竟这种情况非常少见。


我觉得不能小看对全局命名空间的污染。我举一个例子。

假设有人写了一个 jsipkg1 的类库。在其中他
$import ("prototype") ,即他的类库依赖 Prototype 库。

有另一个人写了一个 jsipkg2 的类库。在其中他
$import ("jquery") ,即他的类库依赖 jQuery 库。

我们知道 prototype 的 $ 和 jquery 的 $ 是有冲突的。

现在问题就是,jsipkg3 能否同时使用 jsipkg1 和 jsipkg2。

假如$都是被导入到全局空间上,则就存在问题了。当然,也许jsi至少会给点异常信息。但是如果不能在不修改他们的源码的情况下使用,那就是一个问题。当然,我们可以修改jsipkg1和jsipkg2的源码,将其$import语句改为导出到一个容器上,但是这存在一个严重问题:

如果jsipkg1和jsipkg2原来是没有使用jsi的,那么原本他进入jsi,只需要加入依赖声明和import语句,工作量还是不大的,但是现在要修改大量源码了(所有用$的地方要改成 container.$),而且这个味道不好,因为破坏了使用者对于prototype/jquery库的使用习惯,也丧失了$短名字的好处。总之一句话,这里产生了jsi希望避免的侵入性。

再者,假如这是不可避免的,那么宁可在API上让大家默认导入到一个container上,这至少保证一个类库在写好之后不会造成全局命名空间污染,至于写jsipkg3的人,他如果爱用prototype,那他自己还可以强制的把prototype导到全局空间上(通过类似$import("prototype").to(window)之类的语法)。这个问题其实说明一点,如果我用jsi写了一个类库,C1,C2,C3.....C100,使用者只用C1,这个现在是可以办到了,但是现在的问题是,如何避免使用者在使用C1的时候,被迫接受全局空间上被加入了可能引起冲突的 $ 或其他类似的东西。
0 请登录后投票
   发表时间:2008-02-13  
kebo 写道
确实jsvm就是导入的脚本没法调试,压根看不到错误的行数。麻烦,只能用眼睛看。有机会试试你这个。


确实。这是个大麻烦。但是相比较 命名空间污染 的问题,我认为这两个问题不是在同一个层面上的。命名空间污染,是一个更加基本的编程问题。而调试定位问题,则是工具层面的问题。

总的来讲,如果类库整体是建筑在jsi/pies之类的系统上,则模块可以做到很小,而我们至少可以定位到源文件名,如果再配合良好的log,则调试定位的问题相对就降低了。

当然,有些同志养成了严重依赖调试器的习惯,这个就比较难办了。
0 请登录后投票
   发表时间:2008-02-13  
我觉得import指令应该只包含所依赖的类名,如import("x.y.z"),至于"x.y.z"这个类在那个文件,通过另一个文件来指定,最好有一个默认的映射规则。
独立控制每个文件使用什么形式加载。
另外不用eval,用document.write script标签的形式,因为知道类和文件的映射关系,便可以检测相应的类是否存在来判定文件是否已经加载下来。
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics