seajs学习--module-id 规范

大家相信现在已经能够用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
]()

###在详细的讨论下 Module_ID的解析规则

Sea.js 中的模块标识是 CommonJS 模块标识 的超集:

* 一个模块标识由斜线(/)分隔的多项组成。
* 每一项必须是小驼峰字符串、 . 或 .. 。
* 模块标识可以不包含文件后缀名,比如 .js 。
* 模块标识可以是 相对 或 顶级 标识。如果第一项是 . 或 ..,则该模块标识是相对标识。
* 顶级标识根据模块系统的基础路径来解析。
* 相对标识相对 require 所在模块的路径来解析。

注意,符合上述规范的标识肯定是 Sea.js 的模块标识,但 Sea.js 能识别的模块标识不需要完全符合以上规范。 比如,除了大小写字母组成的小驼峰字符串,Sea.js 的模块标识字符串还可以包含下划线(_)和连字符(-), 甚至可以是 http://、https://、file:/// 等协议开头的绝对路径。

相对标识

相对标识以 . 开头,只出现在模块环境中(define 的 factory 方法里面)。相对标识永远相对当前模块的 URI 来解析:

// 在 http://example.com/js/a.js 的 factory 中:
    require.resolve(‘./b‘);
      // => http://example.com/js/b.js

// 在 http://example.com/js/a.js 的 factory 中:
    require.resolve(‘../c‘);
      // => http://example.com/c.js
    顶级标识

顶级标识不以点(.)或斜线(/)开始, 会相对模块系统的基础路径(即 Sea.js 的 base 路径)来解析:

// 假设 base 路径是:http://example.com/assets/

// 在模块代码里:
    require.resolve(‘gallery/jquery/1.9.1/jquery‘);
      // => http://example.com/assets/gallery/jquery/1.9.1/jquery.js
  
模块系统的基础路径即 base 的默认值,与 sea.js 的访问路径相关:

如果 sea.js 的访问路径是:
      http://example.com/assets/sea.js

则 base 路径为:
      http://example.com/assets/
    当 sea.js 的访问路径中含有版本号时,base 不会包含 seajs/x.y.z 字串。 当 sea.js 有多个版本时,这样会很方便。

如果 sea.js 的路径是:
      http://example.com/assets/seajs/1.0.0/sea.js

则 base 路径是:
      http://example.com/assets/
    当然,也可以手工配置 base 路径:

seajs.config({
      base: ‘http://code.jquery.com/‘
    });

// 在模块代码里:
    require.resolve(‘jquery‘);
      // => http://code.jquery.com/jquery.js
  
####普通路径

除了相对和顶级标识之外的标识都是普通路径。普通路径的解析规则,和 HTML 代码中的 <script src="..."></script> 一样,会相对当前页面解析。

// 假设当前页面是 http://example.com/path/to/page/index.html

