使用FIS3解决seajs中模块的路径匹配问题

最近使用seajs开发的时候遇到一些问题,在此记录一下分享给大家。

模块定义

遵循seajs规范,模块化的js需要使用define函数定义,一个js文件即一个模块。define(id, deps, factory) 函数包括三个参数:iddeps、factory,其中id是模块的id,deps是模块的依赖。

模块ID定义

一般我们用js文件的路径来定义模块,如下:

define('src/mod1/demo', function(require, exports, module) {
  ...
});

在页面引入模块的时候使用seajs.use函数,需要使用模块的 id 引入模块,如下:

seajs.use(['src/mod1/demo'],function (demo) {
    ...
});

此时不得不说seajs中的模块路径规则,seajs要求模块的ID与路径匹配。 如果 seajs.userequire 引用的是不具名模块(未定义了 ID 的模块),则只需要填入模块文件的相对路径即可。 但是如果是引用具名模块(定义了 ID 的模块),会把 ID 和 seajs.use 函数中引用的路径名进行匹配,如果一致,则正确执行模块返回结果。反之,则返回 null。所以,如果想要定义模块的ID,最好与其绝对路径保持一致。
如果想随意定义模块ID,可以在页面中单独用<script>标签引入该模块文件,也可以通过seajs.use函数引入模块,但是这样做违背了seajs按需加载的机制,让js模块化失去意义。

模块间依赖注入

模块之间可以相互依赖,deps是模块的依赖,在deps中添加模块的ID,在加载模块之前会预先加载deps中的资源。如果define函数中deps参数为空,则在该模块被加载之前,会把整个js文件toString,解析为字符串后通过正则匹配,将所有的require()函数中的模块ID以String形式取出来,预先加载资源。
所以当deps参数为空时,不管require()函数出现何处(甚至是注释),都会被当做模块需要的资源预先加载。可想而知,此时require()也不可带变量,这样是获取不到资源的。

现针对上面的列举两种情况,逻辑一致,都是动态给 test2 赋值,但是得到结果却不一致。
1)第一种情况如下,会预先加载./mod1/test1.js./mod1/test2.js./mod2/test2.js。得到的test2为./mod1/test2'

define(function(require, exports, module) {
  'use strict'

  var test1 = require('./mod1/test1')
  var test2

  if(test1){
        test2 = require('./mod1/test2')
  }else{
        test2 = require('./mod2/test2')
  }
 ...
});

2)第二种情况如下,只会预先加载./mod1/test1.js,故得到的test2为null

define(function(require, exports, module) {
  'use strict'

  var test1 = require('./mod1/test1')
  var path

  if(test1){
        path = './mod1/test2'
  }else{
        path = './mod2/test2'
  }
  var test2 = require(path)
  ...
});

使用seajs-combo进行js资源合并

在前端工程中,经常会将前端资源合并,从而达到减少HTTP请求而提升前端性能。seajs也支持资源合并,使用 seajs-combo 插件,配合服务器的 nginx-http-concat 服务,可自动对同一批次的多个模块进行合并下载。
使用combo把模块化的js合并起来,要求每一个模块必须定义ID,遵循路径即ID的原则。
虽然seajs的规范比较简单且容易遵循,但是在一个前端工程中,往往开发环境的文件路径,和经过打包之后的实际环境的文件路径,不一定是一致的。
注意:combo功能需要配合nginx使用

使用FIS3进行打包

FIS3官网是这样介绍:FIS3 是面向前端的工程构建工具。解决前端工程中性能优化、资源加载(异步、同步、按需、预加载、依赖管理、合并、内嵌)、模块化开发、自动化工具、开发规范、代码部署等问题。
个人简单理解为一款前端打包工具。
FIS3支持cmd的模块化开发,帮我们解决模块路径的问题,使用我们在开发过程中不需再考虑头疼的路径问题,也可以完美的结合combo插件进行前端资源合并。安装FIS3参考官网,cmd插件参考使用文档

fis-conf.js配置文件

安装完FIS3和fis3-hook-cmd后,在工程根目录下创建FIS3配置文件fis-conf.js

project
│   fis-conf.js
│   index.html
│   ...
│
└─── src
│   │   
│   └─── mod1
│   │    │   test1.js
│   │    │   test2.js
│   │    │   ...
│   │
│   └─── mod2
│   │    │   test3.js
│   │    │   test4.js
│   │    │   ...
│   │
│   └─── ...
│       
└─── ...

关于FIS3配置文件,需要注意标明那些文件是模块化的js文件

fis.match('/src/**.js', { // 需要对目标文件设置 isMod 属性,说明这些文件是模块化代码。
  isMod: true
})

fis.hook('cmd', {
  baseUrl: '.' // 默认为 . 即项目根目录。用来配置模块查找根目录。
})

在更目录下打开命令行,使用FIS3打包代码,可参考FIS3命令

fis3 release -d ./dist

下图为index.html打包前后的对比,可以看到打包前seajs.use中模块ID写为相对路径,而打包之后变为绝对路径。


index.html.jpg

下图为demo.js打包前后的对比,可以看到打包前模块ID和模块依赖未定义,require()函数中路径为相对路径。打包之后,模块ID被定义为文件的绝对路径,原文件中require函数中的资源ID也变为绝对路径,并且通过deps形式注入依赖。


demo.js.jpg

可见,经过FIS3打包后,define函数中自动填入id,deps参数,即模块ID和模块依赖;引用js时,相对路径被替换为绝对路径。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容