什么是loader
webpack enables use of loaders to preprocess files. This allows you to bundle any static resource way beyond JavaScript. You can easily write your own loaders using Node.js.
webpack可以通过使用loader来预处理文件。这能让你把任意静态资源打包成JavaScript。loader可以使用node.js 简单的书写。
如上文官网原文的解释,众所周知webpack只能处理js模块,那么例如 .vue,.jsx 之类的文件处理就需要全部借助loader来做了。
常见的loader
如何使用loader
- 打开项目中的webpack默认文件,默认是webpack.config.js(此处不考虑vue-cli3+这种二次封装的配置)
- modules -> rules
- api:
module.exports = { entry: “./src/index.js”, output: { filename: “[name].js”, path: path.join(__dirname, “dest/“) }, mode: “development”, plugins: [], resolveLoader: { modules: [“node_modules”, “./Loaders”] }, / here / module: { rules: [ { test: /.scss/, use: [“style-loader”, “css-loader”, “sass-loader”]
}
]
}
}
<a name="w06bw"></a>
## 如何书写一个自定义loader
<a name="AtWnR"></a>
### loader 定义的规则
1. loader 必须是一个js模块,并且export的结果要是一个方法。
1. loader不能使用箭头函数声明,因为在实际运行时,他的this会被webpack放入一系列方法。
1. loader必须有一个返回值,在同步的程序中,可以使用 `return` 或 `this.callback()` 来声明返回值;在异步的程序中,必须使用 `this.async()` 来返回,这样webpack才会等待异步执行结束。
1. loader 的返回值必须是 String 或者 Buffer。
<a name="rwbIH"></a>
### 例子
- 将一个 `console.log('Hello webpack!')` 编译成 `console.log('Hello loader!!')`
```javascript
// index.js
console.log('hello webpack!')
// js-loader
module.exports = function (source) {
// 上一个loader处理后的结果或原文
console.log(source); // console.log('hello webpack!')
this.callback(null, source.replace("webpack", "loader!"))
}
// webpack.config.js
const path = require('path')
module.exports = {
entry: "./src/index.js",
output: {
filename: "[name].js",
path: path.join(__dirname, "dest/")
},
mode: "development",
plugins: [],
module: {
rules: [
{
test: /\.js/,
use: path.join(__dirname, './Loaders/js-loader.js')
}
]
}
}
更简单的写法 —— resolveLoader
- 从上文的例子里可以看出,loader的path要写绝对路径,当需要同时放置多个loader时,书写起来会变的非常冗杂,我们可以通过修改webpack配置的
resovleLoader
来解决这个问题。 resolveLoader
可以用来配置寻找一些东西的路径,在这里我们只需要修改寻找loader的,loader是用于module里面的,所以即为:module.exports = {
// ...
resolveLoader: {
// 这里的路径可以是相对路径,也可以是命名的别名
modules: ['node_modules', './Loaders']
}
}
命名完成后,就可以直接使用
use: 'js-loader'
来进行书写了。webpack会先寻找node_modules里面的js-loader模块,再去Loaders文件夹中寻找。
给loader传入配置
1. 在配置文件中传入
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
{
test: /\.js/,
use: [{
loader: "js-loader",
options: {
param: "hello",
replaceParam: "hi"
}
}]
}
]
}
}
2. 在loader中接收参数
有两个api可以拿到传入的参数,两者拿到的东西是完全一样的:
this.query
- 额外安装
loader-utils
组件,通过loaderUtils.getOptions(this)
module.exports = function (source) {
console.log(this.query); // { param: "hello", replaceParam: "hi" }
this.callback(null, source.replace(this.query.param, this.query.replaceParam))
}
文档
- webpack给loader注入的this方法:https://webpack.js.org/api/loaders/#thisquery