模块化开发的好处毋庸置疑。遗憾的是,尽管在JavaScript社区已经出现了若干种 模块规范,例如:CommonJS、AMD或者ES2015,但是到目前为止,还没有任何 一个浏览器能够很好地支持任何一种模块化规范。
好消息是存在一些模块打包工具,例如webpack、browserify、requirejs 或者systemjs,都可以让我们在浏览器支持之前,就能够采用任何一种模块规范, 以模块化的方式来进行开发,需要调试或发布时再打包成浏览器支持的格式。不过这意 味着,我们的开发流水线又要增加一个新的环节 —— 模块打包:
前端模块打包工具最主要的任务是解析模块之间的依赖关系,并通过拦截模块间的 引用(例如CommonJS的require、ES2015的import、AMD的define)来实现 浏览器中单一JS文件内的多模块化访问。
将.vue文件转化为CommonJS模块:vue2jsm
vue2jsm只是对vue2js做了简单修改:遵循CommonJS模块规范,使用module.exports
输出了整定后的组件代码。
轻量的CommonJS打包器:cjspack
我们实现了一个简单的模块打包器cjspack,用来将CommonJS模块打包为单一文件 供浏览器使用:
~$ ./cjspack ./main.js ./bundle.js
all modules bundled for entry : ./main.js
cjspack是一个node.js小应用,它的原理很简单:
- 利用Esprima进行源文件语法分析,从入口模块开始,遍历所有的require调用,建立模块依赖树,组织模块映射表
- 生成模块编号与对应源代码的映射表
- 生成
require
拦截函数,在其中利用模块映射表执行目标模块源代码 - 生成入口代码