一、什么是 loader
Webpack 默认只能理解 JavaScript 和 JSON 文件,这是 webpack 开箱可用的自带能力。但是通过 loader,能够让 Webpack 去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中。
loader 有两个属性:
test:识别出哪些文件会被转换。use:定义出在进行转换时,应该使用哪个或哪些 loader。
如:
module.exports = {
module: {
rules: [
{
test: /\.txt$/,
use: 'raw-loader'
}
],
},
}
以上代码,告诉 Webpack 当遇到以 .txt 结尾的文件时,在打包之前先使用 raw-loader 转换一下。
二、加载 CSS
1. css
要想在 JavaScript 模块中引入 CSS 文件,就要用到 style-loader 和 css-loader。
npm install --save-dev style-loader css-loader
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
]
},
}
loader 是逆序链式调用的,链中的每个 loader 都将对资源进行转换,并将转换后的资源传递给下一个 loader 进行处理,Webpack 期望链中的最后一个 loader 返回 JavaScript。
以上代码,当遇到以 .css 结尾的文件时,会先使用 css-loader,后使用 style-loader。
在浏览器中查看结果:
2. less 和 sass
要使用 less 或 sass,就需要使用相应的 loader,下面以 less 为例:
npm install less less-loader --save-dev
module.exports = {
module: {
rules: [
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}
]
},
}
在浏览器中查看结果:
三、抽离和压缩 CSS
1. 将 CSS 文件抽离成单独的文件
使用 mini-css-extract-plugin 插件(需要 webpack5 才能正常工作):
npm install mini-css-extract-plugin --save-dev
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
]
},
plugins: [
// new MiniCssExtractPlugin() // 默认打包到 dist 目录下的 main.css
new MiniCssExtractPlugin({ // 传入配置对象,修改打包目录及文件名
filename: 'styles/[contenthash].css'
})
],
}
2. 压缩 CSS
使用 css-minimizer-webpack-plugin 插件:
npm install css-minimizer-webpack-plugin --save-dev
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')
module.exports = {
mode: 'production', // 开发模式
optimization: { // 优化配置
minimizer: [new CssMinimizerWebpackPlugin()],
}
}
四、加载 images 图像
内置的 Asset Modules 让我们在 CSS 中可以直接引入图片资源。
style.css:
.block {
border: 1px solid red;
width: 200px;
height: 200px;
background: url("./assets/svg-1.svg") no-repeat center;
background-size: 100% auto;
}
入口文件 index.js:
import './style.css'
index.html:
<div class="block"></div>
在浏览器中查看效果:
五、加载 fonts 字体
内置的 Asset Modules 让我们在 CSS 中可以直接引入字体资源。
webpack.config.js:
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
type: 'asset/resource'
}
]
},
}
iconfont.css:
@font-face {
font-family: "iconfont"; /* Project id */
src: url('./assets/iconfont.ttf?t=1650766084662') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-airplane:before { content: "\e8db"; }
.icon-bus:before { content: "\e8dc"; }
.icon-bottle:before { content: "\e8dd"; }
.icon-book:before { content: "\e8de"; }
入口文件 index.js:
import './iconfont.css'
index.html:
<ul>
<li><span class="iconfont icon-airplane"></span></li>
<li><span class="iconfont icon-bus"></span></li>
<li><span class="iconfont icon-bottle"></span></li>
<li><span class="iconfont icon-book"></span></li>
</ul>
在浏览器中查看效果:
六、加载数据
JSON 数据在 Webpack 中是默认支持的,如果要加载其他类型的数据,如 CSV、TSV、XML 等,可以使用 csv-loader、xml-loader。
npm install --save-dev csv-loader xml-loader
webpack.config.js:
module.exports = {
module: {
rules: [
{
test: /\.(csv|tsv)$/,
use: 'csv-loader',
},
{
test: /\.xml$/,
use: 'xml-loader',
},
]
},
}
入口文件 index.js:
import helloWorld from './hello-world.js'
import data from './assets/data.xml'
import notes from './assets/data.csv'
helloWorld()
console.log('data:', data)
console.log('notes:', notes)
在浏览器中查看效果:
七、自定义 JSON 模块 parser
通过使用自定义 parser 替代特定的 webpack loader,可以将任何 toml、yaml 或 json5 文件作为 JSON 模块导入。
npm install toml yaml json5 --save-dev
webpack.config.js:
const toml = require('toml')
const yaml = require('yamljs')
const json5 = require('json5')
module.exports = {
module: {
rules: [
{
test: /\.toml$/,
type: 'json',
parser: {
parse: toml.parse,
},
},
{
test: /\.yaml$/,
type: 'json',
parser: {
parse: yaml.parse,
},
},
{
test: /\.json5$/,
type: 'json',
parser: {
parse: json5.parse,
},
},
]
},
}
入口文件 index.js:
import helloWorld from './hello-world.js'
import toml from './assets/json/data.toml'
import yaml from './assets/json/data.yaml'
import json5 from './assets/json/data.json5'
helloWorld()
console.log('toml:', toml)
console.log('yaml:', yaml)
console.log('json5:', json5)
在浏览器中查看效果: