什么是loader:loader的本质就是一个function,在我们进行打包的时候,帮我们处理需要打包的文件。
编写loader
1.创建一个文件夹,使用npm init -y来初始化
npm init -y
2.安装一些开发依赖
npm i webpack webpack-cli clean-webpack-plugin loader-utils -D
3.创建src目录,并在src下创建index.js
index.js内容:
console.log('hello word');
4.创建loaders目录,并在该目录下创建replaceLoader.js文件
replaceLoader.js内容:
const loaderUtils = require('loader-utils');
module.exports = function (source) {
const option = loaderUtils.getOptions(this);
return source.replace('word', option.name);
};
注释:
- 我们在replaceLoader中导出的function,就是一个loader。
- 这个函数默认接收一个参数source,就是我们打包的文件的内容,是字符串来的。
- loader-utils这个插件,使用来帮助我们更方便的获取我们在webpack配置文件中传过来的options。
- 不使用loader-utils这个插件,我们可以通过this.query.name来获取我们传过来的options中的name
- loader不要写成箭头函数的形式,因为我们要使用webpack给我提供的this
- loader一定要有返回值,我们这里就是将index.js文件中的word打包替换成我们在配置文件中自定义的name
5.创建webpack.config.js文件
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].[contenthash].js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
// 通过文件路径来引用loader
loader: path.resolve(__dirname, './loaders/replaceLoader.js'),
options: {
// 传给loader的name参数
name: 'wjg-webpack-loader',
},
}
],
},
],
},
plugins: [new CleanWebpackPlugin()], // 这里我使用来清除上一次打包的文件
};
6.使用npm run build来打包,查看生成的文件
番外篇:在loader中使用异步操作和使用多个loader
1.继续在上面的内容中进行,在loaders文件夹中创建replaceLoaderAsync.js
module.exports = function (source) {
const cb = this.async();
setTimeout(() => {
source = source.replace('hello', 'hi');
cb(null, source);
}, 1000);
};
注释:
- 使用this.async()来帮我们在异步操作中返回
- this.async()返回一个callback函数,上面我简写成了cb
- cb函数的参数:第一个是错误对象,没有就写null,第二个参数是我们修改的source,第三个是sourceMap,第四个是meta,由于我这里没有用到后面两个,就省略不写了
2.修改webpack.config.js文件
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].[contenthash].js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: path.resolve(__dirname, './loaders/replaceLoader.js'),
options: {
name: 'wjg-webpack-loader',
},
},
// 新增异步的loader
{
loader: path.resolve(__dirname, './loaders/replaceLoaderAsync.js'),
},
],
},
],
},
plugins: [new CleanWebpackPlugin()],
};
注:loader的执行顺序:是从后往前执行的。
整个目录文件: