loader
在默认情况下,webpack只支持.js的加载。如果要处理其他类型的文件模块,需要自行实现loader或者使用第三方实现。
大体来讲, loader 可以说成是一个在 requeire 读取到内容之后执行的一个钩子函数。期间,webpack会把文件内容传给该函数,最后函数还需要将其返回,则否会报错。如下(真实例子看文末):1
2
3
4
5function loader(source) {
// to do
return source
}
module.exports = loader
loader 的基本使用
首先新建一个文件夹 loaderdemo. 进入该文件夹初始化,快速创建一个新的工作目录1
yarn init - y
添加webpack.config.js,并构建基本骨架1
2
3
4
5
6
7
8
9
10
11
12
13
14let path = require("path");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: "bundle.[hash:8].js",
path: path.resolve(__dirname, "dist"),
},
module: {
},
plugins: []
}
现在开始添加一个简单的loader规则,比如说我们想把代码里的es6新语法转换成es5。只需要在module配置项下添加rules规则,这样子webpack在处理模块时如果命中了这项规则的正则表示式,那么就会使用use数据里的loader模块去处理。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26let path = require("path");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: "bundle.[hash:8].js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
}
}
]
}
]
},
plugins: []
}
有时候可能需要对一个文件使用多个loader来处理。比如less,需要转换成css代码,css又需要处理自身的文件依赖,最后还要将代码导出到html。这个过程一共需要使用3个loader,分别是 [ 'style-loader','css-loader','less-loader'],并且它们是有执行顺序要求的!less-loader => css-loader => style-loader。loader的执行顺序是数组从后往前开始执行。举个例子:
1 | let path = require("path"); |
也可以使用另一种写法,这种写法默认情况下也是从下向上的执行顺序执行。并且这种写法还支持使用enforce对loader进行一个分类来控制执行顺序,不同分类顺序 pre > normal > inline > post,默认为 normal。
1 | let path = require("path"); |
自己实现一个loader
loader 本质是一个在 requeire 读取到内容之后执行的一个钩子函数,所以只需要在这个钩子函数里实现我们的功能就行了。拿我们最初的例子babel-loader为例,实现一个简化版的babel-loader。
首先分割一下任务, babel-loader做了什么事情:
- 将
es6代码转换成es5语法 - 返回转换好的
es5代码
准备测试用代码 index.js
1 | let a = () => { |
我们需要借助一些第三方库帮我们完成代码的转换,安装第三方库@babel/core1
yarn add @babel/core -D
babel-loader还有一些配置项,同样需要一个第三方库来帮我们读取配置1
yarn add loader-utils -D
对于用户输入的配置,还需要做一个验证1
yarn add schema-utils -D
准备工作完成就开始直接撸代码。首先配置 webpack.config.js, resolveLoader配置项告诉webpack应该去哪里找寻loader模块,它会依次去数组里的路径下找寻loader,这在调试时很有用。
1 | let path = require("path"); |
然后是 babel-loader.js的代码
1 | let babel = require('@babel/core') |
最后在 终端中输入
1 | npx webpack |
成功生成dist目录,成功生成文件并且将代码转换成了es5代码