webpack loader
前言
webpack 有两种扩展方式。一种是 Loader 主要是负责将其他的资源形态转译成 webpack 可以处理的标准 JavaScript 代码;另一种是 Plugin 主要伴随着 webpack 整个生命周期,做一些重塑逻辑。
本文主要介绍第一种扩展方式 Loader。
Loader 是什么?
由于 webpack 只能处理标准的 JavaScript 代码,我们在使用 webpack 打包的过程中还需要处理图片/样式等等内容,那么这些内容都需要先转为 JS 代码才能够被 webpack 打包,因此需要 Loader 来帮我们实现。
Loader 的本质
Loader 的本质是导出函数的 JavaScript 模块,其导出的函数可以实现内容的转换,简单的 Loader 框架如下,接受源代码做一些计算返回修改之后的代码
module.exports = function (source, sourceMap?, data?) {
// 执行计算
return modifySource;
};
Loader 的分类
对于 Loader 来说,一共分为四种类型
- pre: 前置 loader
- normal: 普通 loader
- inline: 行内 loader
- post: 后置 loader
可以通过 webpack enforce 属性来做配置 pre/post,如果不配置默认则为普通 loader
module.exports = {
//...
module: {
rules: [
{
test: /\.css$/,
use: 'css-loader',
// enforce: 'pre' | 'post',
},
],
},
};
可以通过内联 import 语句添加前缀,可以覆盖配置中的所有 loader, preLoader 和 postLoader
-
使用
!前缀,将禁用所有已配置的 normal loader(普通 loader)import Styles from '!style-loader!css-loader?modules!./styles.css'; -
使用
!!前缀,将禁用所有已配置的 loader(preLoader, loader, postLoader)import Styles from '!!style-loader!css-loader?modules!./styles.css'; -
使用
!前缀,将禁用所有已配置的 preLoader 和 loader,但是不禁用 postLoadersimport Styles from '-!style-loader!css-loader?modules!./styles.css';
Normal Loader
首先我们先分别定义三个简单的 Normal Loader
// ==== LoaderC ====
function LoaderC(source) {
console.log('LoaderC run=====', source);
return source + '~loaderC';
}
module.exports = LoaderC;
// ==== LoaderB ====
function LoaderB(source) {
console.log('LoaderB run=====', source);
return source + '~loaderB';
}
module.exports = LoaderB;
// ==== LoaderA ====
function LoaderA(source) {
console.log('LoaderA run=====', source);
return `module.exports = '${source}~loaderA'`;
}
module.exports = LoaderA;
在 webpack.config.js 中如下使用这些 loaders
const path = require('path');
module.exports = {
entry: './src/index.js',
context: path.resolve(__dirname, '.'),
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
mode: 'development',
module: {
rules: [
{
test: /\.js$/,
use: ['babel-loader'],
},
{
test: /\.txt$/,
use: [
path.resolve(__dirname, 'src/loaders/loaderA.js'),
path.resolve(__dirname, 'src/loaders/loaderB.js'),
path.resolve(__dirname, 'src/loaders/loaderC.js'),
],
},
],
},
};
入口文件 index.js 添加一个 txt 的依赖模块
import text from './name.txt';
console.log(text);
执行一次打包


能够发现 Normal Loader 是从 C⇒B⇒A 的执行顺序,也就是从下往上或者从右往左的顺序。并且上一个 loader 返回的结果作为下一个 loader 的 source
