更好的模块化开发体验
一个大型的项目,一般情况都会包括三种类型的模块。 - 第三方模块
- 当前项目可公用的模块
- 应用级模块,每个页面都不一样。
针对这三种性质的模块,我们都比较喜欢放在不同的目录。这样带来的坏处是,不管我用绝对定位还是相对定位,都是如此的别扭。
感谢 AMD 规范中制定了3个非常便于查找模块路径的配置, 我们把这几个配置也应用到了编译期。
通过fis.config.set(‘settings.postprocessor.amd’) 来设置。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | fis.config. set ( 'settings.postprocessor.amd' , {
baseUrl: '.' ,
paths: {
jquery: 'modules/libs/jquery/jquery.js' ,
bootstrap: 'modules/libs/bootstrap/js/bootstrap.js' ,
jqueryui: 'modules/libs/jquery-ui/ui/' ,
app: './modules/app' ,
css: './modules/css.js'
},
packages: [
{
name: 'zrender' ,
location: 'modules/libs/zrender' ,
main: 'zrender'
},
{
name: 'echarts' ,
location: 'modules/libs/echarts' ,
main: 'echarts'
}
]
});
|
当设置了 baseUrl 后,所有绝对路径的模块查找都是基于此目录查找的,对于使用频率比较高的模块,可以把改目录设置成 baseUrl. 比如第三类模块。
对于一些常用的库,可以通过这个来设置短引用或者说别名。比如: jquery , bootstrap 。
另外需要说明的是,有些第三方库在发布的时候,都是指定的别名依赖。如: jquery-ui 一系列。这种模块有很多很多。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | ( function ( factory ) {
if ( typeof define === "function" && define.amd ) {
define([
"jquery" ,
"./core" ,
"./widget" ,
"./position"
], factory );
} else {
factory( jQuery );
}
}( function ( $ ) {
});
|
所以,为了不动第三方源码,我们也需要明确的设置这个别名。 1 2 3 | paths: {
jquery: 'modules/libs/jquery/jquery.js'
}
|
其次,我们可以给这类性质的“当前项目可公用的模块”,设置个 paths. 如: 1 2 3 | paths: {
libs: '/widget/libs/'
}
|
这样对于内部公共模块目录下模块的引用无论你的代码在什么位置就可以这样引用。 1 2 3 4 | define( function (require, exports, module) {
var dialog = require( 'libs/dialog' );
...
});
|
作用基本上和 paths 差不多,只是它更适合配置成一个完整的模块包。如 zrender、echarts 等等。
更智能的包装 在 FIS 开发环境中,你还可以编写满足 commonjs 规范的 js 模块,FIS 会自动包装成 AMD 模块以便于在浏览器中运行。如果直接就是 AMD 规范编写的,那就更不用说了。但是既不是 amd, 也不是 commonJS 规范的模块怎么办呢?
再次感谢 AMD 规范中的 shim 配置,同样,FIS 把这个配置应用到了编译期。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | fis.config. set ( 'settings.postprocessor.amd' , {
shim: {
'modules/libs/bootstrap/js/bootstrap.js' : [ 'jquery' ],
'some/ohther/path.js' : {
deps: [ 'libs/a' , 'libs/b' ],
exports: 'some.thing' ,
init: function (a, b) {
return some.thing + 'another' ;
}
}
}
});
|
FIS 在包装模块组件的时候,会读取此配置,自动把改模块的依赖和暴露的对象添加上。当然 requirejs 本来也能做这个事,但是考虑到性能开销,这个工作更应该在编译期完成。
更高级的插件加载机制 AMD 除了可以处理 JS 模块依赖加载,还能处理其他依赖加载,怎么做?就是利用 amd plugin loader
换句话说 amd 还可以用来加载 css or 前端 tpl。在 fis amd demo 例子中有个示例,就是利用 css amd 插件来动态加载 css 文件。amd 依赖解析插件 不仅只处理模块查找,还处理插件资源查找。 1 2 3 | require([ 'css!./styles/demo.css' ], function () {
document.getElementById( 'main' ).innerHTML = '<div id="demo">It works!</div>' ;
});
|
这样的好处是,对于当前工程下面的静态资源引用,可以用相对路径,也可以用绝对路径,且可以给资源加 md5 戳,甚至可以最终部署到 cdn 上,而不用改一句源码。
更智能的打包 FIS 的 pack 打包方案本来就比较灵活,通过正则或者 glob语法,可以把任意多的文件合并成一个。同时当使用 depscombine 插件的时候也支持 r.js 那种方式,将入口文件的所有依赖合并进来,只要在合并入口 JS 依赖前,配置一条规则把公用依赖部分的 js 合并成一个文件,就能把公共依赖抽离出来,这样公共的部分缓存就可以被利用起来。 1 2 3 4 5 6 7 8 9 | fis.config. set ( 'pack' , {
'pkg/zrender.js' : [ 'modules/libs/zrender/zrender.js' ],
'pkg/echarts.js' : [ 'modules/libs/echarts/echarts.js' ],
'pkg/bootstrap_jquery.js' : [ 'modules/libs/bootstrap/js/bootstrap.js' ],
'pkg/jquery_ui_tabs.js' : [ 'modules/libs/jquery-ui/ui/tabs.js' ]
});
|

当配置好规则后,简单的一个 fis release -p 命令就把所有被打包文件的请求变成合并后的了,源码什么都不用改,如果想愉快的调试代码,release 时不带 -p 参数,又自动变成了非打包方案了。
|