feather2中对前端模块化进行了支持,其未使用requirejs及seajs等开源的模块化加载工具,而是使用了featherjs,即为了解决requirejs及seajs目前不能解决的性能瓶颈:
开发者可以在js文件中,像写node代码一样,require一个模块,并且通过exports暴露出去:
/static/a.js
module.exports = {
name: 'A',
desc: 'haha'
};
/static/index.js
var A = require('./a.js');
console.log(A);
实际在web端的开发中,模块化的js都必须使用define函数包裹才能够正常加载并处理依赖,这一系列行为都不需要开发者处理,feather会自行帮助开发者处理
注: feather2不会对 任意目录下的 third目录做任何处理,包括包裹define函数
在feather中, 提倡调用js时使用require或者require.async函数进行异步调用,原因:
- 异步加载不堵塞页面,可以提升页面加载速度和性能
- 加速domready的触发,可使用户提前使用网站功能
- 预分析deps,结合featherjs,可达到并行加载依赖,提高网站性能
注: 由于feather会除third目录外的js文件使用define包裹,所以开发在使用script标签调用时,由于featherjs使用了cmd规范,所以js文件内的内容只有在被require或者require.async时才会被调用,如果想让文件加载后执行,可进行如下配置,不使用define包裹:
conf/conf.js
feather.match('**.js', {
useJsWraper: false
});
使用require时,被require的模块会在使用前被加载,如果希望某一个模块可以被异步加载或者延迟加载,可使用require.async函数
require.async('./a.js', function(A){
console.log(A);
});
具体详细的使用可见featherjs的文档
另外需要注意的有两点
-
在html中使用require.async对模块进行引用,而不是require
-
如果引用的文件本身依赖别的模块,请确保被引用的模块中有对此依赖模块的声明,或依赖模块会被提前加载, 可通过以下两种方式:
- 模块对依赖模块有依赖声明:
/static/index.js
var A = require('./a.js');
或
/* @require('./a.js'); */
- 如未声明依赖,则需提前加载依赖
<script> require.async('/static/jquery.js', function($){ require.async('/static/jquery-ui.js'); }); </script>
实际,此第二种方法与模块化的概念中的核心点 相违背)