ecomfe / esl

enterprise standard loader
BSD 3-Clause "New" or "Revised" License
845 stars 228 forks source link

esl 和 require 功能似乎不完全一致,与 jquery 和jquery ui配合的问题。 #41

Closed yeyanzhao closed 9 years ago

yeyanzhao commented 9 years ago

问题: esl 不能有效 加载 jquery 和jquery ui。

说说背景:因为我要使用echart,后来又要使用zrender,所以就使用了esl。 后来又要使用 jquery ui,所以想继续使用 esl 来加载 jquery ui【备注,之前jquery一直是静态标签加载的】。 因为 jquery ui的需要, 所以改为 amd 方式 加载 jquery, 但是 require之后, 在浏览器中看页面代码, jquery 和 jquery ui的相关代码文件也都正确加载了,script标签都正确,但就是没有 那个 $, jQuery变量, 还有 jquery ui的相关部件 函数也没有加载到jquery的 fn中。且也不报错。

后来偶然机会试了网上的例子, 又在自己的 程序里试了 require.js 这个库,发现 jquery 和jquery ui的部件 可以正常使用了, 再换回 esl.js, 又不行了。再换回 require.js,又可以了。 所以我的初步判断是 esl 似乎在某些方面 有些不完备。

我不是js 专家,也是把 esl 当作 require.js 来使用的,所以这种差别, 还是有些困惑的。 下面贴上我的配置:

             var  zr, tl;

    require.config({ 
        //baseUrl: 'resource/js',
        packages: [
              {name: 'jquery', location: 'resource/js', main: 'jquery'},
              {name: 'jqueryui', location: 'resource/js/jqueryui/ui', main: 'jqueryui' },
            {   name: 'zrender',
                location: 'resource/js/zrender', 
                main: 'zrender'
            }
        ]
    });

    require([   'zrender/zrender'
                ,'zrender/shape/Circle'
                ,'zrender/shape/Rectangle'],
                function(zrender,_, _, timeline) {
                    //this.zrender = zrender;
                    this.zr = zrender.init(document.getElementById('cmain'));
                }
    );

    require(['jquery'], function($){ //虽然网上有资料说这里要jquery,但试了 jquery/jquery 在require.js 时 也可以成功加载。
        console.log($);     //使用 require.js的时候,这里可以运行到,esl的时候不行,且不报错。
    }); 

    require(['jqueryui/dialog'], function(dialog){
        console.log(dialog);  //使用 require.js的时候,这里可以运行到,esl的时候不行,且不报错。
    }); 
errorrik commented 9 years ago

我的测试结果是,jquery是能正常加载的,但是jqueryui不行。原因是esl的用时定义机制。jqueryui/dialog用到了jqueryui/widget,dependencies数组里也包含它,但是它并没有在jqueryui/dialog内部被require,所以没有进行init。jqueryui/widget在init时会往$上挂东西($.widgets),但是由于没init,$.widgets不存在,所以报错。

http://efe.baidu.com/blog/dissecting-amd-loader/ 这里有提到,esl的用时定义机制。相关讨论在这里也能找到 https://github.com/ecomfe/esl/issues/20

我的建议是,jquery和jqueryui这俩东西,就不要跑在amd体系下了

yeyanzhao commented 9 years ago

是的,jquery 使用 amd确实会有不方便,因为还需要自己弄个 ready函数,然后require jquery的回调里写代码,很麻烦。 不过我这样用,是因为之前想把jquery ui用在另一个使用了 amd模式的 js文件里,所以要接着使用amd模式。 这个结构可能需要改。但是若改就会有另一个麻烦就是 jquery ui 需要选择部件编译,这个也蛮烦的,大多时候可能使用一小点, 编译了一个大块头,想bootstrap 整个文件感觉也是,很多时候是只用到了其中的一小部分,但包含进来的仍然是个大家伙。

errorrik commented 9 years ago

有个很笨的办法,用一个amd module,里面预先require jqueryu所需的各种模块。但是require的时序很重要,必须按着依赖顺序来。所以我说它是很笨的办法。

只是开下脑洞,不建议使用这种办法,还是jqueryui独立于amd环境,独立制定选择性的编译方案更靠谱。

yeyanzhao commented 9 years ago

我已在往前推进,因为这个只是应用中的一环。我发现的另一个问题是,使用了AMD后,有些效果没出来,还不知道怎么回事。而使用普通静态方式就可以不用管那么多。所以,我是真的倾向于使用静态加载的方式了。。

lyt23 commented 8 years ago

如果使用esl+jquery+easyUI,是不是可以采用所谓 “很笨的方法”来解决,谢谢。