zoukankan      html  css  js  c++  java
  • require.js初试(with angular & optimization)

    如果你只是想找一款称手的js加载器,可以参考这篇js loader benchmarks(http://artzstudio.com/files/Boot/test/benchmarks/script.html),即便这篇文章已经例举得够多的了,还是没有涵盖到很多已经广为使用的库,如果要跟你自己熟悉的库来做对比,可以仿照文中的例子自行对比。

    我要说的是require.js,可以作为加载器来使用,但它诞生的目的不是为了异步加载脚本,而是为了模块化,同时也就不会污染global。简单做了一个与angular.js结合的demo。
    关于require.js,可以参考阮一峰的《javascript模块块编程》,在此给出介绍require.js的一节http://www.ruanyifeng.com/blog/2012/11/require_js.html
    官方api就不用说了:http://requirejs.org/docs/api.html
    同时还支持压缩优化:http://requirejs.org/docs/optimization.html

    本文练习使用require.js和angular,以及利用r.js来进行压缩


    1,结构

    --index.html
    --js
        --main.js(入口)
        --app(业务代码,angular相关代码)
            ----app.js
            ----controllers.js
            ----directives.js
            ----filters.js
            ----services.js
        --test(业务代码,测试用,跟app作用差不多,此处测把不同的程序加载同一插件的不同版本)
            ----plugin.1.0.js
            ----plugin.1.2.js
            ----newapp.js
            ----oldapp.js
        --vendor(提供程序,angular,jquery等,如果引用了underscore, backbone当然也应该是这个目录)
            ----jquery.js
            ----angular.js
    --partials
        --partial1.html
        --partial2.html
    --css
        --app.css


    当然,大体上,是跟这个seed一样的:https://github.com/tnajdek/angular-requirejs-seed

    2,传统写法


    <script src="js/vendor/angular.js"></script>
    <script src="js/app/app.js"></script>
    <script src="js/app/services.js"></script>
    <script src="js/app/controllers.js"></script>
    <script src="js/app/filters.js"></script>
    <script src="js/app/directives.js"></script>

    3,require.js的写法

    可以这么写:
    <script type="text/javascript" data-main="js/main" src="js/vendor/require.js"></script> 
    也可以把main.js的内容直接写到紧要require.js引用的地方,第一个被发现的requirejs({}), requirejs.config({}), require({}), 或 require.config({})会被认作配置文件:
    <script type="text/javascript" src="js/vendor/require.js"></script>
      <script type=""text/javascript">
        require.config({
          //same as main.js
        });
        require(['main']);
      </script>

    4,引入require后angular的写法:

    //观察一下define的用法就基本明白了
    
    //声明依赖于service, filter, directive的app级别的moudle
    define(['lib/angular'],function(angular){
        angular.module('myApp', ['filters', 'services', 'directives', 'controllers']).
          config(['$routeProvider', function($routeProvider) {
            $routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'});
            $routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
            $routeProvider.otherwise({redirectTo: '/view1'});
          }]);
    });
    
    //srvices.js
    
    define(['lib/angular'],function(angular){
    // Demonstrate how to register services
    // In this case it is a simple value service.
    angular.module('services', []).
      value('version', '0.1');
      // factory('version',function(){return '0.3';});
    });
    
    //filters.js
    
    define(['lib/angular'],function(angular){
    	angular.module('directives', []).
    	  directive('appVersion', ['version', function(version) {
    	    return function(scope, elm, attrs) {
    	      elm.text(version);
    	    };
    	  }]);
    });
    
    //controllers.js
    
    define(['lib/angular'],function(angular){
    	angular.module('controllers', []).
    	  controller('MyCtrl1', [function() {
    
    	  }])
    	  .controller('MyCtrl2', [function() {
    
    	  }]);
    });

    5,制作main.js文件

    require.config({
        baseUrl:'js/app',//配置默认路径,
        paths:{
            'lib':'../vendor',//配置了baseUrl后,显然不处于其子目录的路径是需要额外配置的
            'test':'../test',
            'main':'../main'
        },
        shim:{
            'lib/angular':{exports:'angular'}//不支持AMD的脚本用shim的方式加载
        },
        map:{
            //一个项目里用了同一插件不同版本的情况用map来映射
            '*':{'plugin':'test/plugin.1.2'},
            'test/oldapp':{'plugin':'test/plugin.1.0'}
        }
    });
    
    require([
        'lib/angular',
        'test/newapp',
        'test/oldapp',
        'app',
        'services',
        'controllers',
        'filters',
        'directives'
    ],function(angular){    
        //此处引用了所需的所有模块,并且只做了一件事,用angular把页面驱动起来。
        angular.bootstrap(document,['myApp']);
    });
    

    写的过程中边看文档边做了很多尝试,总之成品就是上面那样的了,建议还是多读读文档,讲解了很多需要注意的地方。

    6,合并/压缩js文件

    同样,细读文档,你的电脑需要有node环境,同时下载了r.js,测试过程略过,看我测试通过的成品吧:
    //build.js,置于js根目录下
    ({
        baseUrl:'app',
        paths:{requireLib:'../vendor/require'},
        include:'requireLib',//如果需要把require也压进去(这样整个项目只需要一个js文件了),设置其path,并
        name:'main',
        out:'main-built-require.js',//输出的文件名
        optimize:'none',//注释掉此行即可同时把合并后的js文件压缩
        mainConfigFile:'main.js'//用已写好的main.js文件来处理模块依赖关系
    })

    运行命令(因为r.js在整个项目之外,build.js位于/js/目录下,所以跳两层跳出去:

    node ../../r.js -o app.build.js


    同级目录顺利生成main-built-require.js

    7,压缩整个项目

    还没深入研究,以下这个脚本可以把每个js和css进行压缩:
    //app.build.js
    ({
        appDir:'../',//以本文件为起点,配置项目根目录
        dir:'../../appdirectory-build',//为了不影响源码,输出到同级目录
        mainConfigFile:'main.js'//同样,入口配置文件的位置
    })

    同样的命令:

    node ../../r.js -o app.build.js


    看输出,很明显地提示了在用Uglifying压缩了每一个js文件,以及css文件(忽视对web-server.js的报错,那是为了用node把网站跑起来写的一个脚本,与本例无关)
    F:	emp
    equire_angularjs>node ../../r.js -o app.build.js
    Optimizing (standard.keepLines) CSS file: F:/temp/appdirectory-build/css/app.css
    
    Uglifying file: F:/temp/appdirectory-build/js/app/app.js
    Uglifying file: F:/temp/appdirectory-build/js/app/controllers.js
    Uglifying file: F:/temp/appdirectory-build/js/app/directives.js
    Uglifying file: F:/temp/appdirectory-build/js/app/filters.js
    Uglifying file: F:/temp/appdirectory-build/js/app/my.js
    Uglifying file: F:/temp/appdirectory-build/js/app/services.js
    Uglifying file: F:/temp/appdirectory-build/js/app.build.js
    Uglifying file: F:/temp/appdirectory-build/js/build.js
    Uglifying file: F:/temp/appdirectory-build/js/main-built-require.js
    Uglifying file: F:/temp/appdirectory-build/js/main-built-require2.js
    Uglifying file: F:/temp/appdirectory-build/js/main-built.js
    Uglifying file: F:/temp/appdirectory-build/js/main.js
    Uglifying file: F:/temp/appdirectory-build/js/test/newapp.js
    Uglifying file: F:/temp/appdirectory-build/js/test/oldapp.js
    Uglifying file: F:/temp/appdirectory-build/js/test/plugin.1.0.js
    Uglifying file: F:/temp/appdirectory-build/js/test/plugin.1.2.js
    Uglifying file: F:/temp/appdirectory-build/js/vendor/angular.js
    Uglifying file: F:/temp/appdirectory-build/js/vendor/require.js
    toTransport skipping F:/temp/appdirectory-build/web-server.js: Error: Line 1: Un
    expected token ILLEGAL
    Error: Cannot parse file: F:/temp/appdirectory-build/web-server.js for comments.
     Skipping it. Error is:
    Error: Line 1: Unexpected token ILLEGAL
    
    css/app.css
    ----------------
    css/app.css

    8,示例代码下载

    zip文件svn地址

  • 相关阅读:
    深入解析ATL 笔记1 添加一个simple object时做了什么
    分析MFC中CDialog的子类对象如何知道自己是model还是modeless的
    分析boost::signal之识别是否Trackable的派生类对象
    《转》汇编标志位
    <转> strcpy当初没有考虑到的地方
    <转>OD常用断点列表
    依赖倒转原则
    <转> xor eax, ebp” being used
    <转>NEG+SBB指令组合的用处
    函数Int3断点检测
  • 原文地址:https://www.cnblogs.com/walkerwang/p/3372284.html
Copyright © 2011-2022 走看看