zoukankan      html  css  js  c++  java
  • seajs的那些坑

    seajs是what?

    先看段代码:
    1 var loder = {};
    2 var define = loder.define = function(id,deps,factory){
    3       loader[id] = factory;
    4 };
    上述代码干了什么?这就是一个最简单的加载器,但离实际应用还有很大差距,需要添加很多功能,seajs就是一个成熟的方案。
     
    当一个页面集合了越来越多的js,这些js由不同的小组维护而且js包含了众多的组件,于是相同的函数可能命名冲突,为了解决命名冲突,大家可能会加上命名空间,记忆命名空间是一个负担,另外各种组件之间的引用,造成了复杂的依赖的关系,如何管理好依赖文件的加载问题也是个烦恼的问题。
     
    seajs很好地解决了命名空间,依赖等问题。简单的说seajs是模块加载器,它将命名空间、组件解释为模块。按照seajs规则编写的代码符合CMD规范,使用它有两个好处:二是让模块定义变得简单,二是让模块发布变得简单。它是如何做到的这两方面的?
    1. 首先模块定义的方式,模块源代码中是这样编写模块的define(factory),非常简单,但是如果直接合并合并后多个define就会造成不知道如何引用具体的模块,于是涉及到第二个部分,如何让模块发布过程变得简单。
    2. 模块提取过程是,将源代码转换成seajs能正确解释的代码,即define(id,deps,factory)需要借助于grunt-cmd-transport或spm-build工具。
    让这两个方面变得简单的秘诀在于seajs采用了路径即模块标识,于是在提取依赖过程中,根据模块标识找到依赖模块的文件将其合并,并且将模块定义转换为这种形式define(id,deps,factory)。上线后的代码中define(id,deps,factory)的id和deps模块标识用的是路径,根据路径即模块标识,就可以找到相应的完整模块标识。
     

    模块标识

    seajs的模块定义方式非常simple,主要的难点在于不同项目有不同的部署要求,因此会因为模块标识理解不够造成进入各种坑。下面详细分析下模块标识!
    模块标识命名规则
    1. 一个模块标识由斜线(/)分隔的多项组成。
    2. 每一项必须是小驼峰字符串、 . 或 .. 。
    3. 模块标识可以不包含文件后缀名,比如 .js 。
    4. 模块标识可以是 相对 或 顶级 标识。如果第一项是 . 或 ..,则该模块标识是相对标识
    解释一下其中的几种概念
    1. 相对路径,以. 或 ..开头
    2. 顶级路径,不以.或 ..及斜线(/)开头
    3. 普通路径,除相对和顶级路径外的,比如/(根路径)开头的,"http://""https://""file:///" 等协议标识开头的
    4. 模块命名空间是seajs所在文件的根路径即所谓的base路径,去除了seajs/x.y.z 字串,也可以指定seajs.config({base:});
    模块依赖提取过程如何解析?
    1. 只提取相对标识
    2. 相对标识相对 require 所在模块的标识来解析
    上线后模块标识解析规则?
    1. 顶级标识始终相对 base 基础路径解析。(顶级标识由字符串开头)
    2. 绝对路径和根路径,即普通路径,始终相对当前页面解析,跟我们平时用的其他js和css路径一样,比如当前页面是www.simple.com/user/index.html  ,路径为/js/hello.js,它解析后的地址为www.simple.com/js/hello.js。
    3. 模块定义中require 和 require.async 的相对路径相对当前模块路径来解析。

    如果我们能理解其模块标识解析设计的出发点,那么就可以轻易的理解这些而不用记忆这么多:

    1. 关注度分离。书写模块的时候我们是不用指定模块id的,require的模块时候只要填入依赖模块的相对路径,于是我们只要关注代码的书写而不是依赖,打包后工具会自动帮我们处理好模块id。
    2. 尽量与浏览器的解析规则一致。上线后在浏览器中的代码,模块路径的解析规则应该于平时用的css、js这些加载路径规则一样,普通路径和相对路径的都是相对当前页面的。

     示例

    目录结构如下:

    www 
    --app --blog index.html --sea-modules --seajs
    --2.2.0
    sea.js
    --blog
    --user
    --1.0.0
    main.js
    --static
    --user
    --src
    a.js
    b.js
    main.js
    --dist
    main.js
    package.json
    Makefile

    //   /www/static/user/src/a.js
    define(function(require,exports,module){
         module.exports = function(){
             //  ..........................
         };
    });   
    //   /www/static/user/src/b.js
    define(function(require,exports,module){
         module.exports = function(){
             //  ..........................
         };
    });   
    //   /www/static/user/src/main.js
    define(function(require,exports,module){
         var a = require('./a");
         var b = require('./b");
    // ..............
     }); 
    //  /www/static/user/package.json
    {
          family:"blog",
          name:"user",
          version:"1.0.0",
          spm:{
                output:["main.js"]
          }
    }    
     
    // /www/static/user/Makefile
    build: @spm build deploy: @rm
    -rf ../../sea-modules/blog/user @mkdir ../../sea-modules/blog/user @mkdir ../../sea-modules/blog/user/1.0.0 @cp dist/*.* ../../sea-modules/blog/user/1.0.0 @echo @echo " deploy to seajs-modules/blog/user/1.0.0" @echo
    使用spm-build构建项目:
    cd /www/static/user ; spm-build --encoding gbk
    会在/www/static/user/dist 下生成 main.js 和 main-debug.js,main.js大概是这样的
    // /www/static/user/dist/main.js
    define("blog/user/1.0.0/main",["./a","./b"],function(require){ var a = require('./a"); var b = require('./b"); }); define("blog/user/1.0.0/a",[],function(require,exports,module){ // ....................... }); define("blog/user/1.0.0/b",[],function(require,exports,module){ // ....................... });

    然后运行make deploy

    会将 ../dist/main 部署到 /www/sea-modules/blog/user/1.0.0/main.js

    在页面中如何加载模块呢?

    <!--    www.expample.com/app/blog/index.html     -->
    <script src="/sea-modules/seajs/2.4.0/sea.js" id="seajson"></script>
    <script>
         seajs.config({charset:"gbk"});
         seajs.use("blog/user/1.0.0/main");
    </script>

     参考阅读:

  • 相关阅读:
    t
    bert4keras
    embeding应用-airbnb推荐
    The Neural Autoregressive Distribution Estimator
    3.redis desktop manager--redis 可视化工具安装及使用
    Day06作业(postman接口测试)
    DRF学习day01(web应用模式,api接口,RESTful API规范,序列化,Django Rest_Framework)
    restFul接口设计规范
    Vue学习之荏苒资讯项目(一)
    微信小程序开发四:Promise的使用,解决回调地狱
  • 原文地址:https://www.cnblogs.com/xuntu/p/3799988.html
Copyright © 2011-2022 走看看