什么是Loader
webpack官网原话:
webpack only understands JavaScript and JSON files. Loaders allow webpack to process other types of files and convert them into valid modules that can be consumed by your application and added to the dependency graph.(简单说就是webpack只支持js和json,对于不支持的其类型文件的处理就需要依赖各种Loader来转化文件为webpack支持的模块了。嗯,Loader 字面意思不就是加载器么)
曾经了解的loader
为不同资源类型配置正确的loader很重要!X 3(重要的事说三遍),使用webpack打包项目时需要为js(x), less等配置对应的loader,还有其他资源对应的loader,参照配置的格式,选用对的loader就可以,唯一需要注意的是loader的顺序是从右到左的。so easy,参考官网哐哐哐就可以配置可以使用的loader了。
//webpack.config.js
...
module: {
rules: [
{
test: /\.jsx?$/,
use: [
{
loader: 'thread-loader',
options: {
workers: 3
}
},
'babel-loader?cacheDirectory=true'
]
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader',
'postcss-loader',
{
loader: 'px2rem-loader',
options: {
remUnit: 75,
percisson: 8
}
}
]
}
...
]
},
揭开loader的神秘面纱
loader其实就是一个函数,接收一个字符串,返回一个字符串(注意格式,需要是个模块格式)。webpack中loader runner会调用这个loader(函数),并且把前一个loader的返回作为入参传入当前loader,loader 函数内的会被webpack和loader runner注入上下文,有很多有用的 API,可以使用this返回,如this.callback, this.async等。
/**
*
* @param {string|Buffer} content Content of the resource file
* @param {object} [map] SourceMap data consumable by https://github.com/mozilla/source-map
* @param {any} [meta] Meta data, could be anything
*/
function webpackLoader(content, map, meta) {
// 转换逻辑
return `export default ${JSON.stringify(content)}`
}
同步loader 和异步loader
同步的loader如果只有一个返回结果,可以使用return或者this.callback的方式,如果有多个返回则只能使用this.callback。⚠️使用this.callback之后需要返回undefined (return;)
// 主要关注 err 和 content
this.callback(
err: Error | null, // 用于报错
content: string | Buffer,// 返回内容
sourceMap?: SourceMap, // sourcemap
meta?: any // meta
);
function webpackLoader(content, map, meta) {
// 转换逻辑
this.callback(null, content, map, meta);
return; //always return undefined when calling callback()
}
异步loader的返回则需要先调用this.async()(通知loader-runner需要异步调用)并返回this .callback。
function webpackLoader(content, map, meta) {
const callback = this.async();
// 转换逻辑
// 异步操作
someAsyncOperation(content, function (err, result) {
if (err) return callback(err);
callback(null, result, map, meta);
});
}
loader-runner 可用于调试
runLoaders两个参数,第一个是配置options,另一个是回调函数,用于接收loader的返回和异常信息。
const loaderRunner = require('loader-runner');
const path = require('path');
// 注意使用runLoaders, loader中无法使用this.emitFile生成文件,需要用fs.writeFile
loaderRunner.runLoaders({
resource: path.join(__dirname, 'source.txt'), // 目标文件绝对路径
loaders: [
{
loader: path.join(__dirname, 'index.js'),// loader绝对路径
options: {name: 'hello'}// 传入的参数,loader中可以使用loader-utils获取
}
]
}, (err, result) => {
// err loader中的异常信息
err && console.log(err);
console.log('result', result);
})
重点来说一下回调函数中的两个参数,err和result。err是loader的异常,如果loader中直接throw new Error('error') 或者this.callback(new Error('error')),那么将会传到err中。 第二个参数result是包含一些返回结果相关的信息,主要看result.result,存放的是返回的结果,来个简单的demo吧
// 需要安装loader-runner 和loader-utils
//source.txt
hello world
//demo-loader.js
const loaderUtils = require('loader-utils');
// loader 格式 (source: string) => string
module.exports = function(source) {
const { name } = loaderUtils.getOptions(this);
console.log('name', name)
console.log('loader is working, but do nothing');
return `export default ${JSON.stringify(source)}`;
}
// test.js
const loaderRunner = require('loader-runner');
const path = require('path');
// 使用runLoaders 无法使用emitFile生成文件
loaderRunner.runLoaders({
resource: path.join(__dirname, 'source.txt'),
loaders: [{loader: path.join(__dirname, 'index.js'), options: {name: 'hello'}}]
}, (err, result) => {
err && console.log(err);
console.log('result', result);
})
以下是copy来的备注
// err: Error?
// result.result: Buffer | String 此处是个数组
// The result
// only available when no error occured
// result.resourceBuffer: Buffer
// The raw resource as Buffer (useful for SourceMaps)
// only available when no error occured
// result.cacheable: Bool
// Is the result cacheable or do it require reexecution?
// result.fileDependencies: String[]
// An array of paths (existing files) on which the result depends on
// result.missingDependencies: String[]
// An array of paths (not existing files) on which the result depends on
// result.contextDependencies: String[]
// An array of paths (directories) on which the result depends on
先记录这么多,未完待续。。。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!