准备工作
- 安装 Node.js, 建议安装LTS长期支持版本
-
mkdir webpack
andcd webpack
andnpm init -y
npm i webpack webpack-cli --save-dev
loader是什么
所谓 loader 只是一个导出为函数的 JavaScript 模块。loader runner 会调用这个函数,然后把上一个 loader 产生的结果或者资源文件(resource file)传入进去。函数的 this 上下文将由 webpack 填充,并且 loader runner 具有一些有用方法,可以使 loader 改变为异步调用方式,或者获取 query 参数。
第一个 loader 的传入参数只有一个:资源文件(resource file)的内容。compiler 需要得到最后一个 loader 产生的处理结果。这个处理结果应该是 String 或者 Buffer(被转换为一个 string),代表了模块的 JavaScript 源码。另外还可以传递一个可选的 SourceMap 结果(格式为 JSON 对象)。
如果是单个处理结果,可以在同步模式中直接返回。如果有多个处理结果,则必须调用 this.callback()。在异步模式中,必须调用 this.async(),来指示 loader runner 等待异步结果,它会返回 this.callback() 回调函数,随后 loader 必须返回 undefined 并且调用该回调函数。
loader干了些什么
webpack loader对js代码、样式、图片等资源重新编译返回一个理想的结果,本质上说,loader是一些特殊的webpack插件,当然webpack本身有plugin的概念。默认情况下,资源文件会被转化为 UTF-8 字符串,然后传给 loader。通过设置 raw,loader 可以接收原始的 Buffer。每一个 loader 都可以用 String 或者 Buffer 的形式传递它的处理结果。Complier 将会把它们在 loader 之间相互转换。loader 总是从右到左地被调用。
接下来我们以css-loader为例看看它的输出
创建文件如下:
-- a.css
-- index.html
-- index.js
-- webpack.config.js
a.css
#app {
background-color: #f5f5f5;
color: blue;
}
#app p {
color: gray;
}
index.html
<div id="app">
<h4>hello webpack!</h4>
<p>hello loader!</p>
</div>
<script src="./main.js"></script>
index.js
const a = require('./a.css');
console.log(a);
webpack.config.js
module.exports = {
entry: {
main: './index.js'
},
output: {
filename: '[name].js',
},
module: {
rules: [
{
test: /\.css$/,
use: 'css-loader'
}
]
}
}
上面的代码很常见,webpack帮助我们加载.css文件。当weback在构建的过程中会根据已有配置首先将a.css作为参数交给css-loader, css-loader将会进行一系列处理输出特定的数据。实际上a.css
会作为raw resource string
类型的参数,有一些loader只能接受raw作为参数,例如css-loader、handlebars-loader...
执行npx webpack
可以看到,css-loader将样式代码处理成了js数组,并且我们的样式代码被处理成了字符串
修改webpack.config.js
...
module: {
rules: [
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}
]
}
...
加上style-loader
,再看看输出的啥:
如你所见,style-loader将css-loader返回的样式数组一顿操作插入到html head中去了,然后他自己返回了一个空对象
loader特性之一就是:利用参数完成某个任务,不是一定有所输出,就像一个返回值为空的函数。
显然style-loader就是符合这种特性的loader之一,它与css-loader搭配起来实现了我们需要的功能。并且他们各自独立,保持小而精的运行,方便与其他loader搭配合作,比如当我想把样式代码输出为js字符串时我就会选择to-string-loader
,首先安装这个新的partner,npm i to-string-loader
,然后按照顺序引用它,切记顺序很重要,
...
module: {
rules: [
{
test: /\.css$/,
use: [ 'to-string-loader', 'css-loader' ]
}
]
}
...
重新构建后结果如下:
关于css-loader
css-loader使用频率比较高,它有一些配置可以帮助我们实现特定需求。
...
module: {
rules: [
{
test: /\.css$/,
use: [
'to-string-loader',
{
loader: 'css-loader',
options: {
url: true, // 是否启用url(), 类似于 url(image.png)` => `require('./image.png')
import: true, // 是否启用@import()加载样式
modules: false, // 是否启用CSS Modules
localIdentName: [hash:base64], // Configure the generated ident
sourceMap: false, // Enable/Disable Sourcemaps
camelCase: false, // Export Classnames in CamelCase
importLoaders: 0 // Number of loaders applied before CSS loader
}
}
]
}
]
}
...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。