发布于 2016-01-11 10:47:31 | 528 次阅读 | 评论: 1 | 来源: PHPERZ
Mod.js 构建工具
绝大部分童鞋都称 Mod 是一个构建工具:一个用来把源代码编译为可发布代码版本的工具,过程中自动进行预处理,优化,编译等操作。也有童鞋会说 Mod 是一个更复杂的东西:一个流程管理工具,我们可以在Mod构建前后用Mod做更多流水工作,前可以生成项目的脚手架,后可以部署测试环境等等。通常我偏爱的回答更多的是,管他是啥呢,能优雅而简单的解决问题的猫都是好猫。理解Mod能解决什么问题比其是什么更有价值与意义,不是吗?当然,考虑一个项目的完备性,Mod也是其官方解释: JavaScript Workflow Tooling For Web,面向Web的流程工具。
在项目中,我们选择了百度FIS3+MODJS+VUEJS的方案进行前端开发,这套方案具体可以看这里:
https://github.com/zhangtao07/fis-vuejs-seed
本地开发过程非常顺利,第一次线上部署也非常顺利,一切似乎都在平稳进行着。然而在今天上午的一次更新部署以后,出现了意想不到的事情。
我们线上更新代码是通过把fis3 release出来的文件放入服务器文件目录内,再重启服务器的方式进行的。在之前的多次修改中都没有出现问题,但是在今天上午,我把两个新写的js文件添加到服务器文件目录内,按照以往的更新方式进行后,发现控制台报错,错误原因是mod.js无法找到对应的js文件。
项目使用的是异步加载的方式,什么时候需要这个js就直接把它require进来。今天上午的bug就是出现在这里,新添加的两个js文件竟然require不出来了。
首先我仔细检查了文件的引用路径,和能够成功加载的文件的写法是一模一样的,排除了文件路径的问题;
接着对其他页面进行debug,因为之前也试过如果上一个页面报错,会影响这个页面的进行。排除其他页面的错误之后,问题依然存在。
打开chrome控制台,在network里面监视文件请求,发现require路径报404错误,并且发现其content-type为text,而非正常的javascript,同时同事无意中的一句吐槽也引起了我的注意:“很奇怪呀,第一次部署上去的都可以,修改里面的代码也没问题,但是把文件改个名字或者添加新的文件就出问题了。”
通过仔细分析,认为这个bug并未由写错路径之类的低级错误引起的,而是在FIS3编译过程中出现问题或者mod.js进行文件引用的过程中出现问题引起的。
带着这个想法,我首先研究了一下FIS3的config文件,没有找到关键点。初步排除是FIS3编译的问题。
接着在github上,找到百度fex-team所在的mod.js项目,发现有这么一个提问:
https://github.com/fex-team/mod/issues/16#issuecomment-100741125
其中关键的点是这一句:
mod.js 在产出的时候不是以一个完整的 loader 存在的,为了配合 fis 的包括md5、cdn等等功能,需要在加载使用时,给 mod.js 一个静态资源列表
我想我找到了原因。
mod.js并非直接通过写在require('xxxxx')
的方式引入文件,而是通过一张静态资源列表所获得。如果这张表没有记录这个路径,那么mod.js是不可能把资源加载进来的。
这个列表是由后端通过查询 fis 产出的静态资源列表 map.json 得到的。
也就是说,这个表应该是在我FIS3的产出目录或者产出文件中。后打开服务器目录,找到对应文件,真的发现有着这么一份静态资源列表:
require.resourceMap({
"res": {
"project/component/xxx/xx": {
"url": "/project/component/xxx/xx.js",
"type": "js"
},
"pkg":[]
});
问题终于明了。原来是我们只顾着添加新的文件,更新资源的引用路径,却没有更新这份静态资源列表!所以才会出现第一次部署成功,但是修改文件名或者新增加文件的时候出现bug(因为这份静态资源列表存放在一个几乎不用更改的文件内,所以线上部署的时候这个文件依然是沿用着旧版)。
马上给这份静态资源列表进行更新,部署,重启服务器,测试……
测试通过。
bug终于解决!!
后来仔细回想,其实这也算是低级错误,因为竟然遗漏了部署前对文件内容进行对比的步骤。对构建工具的编译流程的不熟悉,对模块加载器加载原理的不了解也是造成bug的原因。今后在开发中一定要对每一个环节都了如指掌,才能避免在知识的空白中出现问题。