JSON

seajs实用教程(三) 生产环境

字号+ 作者:H5之家 来源:H5之家 2015-11-24 19:19 我要评论( )

seajs实用教程(三) 生产环境

相信大家现在已经能够用seajs完成一个项目了,但是此时的项目离正式上线还有很多差距,还需做很多优化,譬如,优化请求次数,优化文件大小。

当你使用seajs愉快的编码的时候,你也就会发现模块实在是太多了,请求数目过多这一问题。在这章,我们来共同探讨一下怎么优化seajs工程,使之真正可以达到可以上线的标准。

在进行优化以前,我们先讨论一下seajs里边的模块ID,还记得前面说过CMD的模块定义吗?define(id?deps?,factory),这里边的模块ID,官方建议我们不要写,通过工具去生成,那么你知道这个id是怎么生成的,通过什么规则呢?

这节我们就来看看这个module ID。

先看看我们会在哪里都会用到module ID。三个地方,

define(id[1],['id[2]'],function(require){ var a = require("id"[3]); })

无论是define第一个参数【模块ID】还是第二个参数【依赖模块的ID】还是【require模块ID】,最终的比对标准是【解析后的文件URI】。 因此,这三处需要写ID 的地方可以以任意一种方式来写,只要最终解析为同一个URI,即被认为是同一个模块。

Sea.js 的一个基本约定原则:ID 和路径匹配原则。

所谓 ID 和路径匹配原则 是指,使用 seajs.use 或 require 进行引用的文件,如果是具名模块(即定义了 ID 的模块),会把 ID 和 seajs.use 的路径名进行匹配,如果一致,则正确执行模块返回结果。反之,则返回 null。例如:

define('path/module/a',[],function(require){ }) 在该例中,模块ID定义为了path/moudle/a,那么a模块应该正确放置的位置就base(在config中定义的)/path/moudle/a.js,假如a.js不在该位置,则返回了null。

至于为什么一定要使用一定要把 ID 定为文件路径,这一块请移步 https://github.com/seajs/seajs/issues/930

 

这节课我们来看看文件合并,主要是通过一个例子来看看。例子使用的是seajs官网提供的helloword。 先看看文件结构如下。

├── hello.html └── static └── js ├── lib │   ├── jquery │   │   ├── easing │   │   │   └── 1.3.0 │   │   │   ├── easing-debug.js │   │   │   ├── easing.js │   │   │   └── package.json │   │   └── jquery │   │   └── 1.10.1 │   │   ├── jquery-debug.js │   │   ├── jquery.js │   │   └── package.json │   └── seajs │   └── seajs │   ├── 2.1.0 │   │   ├── package.json │   │   ├── sea-debug.js │   │   ├── sea.js │   │   └── sea.js.map │   ├── 2.1.1 │   │   ├── package.json │   │   ├── sea-debug.js │   │   ├── sea.js │   │   └── sea.js.map │   └── 2.2.0 │   ├── package.json │   ├── sea-debug.js │   └── sea.js └── src ├── main.js ├── spinning.js └── style.css

看看hello.html中的代码

seajs.config({ base: "./static/js/", alias: { "jquery": "lib/jquery/jquery/1.10.1/jquery.js" }, map:[ ["jquery.js","jquery-debug.js"] ], debug:2 }); seajs.use("./static/js/src/main.js",function(){ console.log("init"); });

看这里边的map定义,jquery请求成了jquery-debug.js,

尝试下你把map去掉后你会发现程序运行不了。提示错误

spinning.js:6 Uncaught TypeError: $ is not a function

为什么会出错呢,查看下jquery.js代码,你会发现这句话

"function" == typeof define && define("jquery/jquery/1.10.1/jquery", [], function() { ... })

这里的jquery已经是具名模块了,id为"jquery/jquery/1.10.1/jquery",在spining.js中

var $ = require('jquery');

为什么报错,我猜你已经猜出,因为 Seajs 本身的约定: ID 和路径匹配原则,不了解的查看上一课时。

那么怎么修改呢?

  • 移动文件位置: 把lib/jquery 移到上一级目录
  • 修改jquery.js: 把里边的id jquery/jquery/1.10.1/jquery 变为lib/jquery/jquery/1.10.1/jquery
  • 合并文件

    我们先尝试下自己手动合并,将原理搞清楚。这个例子请求了两个js,main.js和spinging.js。 那么就需要把这两个文件放到一个文件中。

    我们先在static/js/中新建一个目录dist目录,在文件中我们新建一个main.js文件,将src中的main.js,和spinging.js拷贝过来粘贴。

    此时dist/main.js代码如下:

    define(function(require) { var Spinning = require('../src/spinning'); var s = new Spinning('#container'); s.render(); }); define(function(require, exports, module) { var $ = require('jquery'); ... });

    修改hello.html中seajs.use("./static/js/dist/main.js");

    这样执行肯定会报错,错在哪里了哪?

    错在了seajs.use已经分不清楚你要使用的是那个模块了,就相当于c语言里边找不到main函数了。怎么修改呢?为方便说明,这里的mian.js spinning.js指的是dist/main.js 里边分别copy过来的内容。

    方法1:给main.js部分增加module_id,spining

    define(‘dist/main’,function(require) { var Spinning = require('../src/spinning'); var s = new Spinning('#container'); s.render(); });

    方法2:main代码不动,将spinning代码改动下,增加module_id

    define('spinning',function(require, exports, module) { var $ = require('jquery'); ... });

    大家看到这里也就明白了,给main代码里增加module_id,此时seajs.use也就会调用到该模块,该模块为主模块。

    第二种方法里,除主模块意外所有模块增加moduleid的话,seajs.use使用的没有moduleid的模块。

    注意:1. 在第一种方法里,模块id必须和路径对应起来。2.当给define函数增加deps,必须包含factory里边require引用的所有模块,否则会报错。

    看到这里,看起来文件是合并到一起了,但是当右键查看审查元素中network,发现了还是去请求了../src/spinning.js。多了此请求。

    看上面的源码也就发现了问题所在,需要修改main.js里边的 require('../src/spinning') 为 require('../src/spinning'),把spinning.js里边的module_id就可以了。再次查看确实没有请求spinning.js文件了。

    在这里确实也打破了seajs的ID 和路径匹配原则,也就是该原则是可以被打破的。但是为什么不建议打破呢?

    这样就很麻烦了,当多人开发的时候,大家都自己定义module_id,很可能重名,以后合并时候太容易出问题了。

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • php CI 实战教程:[5]用curl获取json并解析

      php CI 实战教程:[5]用curl获取json并解析

      2016-02-26 17:00

    • Android中JSON数据格式读取解析创建视频教程

      Android中JSON数据格式读取解析创建视频教程

      2016-02-05 19:00

    • HttpClient 4.3教程 第一章 基本概念

      HttpClient 4.3教程 第一章 基本概念

      2016-01-26 16:49

    • 实用的javascript小技巧

      实用的javascript小技巧

      2016-01-25 19:05

    网友点评