(四)seajs.config中vars、alias、paths和map的作用,以及util-path路径解析源码
来源:互联网 发布:.com.cn是什么域名 编辑:程序博客网 时间:2024/06/06 04:19
这篇文章主要是学习下seajs.config中vars、alias、paths、map这4个配置参数的作用和使用方式。这4个配置都会影响一个模块最终的url路径。
alias
seajs.config({ base: 'http://www.main.com/base/', alias: { 'jquery': 'jquery/jquery/1.10.1/jquery', 'app/biz': 'http://path/to/app/biz.js', }});
define(function(require, exports, module) { var $ = require('jquery'); //=> 加载的是 http://www.main.com/base/jquery/jquery/1.10.1/jquery.js var biz = require('app/biz'); //=> 加载的是 http://path/to/app/biz.js});当模块标识很长,写起来不方便、容易出错的时候,可以使用alias来简化模块标识。在seajs.config中进行一次配置之后,所有js模块都可以用require("jquery")这种简单的方式来加载对应的模块了。使用alias,可以让文件的真实路径与模块调用标识分开,有利于统一维护。
paths
seajs.config({ base: 'http://www.main.com/base/', // 别名配置 alias: { 'hostA-jquery': 'hostA/jquery/1.10.1/jquery.js', }, paths: { 'hostA': 'https://www.shenzhen.com/sz''app': 'path/to/app' }});
define(function(require, exports, module) { var underscore = require('hostA/underscore'); //=> 加载的是 https://www.shenzhen.com/sz/underscore.js var jquery = require('hostA-jquery'); //=> 加载的是 https://www.shenzhen.com/sz/jquery/1.10.1/jquery.js var biz = require('APP/biz'); //=> 加载的是 http://www.main.com/base/path/to/app/biz.js});当目录层次比较深,或者是跨目录调用模块的时候,可以用path简化模块标识的书写。paths 配置可以结合 alias 配置一起使用,让模块引用非常方便。
vars
seajs.config({ base: 'http://www.main.com/base/', vars: { 'locale': 'zh-cn' }});
define(function(require, exports, module) { var lang = require('i18n/{locale}.js'); //=> 加载的是 http://www.main.com/base/i18n/zh-cn.js});有些场景下,模块路径在运行时才能确定,这时可以使用 vars 变量来配置。vars配置的是模块标识中的变量值,在模块标识中用 {key} 来表示变量。
map
seajs.config({ base: 'http://www.main.com/base/', 'map': [ [ /(.*?)(\.js)$/i , '$1-debug.js'] ]});
define(function(require, exports, module) { var a = require('cs/a'); //=> 加载的是 http://www.main.com/base/cs/a-debug.js});map配置主要用来做调试用途,用来做路径转换、版本号、时间戳等管理。
seajs解析模块的url,就是根据模块标识(到底是相对标识、顶级标识还是普通标识),和上面这4个配置来确定的。相关源码在util-path.js中,下面附上util-path.js中最核心部分的源码,我加了很多注释,应该很容易看懂。如果有兴趣专研,可以用seajs.resolve()来尝试一下。
/** * util-path.js - The utilities for operating path such as id, uri */ // '/'字符是正则表达式常量的边界,所以需要用'\'进行转义var DIRNAME_RE = /[^?#]*\//;// 全局匹配"/./",字符slash和dot都是特殊字符var DOT_RE = /\/\.\//g;// DOUBLE_DOT_RE.test("//../") ==>false// DOUBLE_DOT_RE.test("/as/../") ==>truevar DOUBLE_DOT_RE = /\/[^/]+\/\.\.\//;// MULTI_SLASH_RE.test("c//") ==> true// MULTI_SLASH_RE.test("///") ==> false// MULTI_SLASH_RE.test("://") ==> false// MULTI_SLASH_RE.test("c://") ==> false// "http://asb///ss".match(MULTI_SLASH_RE)[0] ==> "b///"var MULTI_SLASH_RE = /([^:/])\/+\//g;// Extract the directory portion(一部分) of a path// dirname("a/b/c.js?t=123#xx/zz") ==> "a/b/"// ref: http://jsperf.com/regex-vs-split/2function dirname(path) {//如果path不匹配正则,此时方法会报异常//没有使用/g模式,只查找第一个匹配项,match()返回的是数组 return path.match(DIRNAME_RE)[0];}// Canonicalize(规范化) a path// realpath("http://test.com/a//./b/../c") ==> "http://test.com/a/c"function realpath(path) { // /a/b/./c/./d ==> /a/b/c/d path = path.replace(DOT_RE, "/"); /* @author wh1100717 a//b/c ==> a/b/c a///b/////c ==> a/b/c DOUBLE_DOT_RE matches a/b/c//../d path correctly only if replace // with / first */ path = path.replace(MULTI_SLASH_RE, "$1/");//$1代表第一个分组内容 // a/b/c/../../d ==> a/b/../d ==> a/d // first replace "/c/../" ,then replace "/b/../" with "/" while (path.match(DOUBLE_DOT_RE)) { path = path.replace(DOUBLE_DOT_RE, "/"); } return path;}// Normalize an id// normalize("path/to/a") ==> "path/to/a.js"// normalize("a/b/c/") ==> "a/b/c"// normalize("a/b/c/?d=1") ===> "a/b/c/?d=1"// NOTICE: substring is faster than negative slice and RegExp// 看懂这个方法后,理解[http://www.zhangxinxu.com/sp/seajs/docs/zh-cn/module-identifier.html#tips]太容易了吧function normalize(path) { var last = path.length - 1; var lastC = path.charCodeAt(last); // If the uri ends with `#`, just return it without '#' if (lastC === 35 /* "#" */) { return path.substring(0, last); } return (path.substring(last - 2) === ".js" || path.indexOf("?") > 0 || lastC === 47 /* "/" */) ? path : path + ".js";}// 不能以"/"和":"开头, 结尾必须要是 "/"后面跟着任意字符(数量至少1个)// PATHS_RE.test("dd/") ==> false// PATHS_RE.test("dd/ss") ==> true// PATHS_RE.test("d:d/ss")==> false// PATHS_RE.test("/aa/ss")==> falsevar PATHS_RE = /^([^/:]+)(\/.+)$/;// 匹配变量// VARS_RE.test("{}") ==> false// VARS_RE.test("{{}") ===> false// VARS_RE.test("{as}") ===> truevar VARS_RE = /{([^{]+)}/g;// 解析seajs.config({})中的alias配置function parseAlias(id) { var alias = data.alias; return alias && isString(alias[id]) ? alias[id] : id;}function parsePaths(id) { var paths = data.paths; var m; // 当id匹配PATHS_RE的时候,m[1]代表第一个分组的内容,m[2]代表第二个分组的内容 // m[0]代表的是匹配的内容(不含分组信息,对我这里来说没有啥用) if (paths && (m = id.match(PATHS_RE)) && isString(paths[m[1]])) { id = paths[m[1]] + m[2]; } return id;}function parseVars(id) { var vars = data.vars; if (vars && id.indexOf("{") > -1) { id = id.replace(VARS_RE, function(m, key) { // m like {name}, key like name return isString(vars[key]) ? vars[key] : m; }); } return id;}// 解析config.map支持正则表达式和函数// map最佳实践:用来做版本号和时间戳管理的/*seajs.config({ map: [ ['.js', '-debug.js'] ]});*//*seajs.config({ 'map': [ [ /^(.*\.(?:css|js))(.*)$/i, '$1?20110801'] ]});*/function parseMap(uri) { var map = data.map; var ret = uri; if (map) { for (var i = 0, len = map.length; i < len; i++) { var rule = map[i] ret = isFunction(rule) ? (rule(uri) || uri) : uri.replace(rule[0], rule[1]); // Only apply the first matched rule if (ret !== uri) break; } } return ret;}// 包含":/" 或者以"//{char}"开头({char}代表任意一个字符)// ABSOLUTE_RE.test("/a") ==> falsevar ABSOLUTE_RE = /^\/\/.|:\//;// ROOT_DIR_RE.test("///") ==> true// ROOT_DIR_RE.test("sd//dd") ==>false// ROOT_DIR_RE.test("sd//dd/") ==>true// ROOT_DIR_RE.test("http://127.0.0.1:8080/s/") ==> true// ROOT_DIR_RE.test("http://127.0.0.1:8080/s") ==> truevar ROOT_DIR_RE = /^.*?\/\/.*?\//;function addBase(id, refUri) { var ret; var first = id.charCodeAt(0); // Absolute if (ABSOLUTE_RE.test(id)) { ret = id; } // Relative else if (first === 46 /* "." */) { ret = (refUri ? dirname(refUri) : data.cwd) + id; } // Root else if (first === 47 /* "/" */) { var m = data.cwd.match(ROOT_DIR_RE); ret = m ? m[0] + id.substring(1) : id; } // Top-level else { ret = data.base + id; } // Add default protocol when uri begins with "//" if (ret.indexOf("//") === 0) { ret = location.protocol + ret; } return realpath(ret);}function id2Uri(id, refUri) { if (!id) return ""; id = parseAlias(id); id = parsePaths(id); id = parseAlias(id); id = parseVars(id); id = parseAlias(id); id = normalize(id); id = parseAlias(id); var uri = addBase(id, refUri); uri = parseAlias(uri); uri = parseMap(uri); return uri;}// For Developersseajs.resolve = id2Uri;
可以看到id2Uri这个方法在不停的处理alias、paths、vars、map,有兴趣的可以去专研。util-path.js核心就是一堆正则表达式,上面已经加了很多注释。
1 0
- (四)seajs.config中vars、alias、paths和map的作用,以及util-path路径解析源码
- Seajs源码解析系列(四)
- Shiro中自定义Realm的作用(FormAuthenticationFilter和PermissionAuthorizationFilter)以及源码解析
- seajs 路径解析过程
- 支持seaJs和requireJs的前端模块开发方案(四):AMD模式和CMD模式下的config.js
- 环境变量中path和classpath的作用
- 环境变量中path和classpath的作用
- 环境变量中Path和classpath的作用
- 环境变量中path和classpath的作用
- python里使用vars()返回当前局部作用域的所有成员函数和成员变量
- 设置环境变量的作用以及path和classpath的区别
- java中classpath、path、JAVA_HOME的设置以及作用
- Ehcache 中diskStore path 的作用以及说明
- Seajs源码解析系列(三)
- tomcat源码解析(四)--请求过程之路径的匹配
- (一)页面中引入seajs以及模块的加载和启动
- Extjs alias的作用
- python dir()和vars()的区别
- Mysql检查列是否存在并新增、修改、删除列
- hadoop编译的本地库会依赖操作系统吗?比如amd64的系统编译的可以在其他X86OS上工作吗??hadoop本地库与系统版本不一致
- Event原理解析
- 编辑删除收藏在tableView的内容
- DisplayMetrics简介
- (四)seajs.config中vars、alias、paths和map的作用,以及util-path路径解析源码
- 常成员变量数组初始化的问题
- ACE_POSIX_AIOCB_Proactor和ACE_WIN32_Proactor的区别
- 进一步体会到面对对象
- iOS开发 实战篇---Xcode7免费真机测试流程
- 按钮写到UItableView的头视图还是列表之外
- UI资料
- Java的StringBuffer类
- 【codevs 2975】与2,3,5无关的数