JavaScript Autoload
  更好的组织你的 JavaScript文件
       拔赤 – F2E@Taobao




                          2011-08
ongoingproject




http://ued.taobao.com/javascript   http://jayli.github.com/jswebapps

                                                                    @jayli
                                                        F2E & Translator
                                                 htt[p://jayli.github.com
                                                       bachi@taobao.com
静态语言
  vs
动态语言
如何载入外部文件/包?
PHP

<?php
   inlcude(‘config.php’);
   include(‘head.php’);
   include(‘sidebar.php’);
   include(‘main_content.php’);
   Include(‘sth_section.php’);

     //other logic
?>
C++
#include   <fstream>
#include   <sstream>
#include   <time.h>
#include   <stdio.h>
#include   <string.h>

int main(int argc,char **argv){
     //main logic…
}
Python

import dump.log
import io.xml
import io.json
from bean import *
From mod1 import *

# main logic…
PHP文件依赖

            config.php
                            sitenav.php

index.php
               header.php     channel.php



            content.php        section.php
JavaScript?
<script src=‘core.js’ />
<script src=‘dom.js’ />
<script src=‘util.js’ />
<script src=‘selection.js’ />
<script src=‘editor.js’ />
<script>
  //main logic…
</script>
JavaScript文件依赖 ?

              selection.js
                                dom.js
                                 style.js
editor.js
                  plugin.js       event.js



               editor‐util.js      core.js
                                   browser.js
JavaScriptLoader

YUI Loader
  http://developer.yahoo.com/yui/3
Yepnope.js
  http://yepnopejs.com
SeaJS
  http://seajs.com
YUILoader




http://developer.yahoo.com/yui/3
Loader.add({
  ‘base’:{
      path:’base.js’,
      requires:[‘dom’,’node’,’io’]
  },
  ‘pagination’:{
      path:’pagination-v121.js’,
      requires:[‘page-skin’,’node’,’base’]
  }
  //…
});
异步载入文件

Loader.use(‘pagination’,‘dump’,function(Y){
     //main logic…
});
Why异步?
function getScript(url,callback){
  var el = $.createElement(‘script’);
  el.src = url;
  el.onload = function(){
     callback();
  };
  document.head.appendChild(el);
}
除了html中的<script>标签
JavaScript文件载入都是异步
并行 or串行 ?
并行载入文件
getScritp(‘file1.js’);
getScript(‘file2.js’);
getScript(‘file3.js’);
…
//main logic ?
串行载入文件
getScritp(‘file1.js’,function(){
  getScript(‘file2.js’,function(){
      …
      getScript(‘fileN.js’,function(){
           //main logic…
      });
  });
});
可以这样串行!
getScritp(
  ‘file1.js’,
  ‘file2.js’,
  ‘file3.js’,…
  function(){
     //main logic…
  }
);
Yepnope.js




http://yepnopejs.com
Yepnope.js串行载入文件

yepnope([{
  load:[’file1.js’,’file2.js’]
  complete:function(){
     //main logic…
  }
}]);
有条件载入文件?
PHP
<?php
   if(condition1){
      include(‘file1.php’);
   } else if (condition2){
      include(‘file2.php’);
   } else {
      include(‘file3.php’);
   }

     //main logic…

?>
Yepnope.js

yepnope([{
  test:condition,
  yep:’file1.js’, // condition == true
  nope:’file2.js’,// condition == false
  complete:function(){
     //main logic…
  }
}]);
任意条件
if(condition1){
  getScript(‘file1.js’,foo);
}else if(condition2){
  getScript(‘file2.js’,foo);
}else{
  getScript(‘file3.js’,foo);
}

function foo(){ //主逻辑必须写入回调中
  //main logic…
}
可不可以不写回调?
CommonJS




http://www.commonjs.org
CommonJS




http://www.commonjs.org
CommonJS ∈ServerSide JS

   define(function(require){
     require(‘./mod1’); //阻塞式载入
     require(‘./mod2’); //阻塞式载入

     //main logic…
   });
CommonJS ∈Client SideJS?
SeaJS




http://seajs.com
SeaJS Demo- Calculator




   http://seajs.com/docs/demo/calculator/
JavaScript文件依赖
                      jquery.js
           stdin.js

                      calculate.js
init.js


                                      math.js
                          stdout.js
init.js
define(function(require){
     require(‘./stdin’); //输入的逻辑
     require(‘./stdout’); //输出的逻辑
});


             stdin.js
define(function(require){
     require(‘./jquery’); //载入jQuery
     require(‘./calculator’); //计算器的逻辑
});
JavaScript加载过程
闭包的重要性




http://seajs.com/docs/commonjs-modules.html#why-wrapped
SeaJS 伪阻塞 (init.js)
define(function(require){
     return;
     require(‘./mod1’);
     require(‘./mod2’);
});
Whatever
GoodIdea!
GoodIdea!

•   串行加载JavaScript文件
•   统一的沙箱结构
•   对沙箱逻辑的“预解析”
•   动态加载JavaScript文件
降低 JS文件之间的耦合
Problem!
define(function(require){
     require(‘./dom’); //必须手动引入文件?
     DOM.get(‘#id’);
});




    使用某个类的前提是
 必须知道它所在的模块/文件名称!
   并手动载入模块/文件!
Iwantthis!

define(function(require){
     require(‘./dom’);

      //知道了方法名,何必再需知道文件名?
      DOM.get(‘#id’);
});
CommonJS


文件名 =>命名空间
PHPautoload




http://cn.php.net/__autoload
<?php
  function __autoload($class_name) {
     if($class_name == ‘MyClass1’){
           require_once(‘MyClass1.php’);
      }else if($class_name == ‘MyClass2’){
           require_once(‘MC2_v102.php’);
      }
  }

  $obj = new MyClass1();
  $obj2 = new MyClass2();
?>
Sandbox.JS




https://github.com/jayli/sandbox
autoload map

function __autoload() {
  return {
     'S.Carousel':'carousel.js',
     'S.ColorPicker':'colorpicker-v1.js',
     'S.Editor':'article.js'
  };
}
SandboxJS Demo- autoload




http://jayli.github.com/sandbox/examples/autoload/test/mojo.html
<script src=“种子文件.js & 配置文件.js” />
<script>
Sandbox.ready(function(S){
  // 旋转木马模块
  S.Carousel.init(‘bid’);

 //选择颜色模块
 S.ColorPicker(‘cid’);

  //编辑器
  S.Editor(‘eid’,'淘宝UED');
});
</script>
JavaScriptAutoload

•   代码解耦更充分
•   开发者记忆负担最低
•   免除基础库升级更改文件名的麻烦
•   享受动态语言编程
•   …
Ok,开始享受编程?
Warning !!!
JavaScriptAutoload 的不足

 •   串行加载JS- 速度是个问题
 •   伪阻塞 - 客户端无“真”阻塞
 •   对包装器的支持不好(Wrap(dom))
 •   对链式调用支持不好
适用 JavaScriptAutoload 的场景

    •   内部系统 – 对性能要求不高
    •   ServerSideJavaScript
    •   当你想要更纯粹的编程时
    •   …
优化JS加载器的手段

    SeaJS - spm

YUI3 - configurator

CDN - Combo Handler
Enjoyit,Justforfun~
ref

http://developer.yahoo.com/yui/3
http://yepnopejs.com
http://seajs.com
https://github.com/seajs/spm
https://github.com/jayli/sandbox
http://www.commonjs.org
http://cn.php.net/__autoload
@jayli
       F2E & Translator
htt[p://jayli.github.com
      bachi@taobao.com

Javascript autoload