难度:中等
Dojo版本:1.7+
原作者:Dylan Schiemann
译者:Nate ([email protected])
原文链接:http://www.sitepen.com/blog/2012/08/27/working-with-dojo-and-amd-in-production/
在最近的一些文章中,我们展示过如何使用嵌套的require来使用通过Dojo Build 系统打包的layer文件。在这里,layer是Dojo中的一个术语,一个layer是一个包含了很多JavaScript资源的文件,即常说的打包后的文件。从而在生产环境中能够减少请求次数,提高页面加载速度。
我们最初是通过如下的语句来实现引入layer文件的:
<script type="text/javascript" src="../../dojo/dojo.js" data-dojo-config="async: true"></script> <script type="text/javascript"> require(['dgrid/dgrid'], function () { require(["dgrid/List", "dgrid/OnDemandGrid","dgrid/Selection", "dgrid/Keyboard", "dojo/_base/declare", "dgrid/test/data/perf", "dojo/domReady!"], function(List, Grid, Selection, Keyboard, declare, testPerfStore){ //...这样的写法固然可以工作,但是并不是很完美。因为你在build之后部署最终的应用的时候需要去修改源文件。引入一个layer,和在开发过程中require一个普通的AMD Module,写法是不太一样的。虽然你可以用PHP或者一些服务器端语言来生成这样的javascript文件,但除此之外,还有很多备选方案。在这我们来看看下面的5种方法:
适用于:简单,快速,单layer的应用
在最初的文章中,我们主要关注如何构建一个简单并且迷你的包。在现在的场景中,你可能需要创建一个自定义的dojo.js,其中包含了所有你需要的模块。从而我们能够在页面的require中一次加载所有需要的模块。我们不需要提前require一个layer,因为所有需要的模块已经通过dojo.js被加载了。
适用于:简单而快速的基于URL格式引入模块
这种方法根据URL来判断应用应该载入哪些模块。例如,我们可以去判断URL中是否包含dev这个单词,从而可以只有在非开发环境时去引入一个额外的模块,即已经打包好的layer。
require(/dev/.test(location.search) ? [] : ['dgrid/dgrid'], function(){ require(["dgrid/List", "dgrid/OnDemandGrid","dgrid/Selection", "dgrid/Keyboard", "dojo/_base/declare", "dgrid/test/data/perf", "dojo/domReady!"], function(List, Grid, Selection, Keyboard, declare, testPerfStore){ //... }); });
适用于:基于URL或者dojoConfig中的设置去载入相应的模块
Dojo的全局配置中可以设置dojoConfig.deps属性来载入一个layer,并且在layer载入完成后会自动调用dojoConfig.callback,其中可以放置应用程序启动的逻辑。
<script type="text/javascript"> var dojoConfig = { async: 1, deps: ['dgrid/dgrid'], callback: function(){ require(["dgrid/List", "dgrid/OnDemandGrid","dgrid/Selection", "dgrid/Keyboard", "dojo/_base/declare", "dgrid/test/data/perf", "dojo/domReady!"], function(List, Grid, Selection, Keyboard, declare, testPerfStore){ //... }); } }; </script> </script type="text/javascript" src="../../dojo/dojo.js"></script>
<script> var dojoConfig = { async: 1, deps: /dev/.test(location.search) ? [] : ['dgrid/dgrid'], callback: function(){ require(["dgrid/List", "dgrid/OnDemandGrid","dgrid/Selection", "dgrid/Keyboard", "dojo/_base/declare", "dgrid/test/data/perf", "dojo/domReady!"], function(List, Grid, Selection, Keyboard, declare, testPerfStore){ //... }); } }; </script> </script type="text/javascript" src="../../dojo/dojo.js"></script>
这种灵活的方式可以使我们自由的在开发,测试,以及生产环境之间进行切换。
适用于:包含非常多模块的大型应用
另一种在开发环境和生产环境间平滑过的常见方法是创建一个顶级模块,在这个顶级模块中去引入某个页面需要的模块。从而在Dojo Build工具中可以为一个layer仅仅指定这个顶级模块即可,从而开发环境和生产环境都仅需要在HTML中载入同样的模块。这种方法还有另外一个好处,就是保证了HTML之内没有JavaScript代码,从而更加易于维护。
例如,你可能定义了一个模块:app/app.js
define(["dgrid/List", "dgrid/OnDemandGrid","dgrid/Selection", "dgrid/Keyboard", "dojo/_base/declare", "dgrid/test/data/perf", "dojo/domReady!"], function(List, Grid, Selection, Keyboard, declare, testPerfStore){ //... });然后,你的HTML中仅需要包含下面这段简单的代码:
<script> var dojoConfig = { async: true, deps: ["app/app"] }; </script> <script src="dojo/dojo.js"></script>
适用于:基于Dojo Build最佳实践的一种相当自动的方法
Dojo Boilerplate项目将会自动处理适用于你的场景。它创建了一些Dojo常见应用架构供参考,并且包含了一些自动build脚本来帮助从开发环境过渡到生产环境。