带你深入解锁webpack系列基础篇(Webpack基础应用篇-9)
带你深入解锁webpack系列基础篇(Webpack基础应用篇-9)module: { rules: [ { test: /\.(woff|woff2|eot|ttf|otf)$/i type: 'asset/resource' } ] }07-manage-assets/webpack.config.js那么,像字体这样的其他资源如何处理呢?使用 Asset Modules 可以接收并加载任何文件,然后将其输出到构建目录。这就是说,我们可以将它们用于任何类型的文件,也包括字体。让我们更新 webpack.config.js 来处理字体文件:编辑切换为居中添加图片注释,不超过 140 字(可选)我们看到,通过样式把背景图片加到了页面中。
1.6.4 加载 images 图像假如,现在我们正在下载 CSS,但是像 background 和 icon 这样的图像,要如何处理呢?在 webpack 5 中,可以使用内置的 Asset Modules,我们可以轻松地将这些内容混入我们的系统中,这个我们在"资源模块"一节中已经介绍了。这里再补充一个知识点,在 css文件里也可以直接引用文件,修改 style.css 和入口 index.js:
.block-bg {
background-image: url(./assets/webpack-logo.svg) ;
}
block.style.cssText = `width: 200px; height: 200px; background-color: #2b3a42`
block.classList.add('block-bg')
07-manage-assets/src/style.css
.hello {
background-color: #f9efd4;
}
.block-bg {
background-image: url(./assets/webpack-logo.svg) ;
}
07-manage-assets/src/index.js
// 导入模块
//...
import './style.css'
//...
block.style.cssText = `width: 200px; height: 200px; background-color: #2b3a42`
block.textContent = exampleText
block.classList.add('block-bg')
document.body.appendChild(block)
//...
启动服务,打开浏览器:
编辑切换为居中
添加图片注释,不超过 140 字(可选)
我们看到,通过样式把背景图片加到了页面中。
1.6.5 加载 fonts 字体那么,像字体这样的其他资源如何处理呢?使用 Asset Modules 可以接收并加载任何文件,然后将其输出到构建目录。这就是说,我们可以将它们用于任何类型的文件,也包括字体。让我们更新 webpack.config.js 来处理字体文件:
module: {
rules: [
{
test: /\.(woff|woff2|eot|ttf|otf)$/i
type: 'asset/resource'
}
]
}
07-manage-assets/webpack.config.js
//...
module.exports = {
//...
// 配置资源文件
module: {
rules: [
//...
{
test: /\.(woff|woff2|eot|ttf|otf)$/i
type: 'asset/resource'
}
]
}
//...
}
在项目中添加一些字体文件:
编辑
添加图片注释,不超过 140 字(可选)
配置好 loader 并将字体文件放在合适的位置后,你可以通过一个 @font-face 声明将其混合。本地的 url(...) 指令会被 webpack 获取处理,就像它处理图片一样:
@font-face {
font-family: 'iconfont';
src: url('./assets/iconfont.ttf') format('truetype');
}
.icon {
font-family: "iconfont" !important;
font-size: 30px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
07-manage-assets/src/style.css
@font-face {
font-family: 'iconfont';
src: url('./assets/iconfont.ttf') format('truetype');
}
.hello {
background-color: #f9efd4;
}
.icon {
font-family: "iconfont" !important;
font-size: 30px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.block-bg {
background-image: url(./assets/webpack-logo.svg);
}
const span = document.createElement('span')
span.classList.add('icon')
span.innerHTML = ''
document.body.appendChild(span)
07-manage-assets/src/index.js
// 导入模块
//...
const span = document.createElement('span')
span.classList.add('icon')
span.innerHTML = ''
document.body.appendChild(span)
启动服务,打开浏览器:
编辑切换为居中
添加图片注释,不超过 140 字(可选)
我们再打包一下,看看输出的文件:
[felix] 07-manage-assets $ npx webpack
07-manage-assets/dist/styles/4a9cff551c7a105e1554.css
/*!******************************************************************!*\
!*** css ../node_modules/css-loader/dist/cjs.js!./src/style.css ***!
\******************************************************************/@font-face{font-family:iconfont;src:url(../images/65b194f1f711865371d1.ttf) format("truetype")}.hello{background-color:#f9efd4}.icon{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:iconfont!important;font-size:16px;font-style:normal}.block-bg{background-image:url("data:image/svg xml;charset=utf-8 ")}
/*# sourceMappingURL=data:application/json;charset=utf-8;base64 eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3R5bGVzLzRhOWNmZjU1MWM3YTEwNWUxNTU0LmNzcyIsIm1hcHBpbmdzIjoiQUFBQTs7cUVBRXFFLENDRnJFLFdBQ0Usb0JBQXVCLENBQ3ZCLDhEQUNGLENBRUEsT0FDRSx3QkFDRixDQUVBLE1BSUUsa0NBQW1DLENBQ25DLGlDQUFrQyxDQUpsQyw4QkFBa0MsQ0FDbEMsY0FBZSxDQUNmLGlCQUdGLENBRUEsVUFDRSw0d0VBQ0YiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vNGE5Y2ZmNTUxYzdhMTA1ZTE1NTQuY3NzIiwid2VicGFjazovLy8uL3NyYy9zdHlsZS5jc3MiXSwic291cmNlc0NvbnRlbnQiOlsiLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIGNzcyAuLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL3NyYy9zdHlsZS5jc3MgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbkBmb250LWZhY2Uge1xuICBmb250LWZhbWlseTogJ2ljb25mb250JztcbiAgc3JjOiB1cmwoLi4vaW1hZ2VzLzY1YjE5NGYxZjcxMTg2NTM3MWQxLnR0ZikgZm9ybWF0KCd0cnVldHlwZScpO1xufVxuXG4uaGVsbG8ge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjllZmQ0O1xufVxuXG4uaWNvbiB7XG4gIGZvbnQtZmFtaWx5OiBcImljb25mb250XCIgIWltcG9ydGFudDtcbiAgZm9udC1zaXplOiAxNnB4O1xuICBmb250LXN0eWxlOiBub3JtYWw7XG4gIC13ZWJraXQtZm9udC1zbW9vdGhpbmc6IGFudGlhbGlhc2VkO1xuICAtbW96LW9zeC1mb250LXNtb290aGluZzogZ3JheXNjYWxlO1xufVxuXG4uYmxvY2stYmcge1xuICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoXCJkYXRhOmltYWdlL3N2Zyt4bWwsJTNjc3ZnIHZpZXdCb3g9JzAgMCAzMDQ2LjcgODc1LjcnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyclM2UlM2NwYXRoIGQ9J20zODcgMCAzODcgMjE4Ljl2NDM3LjlsLTM4NyAyMTguOS0zODctMjE4Ljl2LTQzNy45eicgZmlsbD0nd2hpdGUnLyUzZSUzY3BhdGggZD0nbTcwNC45IDY0MS43LTMwNS4xIDE3Mi42di0xMzQuNGwxOTAuMS0xMDQuNnptMjAuOS0xOC45di0zNjAuOWwtMTExLjYgNjQuNXYyMzJ6bS02NTcuOSAxOC45IDMwNS4xIDE3Mi42di0xMzQuNGwtMTkwLjItMTA0LjZ6bS0yMC45LTE4Ljl2LTM2MC45bDExMS42IDY0LjV2MjMyem0xMy4xLTM4NC4zIDMxMi45LTE3N3YxMjkuOWwtMjAwLjUgMTEwLjMtMS42Ljl6bTY1Mi42IDAtMzEyLjktMTc3djEyOS45bDIwMC41IDExMC4yIDEuNi45eicgZmlsbD0nJTIzOGVkNmZiJy8lM2UlM2NwYXRoIGQ9J20zNzMgNjQ5LjMtMTg3LjYtMTAzLjJ2LTIwNC4zbDE4Ny42IDEwOC4zem0yNi44IDAgMTg3LjYtMTAzLjF2LTIwNC40bC0xODcuNiAxMDguM3ptLTIwMS43LTMzMS4xIDE4OC4zLTEwMy41IDE4OC4zIDEwMy41LTE4OC4zIDEwOC43eicgZmlsbD0nJTIzMWM3OGMwJy8lM2UlM2NwYXRoIGQ9J20xMTY0LjMgNTc2LjNoODIuNWw4NC4xLTI4MC4yaC04MC40bC00OS44IDE5OC44LTUzLjEtMTk4LjhoLTY5LjZsLTUzLjYgMTk4LjgtNDkuMy0xOTguOGgtODAuNGw4My42IDI4MC4yaDgyLjVsNTItMTc5LjV6bTE3MC45LTEzOS4zYzAgODQuMSA1Ny4zIDE0Ni4zIDE0Ny40IDE0Ni4zIDY5LjcgMCAxMDcuMi00MS44IDExNy45LTYxLjZsLTQ4LjgtMzdjLTggMTEuOC0zMCAzNC4zLTY4LjEgMzQuMy00MS4zIDAtNzEuMy0yNi44LTcyLjktNjQuM2gxOTcuM2MuNS01LjQuNS0xMC43LjUtMTYuMSAwLTkxLjYtNDkuMy0xNDkuNS0xMzYuMS0xNDkuNS03OS45IDAtMTM3LjIgNjMuMi0xMzcuMiAxNDcuOXptNzcuNy0zMC42YzMuMi0zMi4xIDI1LjctNTYuOCA2MC42LTU2LjggMzMuOCAwIDU4LjQgMjIuNSA2MCA1Ni44em0yMjMuNSAxNjkuOWg2OS43di0yOC45YzcuNSA5LjEgMzUuNCAzNS45IDgzLjEgMzUuOSA4MC40IDAgMTM3LjItNjAuNSAxMzcuMi0xNDYuOCAwLTg2LjgtNTIuNS0xNDcuMy0xMzIuOS0xNDcuMy00OC4yIDAtNzYuMSAyNi44LTgzLjEgMzYuNHYtMTM2LjdoLTczLjl2Mzg3LjR6bTcxLjgtMTM5LjNjMC01Mi41IDMxLjEtODIuNSA3MS44LTgyLjUgNDIuOSAwIDcxLjggMzMuOCA3MS44IDgyLjUgMCA0OS44LTMwIDgwLjktNzEuOCA4MC45LTQ1IDAtNzEuOC0zNi41LTcxLjgtODAuOXptMjQ3IDIzOS41aDczLjl2LTEyOS4yYzcgOS4xIDM0LjggMzUuOSA4My4xIDM1LjkgODAuNCAwIDEzMi45LTYwLjUgMTMyLjktMTQ3LjMgMC04NS43LTU2LjgtMTQ2LjgtMTM3LjItMTQ2LjgtNDcuNyAwLTc1LjYgMjYuOC04My4xIDM2LjR2LTI5LjVoLTY5Ljd2MzgwLjV6bTcxLjgtMjQxLjFjMC00NC41IDI2LjgtODAuOSA3MS44LTgwLjkgNDEuOCAwIDcxLjggMzEuMSA3MS44IDgwLjkgMCA0OC44LTI4LjkgODIuNS03MS44IDgyLjUtNDAuNyAwLTcxLjgtMzAtNzEuOC04Mi41em0yMzEuNSA1NC4xYzAgNTguOSA0OC4yIDkzLjggMTA1IDkzLjggMzIuMiAwIDUzLjYtOS42IDY4LjEtMjUuMmw0LjggMTguMmg2NS40di0xNzcuNGMwLTYyLjctMjYuOC0xMDkuOC0xMTYuOC0xMDkuOC00Mi45IDAtODUuMiAxNi4xLTExMC40IDMzLjJsMjcuOSA1MC40YTE2NS4yIDE2NS4yIDAgMCAxIDc0LjUtMTkuOGMzMi43IDAgNTAuOSAxNi42IDUwLjkgNDEuM3YxOC4yYy0xMC4yLTctMzIuMi0xNS41LTYwLjYtMTUuNS02NS40LS4xLTEwOC44IDM3LjQtMTA4LjggOTIuNnptNzMuOS0yLjJjMC0yMyAxOS44LTM5LjEgNDguMi0zOS4xczQ4LjggMTQuNSA0OC44IDM5LjFjMCAyMy42LTIwLjQgMzguNi00OC4yIDM4LjZzLTQ4LjgtMTUuNS00OC44LTM4LjZ6bTM0OC45IDMwLjZjLTQ2LjYgMC03OS44LTMzLjgtNzkuOC04MS40IDAtNDUgMjkuNS04MiA3Ny4yLTgyYTk1LjIgOTUuMiAwIDAgMSA2NS40IDI2LjhsMjAuOS02Mi4yYTE0Mi42IDE0Mi42IDAgMCAwIC04OC40LTMwYy04NS4yIDAtMTQ5IDYyLjctMTQ5IDE0Ny45czYyLjIgMTQ2LjMgMTQ5LjUgMTQ2LjNhMTQxIDE0MSAwIDAgMCA4Ny4zLTMwbC0xOS44LTYwLjVjLTEyLjQgMTAuMS0zNC45IDI1LjEtNjMuMyAyNS4xem0xMTAuOSA1OC40aDczLjl2LTE0NC43bDkzLjggMTQ0LjdoODYuOGwtMTA2LjEtMTUzLjMgOTguNi0xMjdoLTgzLjFsLTkwIDExNy45di0yMjVoLTczLjl6JyBmaWxsPSclMjNmNWZhZmEnLyUzZSUzYy9zdmclM2VcIikgO1xufVxuIiwiQGZvbnQtZmFjZSB7XG4gIGZvbnQtZmFtaWx5OiAnaWNvbmZvbnQnO1xuICBzcmM6IHVybCgnLi9hc3NldHMvaWNvbmZvbnQudHRmJykgZm9ybWF0KCd0cnVldHlwZScpO1xufVxuXG4uaGVsbG8ge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjllZmQ0O1xufVxuXG4uaWNvbiB7XG4gIGZvbnQtZmFtaWx5OiBcImljb25mb250XCIgIWltcG9ydGFudDtcbiAgZm9udC1zaXplOiAxNnB4O1xuICBmb250LXN0eWxlOiBub3JtYWw7XG4gIC13ZWJraXQtZm9udC1zbW9vdGhpbmc6IGFudGlhbGlhc2VkO1xuICAtbW96LW9zeC1mb250LXNtb290aGluZzogZ3JheXNjYWxlO1xufVxuXG4uYmxvY2stYmcge1xuICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoLi9hc3NldHMvd2VicGFjay1sb2dvLnN2ZykgO1xufSJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==*/
由于在前面我们应用了如下配置,使生产环境css 文件也进行了压缩处理。我们可以注释它:
optimization: {
// minimize: true
}
1.6.6 加载数据
此外,可以加载的有用资源还有数据,如 JSON 文件,CSV、TSV 和 XML。类似于 NodeJS,JSON 支持实际上是内置的,也就是说 import Data from './data.json' 默认将正常运行。要导入 CSV、TSV 和 XML,你可以使用 csv-loader 和 xml-loader。让我们处理加载这三类文件:
[felix] webpack5 $ npm install --save-dev csv-loader xml-loader
添加配置:
module: {
rules: [
{
test: /\.(csv|tsv)$/i
use: ['csv-loader']
}
{
test: /\.xml$/i
use: ['xml-loader']
}
]
}
07-manage-assets/webpack.config.js
//...
module.exports = {
//...
// 配置资源文件
module: {
rules: [
//...
{
test: /\.(csv|tsv)$/i
use: ['csv-loader']
}
{
test: /\.xml$/i
use: ['xml-loader']
}
]
}
//...
}
现在,你可以 import 这四种类型的数据(JSON CSV TSV XML)中的任何一种,所导入的 Data 变量,将包含可直接使用的已解析 JSON:
创建两个文件:
07-manage-assets/src/assets/data.xml
<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Mary</to>
<from>John</from>
<heading>Reminder</heading>
<body>Call Cindy on Tuesday</body>
</note>
07-manage-assets/src/assets/data.csv
to from heading body
Mary John Reminder Call Cindy on Tuesday
Zoe Bill Reminder Buy orange juice
Autumn Lindsey Letter I miss you
在入口文件里加载数据模块,并在控制台上打印导入内容:
import Data from './assets/data.xml'
import Notes from './assets/data.csv'
console.log(Data)
console.log(Notes)
07-manage-assets/src/index.js
// 导入模块
//...
import Data from './assets/data.xml'
import Notes from './assets/data.csv'
//...
console.log(Data)
console.log(Notes)
查看开发者工具中的控制台,你应该能够看到导入的数据会被打印出来!
[felix] 07-manage-assets $ npx webpack serve
编辑切换为居中
添加图片注释,不超过 140 字(可选)
由此可见,data.xml文件转化为一个JS对象,data.cvs转化为一个数组。
1.6.7 自定义 JSON 模块 parser通过使用 自定义 parser 替代特定的 webpack loader,可以将任何 toml、yaml 或 json5 文件作为 JSON 模块导入。
假设你在 src 文件夹下有一个 data.toml、一个 data.yaml 以及一个 data.json5 文件:
07-manage-assets/src/assets/json/data.toml
title = "TOML Example"
[owner]
name = "Tom Preston-Werner"
organization = "GitHub"
bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
dob = 1979-05-27T07:32:00Z
07-manage-assets/src/assets/json/data.yaml
title: YAML Exampleowner:name: Tom Preston-Wernerorganization: GitHubbio: |-GitHub Cofounder & CEOLikes tater tots and beer.dob: 1979-05-27T07:32:00.000Z
07-manage-assets/src/assets/json/data.json5
{
// comment
title: 'JSON5 Example'
owner: {
name: 'Tom Preston-Werner'
organization: 'GitHub'
bio: 'GitHub Cofounder & CEO\n\
Likes tater tots and beer.'
dob: '1979-05-27T07:32:00.000Z'
}
}
首先安装 toml,yamljs 和 json5 的 packages:
[felix] webpack5 $ npm install toml yamljs json5 --save-dev
并在你的 webpack 中配置它们:
const toml = require('toml');
const yaml = require('yamljs');
const json5 = require('json5');
module.exports = {
module: {
rules: [
{
test: /\.toml$/i
type: 'json'
parser: {
parse: toml.parse
}
}
{
test: /\.yaml$/i
type: 'json'
parser: {
parse: yaml.parse
}
}
{
test: /\.json5$/i
type: 'json'
parser: {
parse: json5.parse
}
}
]
}
}
07-manage-assets/webpack.config.js
//...
const toml = require('toml')
const yaml = require('yamljs')
const json5 = require('json5')
module.exports = {
//...
// 配置资源文件
module: {
rules: [
//...
{
test: /\.toml$/i
type: 'json'
parser: {
parse: toml.parse
}
}
{
test: /\.yaml$/i
type: 'json'
parser: {
parse: yaml.parse
}
}
{
test: /\.json5$/i
type: 'json'
parser: {
parse: json5.parse
}
}
]
}
//...
}
在主文件中引入模块,并打印内容:
import toml from './data.toml';
import yaml from './data.yaml';
import json from './data.json5';
console.log(toml.title); // output `TOML Example`
console.log(toml.owner.name); // output `Tom Preston-Werner`
console.log(yaml.title); // output `YAML Example`
console.log(yaml.owner.name); // output `Tom Preston-Werner`
console.log(json.title); // output `JSON5 Example`
console.log(json.owner.name); // output `Tom Preston-Werner`
07-manage-assets/src/index.js
// 导入模块
//...
import toml from './assets/json/data.toml'
import yaml from './assets/json/data.yaml'
import json from './assets/json/data.json5'
//...
console.log(toml.title); // output `TOML Example`
console.log(toml.owner.name); // output `Tom Preston-Werner`
console.log(yaml.title); // output `YAML Example`
console.log(yaml.owner.name); // output `Tom Preston-Werner`
console.log(json.title); // output `JSON5 Example`
console.log(json.owner.name); // output `Tom Preston-Werner`
启动服务,打开浏览器:
[felix] 07-manage-assets $ npx webpack serve
编辑切换为居中
添加图片注释,不超过 140 字(可选)
现在,toml、yaml和json5几个类型的文件都正常输出了结果。