// 绝对路径是普通路径:
    require.resolve(‘http://cdn.com/js/a‘);
      // => http://cdn.com/js/a.js

// 根路径是普通路径:
    require.resolve(‘/js/b‘);
      // => http://example.com/js/b.js

// use 中的相对路径始终是普通路径:
    seajs.use(‘./c‘);
      // => 加载的是 http://example.com/path/to/page/c.js

seajs.use(‘../d‘);
      // => 加载的是 http://example.com/path/to/d.js
      
提示:

顶级标识始终相对 base 基础路径解析。
绝对路径和根路径始终相对当前页面解析。
require 和 require.async 中的相对路径相对当前模块路径来解析。
seajs.use 中的相对路径始终相对当前页面来解析。
文件后缀的自动添加规则

Sea.js 在解析模块标识时, 除非在路径中有问号(?)或最后一个字符是井号(#),否则都会自动添加 JS 扩展名(.js)。如果不想自动添加扩展名,可以在路径末尾加上井号(#)。

// ".js" 后缀可以省略:
    require.resolve(‘http://example.com/js/a‘);
    require.resolve(‘http://example.com/js/a.js‘);
      // => http://example.com/js/a.js

// ".css" 后缀不可省略:
    require.resolve(‘http://example.com/css/a.css‘);
      // => http://example.com/css/a.css

// 当路径中有问号("?")时,不会自动添加后缀:
    require.resolve(‘http://example.com/js/a.json?callback=define‘);
      // => http://example.com/js/a.json?callback=define

// 当路径以井号("#")结尾时,不会自动添加后缀,且在解析时,会自动去掉井号:
    require.resolve(‘http://example.com/js/a.json#‘);
      // => http://example.com/js/a.json
      
####设计原则

模块标识的规则就上面这些,设计的核心出发点是:

关注度分离。比如书写模块 a.js 时,如果需要引用 b.js,则只需要知道 b.js 相对 a.js 的相对路径即可,无需关注其他。

尽量与浏览器的解析规则一致。比如根路径(/xx/zz)、绝对路径、以及传给 use 方法的非顶级标识,都是相对所在页面的 URL 进行解析。

时间: 2024-11-08 22:19:06

seajs学习--module-id 规范的相关文章

模块化之seaJs学习和使用

使用seaJs也有一阵子了,一直也想抽个时间写个这方面的博客,直到今天才写--也许写的不是很完善,但跟大伙分享也是一种乐趣,不对之处欢迎指出.[抱拳] 时间有限,我这里不过多介绍前端模块化,有兴趣可以去了解. 一.写在前面 seaJs出自前端工程师玉伯之手,一个文件就是一个模块,实现JavaScript的模块化及按模块加载.使用SeaJS可以提高JavaScript代码的可读性和清晰度,确保各个JS文件先后加载的顺序,解决目前JavaScript编程中普遍存在的依赖关系混乱和代码纠缠等问题,方便

seajs学习笔记(基础)

一:前端开发中常遇到的问题       如果我们的网站简单的时候,结构上也许不会有什么问题,但是如果我们的网站越来复杂的时候(比如功能越来越多的时候,加入项目的人越来越多的时候),我们书写的代码就会遇到下面的两个问题: 1. 恼人的命名冲突 比如我们多人开发一个项目,事先由我自己写好了一个共公的组件库common.js供大家调用,里面的包括 function tab(){ 实现代码: }; function drag(){ 实现代码: }; function dialog(){ 实现代码: };

seajs 学习笔记

seajs的作者是玉伯,具体好处优点等详见官方网址 介绍 1 模块定义define define(function(require,exports,module){ //require 引入需要的模块如jquery等 //var $ = require('./jquery'); //exports可以把方法或属性暴露给外部 exports.name = 'hi'; exports.hi = function(){ alert('hello'); } //module提供了模块信息 }); 2 使

seajs学习笔记

一.使用SeaJS开发JavaScript的基本原则就是:一切皆为模块.引入SeaJS后,编写JavaScript代码就变成了编写一个又一个模块,SeaJS中模块的概念有点类似于面向对象中的类——模块可以拥有数据和方法,数据和方法可以定义为公共或私有,公共数据和方法可以供别的模块调用.每个模块应该都定义在一个单独js文件中,即一个对应一个模块. 二.模块的定义和编写 fn.define = function(id, deps, factory) { //code of function… } 如

seaJs学习笔记2 – seaJs组建库的使用

原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最近在学习seaJs和AngualrJs的指令和服务,感觉angularjs实在太强大了,好吧,步入主题,今天在深入了解seaJs的时候发现了一款神器,不过这款神奇貌似没有更新和维护了,但我测试了一下,还是可以用的. 这款神奇就是SeaJS 组件库 ,Sea.js 是一个适用于 Web 浏览器端的模块

selenium webdriver学习--通过id、name定位,输入内容,搜索,关闭操作

selenium webdriver学习--通过id.name定位,输入内容,搜索,关闭操作: 打开谷歌浏览器,输入不同的网站,搜索框的定位含有不同元素(有时为id,有时为name) import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.chrome.ChromeDriver; impor

seajs学习一天后的总结归纳

公司项目最近需要将js文件迁移到seajs来进行模块化管理,由于我以前主要接触模块化开发是接触的AMD规范的requireJS,没有接触过CMD规范,而且在实际项目中还没有用过类似技术. 于是,我非常兴奋的开始了seajs的学习,正好对模块化开发仰慕已久,终于有机会大展身手了! 一开始总是有点曲折的,我照着玉伯的github上的教程一步步来,然后发现在我引入jquery的时候,require到的jquery竟然是undefined 经过一番摸索,我发现原来jquery是基于amd规范的,seaj

自学了三天的SeaJs学习,解决了前端的一些问题,与小伙伴们一起分享一下!

我为什么学习SeaJs ? [第一]:为了解决项目中资源文件版本号的问题,以及打包压缩合并等问题. [第二]:好奇心和求知欲.[我发现很多知名网站也都在使用( qq空间 , msn ,淘宝 等等),而且 SeaJs 也得到了很好的推广与应用]. [第三]:经过了解得知 淘宝的 玉伯 是 湖南炎陵 人,觉得他很牛X. [强烈]给小伙伴们推荐一个   玉伯   的讲的 SeaJs PDF 学习资料,下载地址:http://pan.baidu.com/s/1CCz4C 第一步 [ 版本号问题的解决] 

SeaJS 学习

什么是系统 在生活和工作中,我们会接触到大量系统:自然界生态系统.计算机操作系统.软件办公系统,还有教育系统.金融系统.网络系统.理论系统等等.究竟什么是系统呢? 来看下维基百科的解释: 系统泛指由一群有关连的个体组成,根据预先编排好的规则工作,能完成个别元件不能单独完成的工作的群体.系统分为自然系统与人为系统两大类. 简言之,系统有两个基本特性: 系统由个体组成. 个体之间有关连,按照规则协同完成任务. 系统中的个体可称之为系统成员,这样,要构建一个系统,最基本层面需要做两件事: 定义系统成员