怎样写一个加载器?
关于加载器
Loader是一个帮你预处理JS之外的文件的工具,它有点像是gulp这些构建工具里的Tasks,它可以把coffee转成js,也可以把images转成url形式的数据。通过使用Loader,我们可以在JS文件里require css文件。
要用Loader转换模块,可以在一个require调用里完成:
var moduleWithOneLoader = require("my-loader!./my-module");
上面这个例子里面Loader使用名字的形式指定的,当然我们也可以用相对路径来指定Loader:
require("./loaders/my-module!./my-module");
Loader也可以进行链式操作:
require("style-loader!css-loader!less-loader!./my-styles.less");
链式操作是从右至左进行的,在上面这个例子里面,my-style.less会首先通过less-loader来转换成css,再通过css-loader处理诸如urls,字体等资源,然后传到style-loader来放到一个style标签里去。
另外,Loader还能用查询参数:
require("loader?with=parameter!./file");
在配置文件里配置Loader
通过require来配置Loader意味着需要几个Loader就要写几个require,这显然不是个好办法。
我们还可以用在配置文件里使用Loader:
{
module:{
Loaders:[
{test:/\.coffee$/,loader:"coffee-loader"}
],
preLoaders:[
{test:/\.coffee$/,loader:"coffee-hint-loader"}
]
}
};
Loader的顺序
当文件被读取的时候,Loaders以以下的顺序执行:
- preLoaders
- loaders
- require里指定的loaders
- postLoaders
你也可以修改require的写法来修改Loader的加载顺序:
- 在require里添加!会使得配置文件里的预加载器失效
- require("!raw!./script/coffee");
- 在require里添加!!会使得配置文件里所有的加载器失效
- require("!!raw!./script/coffee");
- 在require里添加 - 会使得配置文件里的加载器和预加载器失效
- require("-!raw!./script.coffe");
建议
暂空
写一个加载器
写一个加载器是件挺简单的事,一个加载器就是一个导出一个方法的文件(这个方法就是处理源文件的方法),编译器把上一个加载器的结构当作参数传进去然后调用这个函数,编译器会往这个函数的this绑定一些诸如把加载从同步改成异步、获取查询参数之类的方法。第一个加载器的参数就是源文件,最后一个加载器则输出期望的结果,这个结果应该是个字符串或者buffer(被转成字符串),也就是这个模块经过处理之后得到的JS代码。还有一个可选的结果是SourceMap,一个JSON对象。
如果只有一个结果,那就会以同步形式返回。有多个结果的话,this.callback一定会被调用。在异步模式下则会调用this.async(),如果异步模式是可行的,它会返回this.callback,然后加载器就必须返回undefined并且调用callback。
同步加载器
module.exports = function(){
return someSyncOperation(content);
};
异步加载器
module.exports = function(){
var callback = this.async();
if(!callback) return someSyncOperation(content);
someAsyncOperstion(content,function(err,result){
if(err) return callback(err);
callback(null,result);
})
}
注意:最好在异步不可行的时候fallback到同步的模式