zoukankan      html  css  js  c++  java
  • RequireJS初探

    什么是RequireJS?

    /* ---

    RequireJS 是一个JavaScript模块加载器。它非常适合在浏览器中使用, 它非常适合在浏览器中使用,但它也可以用在其他脚本环境, 就像 Rhino and Node. 使用RequireJS加载模块化脚本将提高代码的加载速度和质量。

    IE 6+ .......... 兼容 ✔
    Firefox 2+ ..... 兼容 ✔
    Safari 3.2+ .... 兼容 ✔
    Chrome 3+ ...... 兼容 ✔
    Opera 10+ ...... 兼容 ✔

    开始使用 或者看看 API

    --- */

    http://www.requirejs.cn/home.html

    https://github.com/jrburke/requirejs

    一句话, 它是为了JS模块化而生,是代码逻辑封装的手段,  目的是为了减少代码复杂度,提高代码可维护性, 满足设计上要求的高内聚+低耦合。

    为浏览器环境而生,提高js加载速度。

    为什么要有RequireJS?

    http://www.requirejs.cn/docs/why.html

    遇到的问题

    • Web sites are turning into Web apps
    • Code complexity grows as the site gets bigger
    • Assembly gets harder
    • Developer wants discrete JS files/modules
    • Deployment wants optimized code in just one or a few HTTP calls

    ---- 翻译 ----

    1、 web站点转变为 web应用

    2、代码复杂度随着站点的变大而增长

    3、组装(页面代码)更加困难

    4、开发者需要分离js文件和模块

    5、部署活动需要优化过的代码存储在一个文件中, 或者少些HTTP请求。

    解决方案:

    Front-end developers need a solution with:

    • Some sort of #include/import/require
    • ability to load nested dependencies
    • ease of use for developer but then backed by an optimization tool that helps deployment

    ---- 翻译 ----

    前端开发者需要一个满足如下条件的解决方案:

    1、一些类似 include import require 等经典模块方法

    2、有能力加载嵌套依赖

    3、对于开发者易用, 同时也可以被(用于部署的)优化工具支持。

    ---- 模块化进化史 -----

    原始

    -在一个页面还很简单的时候, 一个同事添加了一个js函数  function xx

    后由于新增需求, 另外一个同事处于另外目的, 添加了一个相同名称的函数 function xx, 内容实现不一样, 这样就悲剧了, 第一个同事实现的 函数被冲掉了, 因为它们都定义在 全局环境中。

    IIFE == imediately invoked function expression  立刻执行函数表达式

    组织规范要求, 每个人开发的相关内容做为一个模块, 必须放在一个IIFE的函数体中,

    (fuction(){

         funciton XX(){}

    })();

    这样两个同事开发代码都不会相互影响对方, 但是这样定义的函数, 不能再全局环境的其他代码中调用, 因为在IIFE中的函数只在其函数体中生效, 可以作为window一个属性开放出去,

    但是其仍然有个缺点, 就是两个模块之间的依赖无法体现, 如果后面一个同事的开发模块, 依赖前一个同事的, 这样后面同事写的代码必须在 前一个同事代码 之后, 否则就会调用失败。

    module时代

    随着web页面内容越来越大, 前端代码越来越复杂,且有复杂的代码依赖关系。 就需要今天的主题事物出场。

    AMD vs CommonJS

    模块化标准包括 commonjs和requirejs, requireJS满足AMD标准, 为啥采用AMD?

    因为主要是此标准为异步加载设计, 故适合浏览器远程加载若干模块的js文件。

    而commonjs标准,加载文件为同步模式, 一个一个执行, 适合加载本地文件, nodejs实现满足此标准。

    两个标准的详细描述见:

    http://www.commonjs.org/

    http://www.requirejs.org/docs/whyamd.html

    怎么使用RequireJS?

    http://requirejs.org/docs/api.html

    定义模块,新建一个文件, 按照api规范定义模块实现, 模块返回为对象

    //Inside file my/shirt.js:
    define({
        color: "black",
        size: "unisize"
    });

    如果还有些定制逻辑,则有可以使用函数,作为模块实现作用域:

    //my/shirt.js now does setup work
    //before returning its module definition.
    define(function () {
        //Do setup work here
    
        return {
            color: "black",
            size: "unisize"
        }
    });
     

    如果模块对其他模块有依赖

    //my/shirt.js now has some dependencies, a cart and inventory
    //module in the same directory as shirt.js
    define(["./cart", "./inventory"], function(cart, inventory) {
            //return an object to define the "my/shirt" module.
            return {
                color: "blue",
                size: "large",
                addToCart: function() {
                    inventory.decrement(this);
                    cart.add(this);
                }
            }
        }
    );

    模块也可以返回函数

    //A module definition inside foo/title.js. It uses
    //my/cart and my/inventory modules from before,
    //but since foo/title.js is in a different directory than
    //the "my" modules, it uses the "my" in the module dependency
    //name to find them. The "my" part of the name can be mapped
    //to any directory, but by default, it is assumed to be a
    //sibling to the "foo" directory.
    define(["my/cart", "my/inventory"],
        function(cart, inventory) {
            //return a function to define "foo/title".
            //It gets or sets the window title.
            return function(title) {
                return title ? (window.title = title) :
                       inventory.storeName + ' ' + cart.name;
            }
        }
    );

    还可以自定义模块名称

        //Explicitly defines the "foo/title" module:
        define("foo/title",
            ["my/cart", "my/inventory"],
            function(cart, inventory) {
                //Define foo/title object in here.
           }
        );

    DEMO

    定义了两个模块, 和一个app, 依赖两个模块, 调用并执行:

    https://github.com/fanqingsong/code-snippet/tree/master/web

    image

    one.js

    //Inside one.js:
    define(function() {
            return function(title) {
                return console.log('one module called');
            }
        }
    );

    two.js

    //Inside two.js:
    define(function() {
            return function(title) {
                return console.log('two module called');
            }
        }
    );

    app.js

    requirejs.config({
        //By default load any module IDs from ./
        baseUrl: './',
    });

    // Start the main app logic.
    requirejs(['one', 'two'],
    function   (one, two) {
        one();
        two();
    });

    demo.html

    <html>
    <head>
            <!--This sets the baseUrl to the "scripts" directory, and
                loads a script that will have a module ID of 'main'-->
            <script data-main="./app.js" src="./require.js"></script>
            <style>

            </style>
    </head>
    <body>
            <h1>hello world!</h1>
    </body>
    </html>

    打印:

    image

  • 相关阅读:
    NOIP2011 D1T1 铺地毯
    NOIP2013 D1T3 货车运输 倍增LCA OR 并查集按秩合并
    POJ 2513 trie树+并查集判断无向图的欧拉路
    599. Minimum Index Sum of Two Lists
    594. Longest Harmonious Subsequence
    575. Distribute Candies
    554. Brick Wall
    535. Encode and Decode TinyURL(rand and srand)
    525. Contiguous Array
    500. Keyboard Row
  • 原文地址:https://www.cnblogs.com/lightsong/p/4719750.html
Copyright © 2011-2022 走看看