携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
简介
前面我们介绍了css前置处理器
和css后置处理器
,并且也讲解了在webpack
中的应用。今天我们再来说说webpack
中图片、字体、文本、数据文件处理。
创建项目
老规矩,首先我们创建一个文件夹,然后初始化package.json
文件。
// 创建webpacktest文件夹
mkdir webpacktest
// 进入webpacktest文件夹
cd webpacktest
// 创建package.json
npm init
安装webpack 和 webpack-cli
接下来我们本地安装webpack 和 webpack-cli
npm i webpack webpack-cli -D
配置构建脚本
然后在package.json
文件中配置编译脚本
"scripts": {
"webpack-file": "webapck"
}
初始化webpack的配置文件
创建webpack
的配置文件webpack.config.js
,并配置好html-webpack-plugin
和clean-webpack-plugin
插件
npm i html-webpack-plugin clean-webpack-plugin -D
const path = require("path");
// 1.引入
const HtmlWebpackPlugin = require("html-webpack-plugin");
// 引入插件
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
// 处理js
module.exports = {
mode: "development",
// 入口可以有多个
// './src/index.js' //webpack的默认配置
entry: "./filesrc",
// 出口只能是一个
output: {
filename: "[name].js",
// 必须是绝对路径
path: path.resolve(__dirname, "./filedist"),
},
// 2. 实例化插件
plugins: [
new HtmlWebpackPlugin({
// 模板html文件的位置,我们这里是在根目录下
template: "./filesrc/index.html",
}),
new CleanWebpackPlugin(),
],
};
创建源文件夹
然后创建filesrc
目录作为源文件目录,并创建index.js
文件,作为入口。创建index.html
文件作为模板。
图片处理
前端图片有png|jpg|gif|jpeg|webp|svg
等格式。并且常用的使用方式有在js
中使用和css
中使用两种方式。
在js
中使用
// src/index.js
// js引入图片
import logo from "./logo.png";
var element = document.createElement("div");
var myIcon = new Image();
myIcon.src = logo;
element.appendChild(myIcon);
document.body.appendChild(element);
// 引入样式图片css文件
import "./index.css";
在css
中使用
// index.css
.box {
background-image: url("./img1.jpeg");
width: 300px;
height: 200px;
}
.svg-box {
background-image: url("./compute.svg");
width: 300px;
height: 200px;
}
如果我们不做任何处理,直接运行npm run webpack-file
打包,webpack
是会报错的,因为webpack
只认识js
文件,并不认识这些图片文件。所以我们需要安装对应的loader
来处理图片。
图片文件我们一般使用file-loader
和url-loader
。这两者有细微差别,这个我们后面说。
首先我安装这两个loader
。
npm i file-loader url-loader -D
使用file-loader处理图片
然后在webpack.config.js
中进行配置,首先我们使用file-loader
来处理图片文件。
const path = require("path");
// 1.引入
const HtmlWebpackPlugin = require("html-webpack-plugin");
// 引入插件
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
// 处理js
module.exports = {
mode: "development",
// './src/index.js' //webpack的默认配置
entry: "./filesrc",
// 出口只能是一个
output: {
filename: "[name].js",
// 必须是绝对路径
path: path.resolve(__dirname, "./filedist"),
},
module: {
rules: [
// css配置
{
test: /\.css$/,
// use: ["css-loader"],
use: [
"style-loader",
{
loader: "css-loader",
},
],
},
// 图片处理
{
test: /\.(png|jpg|gif|jpeg|webp|svg)$/,
// css里面的图片识别不了
// 原因:因为webpack新版本中可以不需要新增loader进行资源打包
// 所以要自定义需要设置: esModule: false 和 type: "javascript/auto"
use: [
{
loader: "file-loader",
options: {
name: "[name].[ext]",
esModule: false,
// 打包后的目录
outputPath: "assets",
},
},
],
type: "javascript/auto", //默认使用自定义的
exclude: /node_modules/, //排除 node_modules 目录
},
],
},
// 2. 实例化插件
plugins: [
new HtmlWebpackPlugin({
// 模板html文件的位置,我们这里是在根目录下
template: "./filesrc/index.html",
}),
new CleanWebpackPlugin(),
],
};
这里有个坑,就是笔者使用的是最新版本的webpack5
,因为webpack5
默认支持了文件处理,所以我们需要加上esModule: false 和 type: "javascript/auto"
两个配置。
关于webpack5
对于文件的默认处理,笔者后面会细说。
配置好loader
后,我们再次运行webpack-file
命令,进行打包。成功了。我们来看下效果
css中的两张背景图和js创建的img总共三张图片都显示出来了。
我们来看看打包后的目录,可以看到,源文件夹中的三张图片被file-loader
直接拷贝到assets
目录下了。
前面说了,图片还可以使用url-loader
来处理,那url-loader
和file-loader
又有什么区别呢?
使用url-loader处理图片
其实url-loader
功能类似于 file-loader
,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL
。
我们来试试
将webpack.config.js
里面的file-loader
替换成url-loader
,并配置limit
参数,用来限制图片在这个范围内直接使用DataURL
,将图片转成base64
链接,直接内联在js
文件里面。否则复制到打包目录。
这里我们限制成20kb,也就是图片小于20kb我们就使用DataURL
。
use: [
{
loader: "url-loader",
options: {
name: "[name].[ext]",
esModule: false,
// 打包后的目录
outputPath: "assets",
limit: 1024 * 20,
},
},
],
笔者的这三张图片大小依次是img1.jpeg 16kb, logo.png 7kb, compute.svg 56kb
。
所以接下来打包,img1.jpeg, logo.png
这两张图片肯定会变成DataURL
,而compute.svg
不会。
我们再次运行webpack-file
命令,进行打包。我们来看下打包后的目录
果不其然,只剩下一张compute.svg
图片了。我们来看看页面样式
可以发现,这两张图使用的是DataURL
链接。
看到这,小伙伴们应该都知道在webpack
中怎么处理图片了吧,并且也清楚了file-loader
和url-loader
这两者的区别了吧。
字体处理
字体常用的格式有eot|ttf|woff|woff2
。对于字体的处理,我们也是使用file-loader
和url-loader
。
我们在index.css
里面加上字体样式。
// index.css
@font-face {
font-family: "MyFont";
src: url("./1644225200443733.ttf");
font-weight: 600;
font-style: normal;
}
.text {
font-family: MyFont;
margin: 20px;
}
然后在模本文件,index.html
里面加上
<div class="text">我用的是新字体哦</div>
使用file-loader处理字体
然后在webpack.config.js
里面进行配置
// 字体处理
{
test: /\.(eot|ttf|woff|woff2)$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[ext]",
esModule: false,
// 打包后的目录
outputPath: "assets",
},
},
],
type: "javascript/auto", //默认使用自定义的
exclude: /node_modules/, //排除 node_modules 目录
},
我们再次运行webpack-file
命令,进行打包。我们来看看页面效果
字体真的被改变了。
我们来看看打包后的目录
字体文件直接被复制到打包目录下了,前面说了,我们还可以使用url-loader
来将文件打包成DataURL
链接。接下来我们尝试下
使用url-loader处理字体
将webpack.config.js
里面的file-loader
替换成url-loader
,并配置limit
参数,由于笔者的这个字体文件有6.4M
,所以需要将imit设置的大一点才有效果。所以这里我们设置成10M
// 字体处理
{
test: /\.(eot|ttf|woff|woff2)$/,
use: [
{
loader: "url-loader",
options: {
name: "[name].[ext]",
esModule: false,
// 打包后的目录
outputPath: "assets",
limit: 1024 * 1000 * 10,
},
},
],
type: "javascript/auto", //默认使用自定义的
exclude: /node_modules/, //排除 node_modules 目录
},
我们再次运行webpack-file
命令,进行打包。我们来打包后的效果
哈哈,字体文件不见了,被直接内联到js
文件里面去了。
对于大文件,笔者推荐还是直接复制过去,不建议转成DataURL
链接。
文本处理
有时项目中需要读取一些文件,比如.txt
// test.txt
我的名字是randy
在入口文件中引入。
// index.js
// text
import text from "./test.txt";
console.log(text);
如果直接运行webpack-file
构建会发现会报错,因为对于.txt
文件webpack
照样不认识,所以也是需要安装对应的loader
来处理。
对于这种文本文件,我们需要使用raw-loader
来处理。这个loader
的作用就是 加载文件原始内容(utf-8)
使用raw-loader处理文本
首先我安装这个loader
。
npm i raw-loader -D
然后在webpack.config.js
进行配置
// 原始文件
{
test: /\.txt$/,
// 加载文件原始内容(utf-8)
use: "raw-loader",
},
再次运行webpack-file
,我们来看看效果
文件内容被直接输出出来了。
对于想把文件内容当做字符串直接输出的我们都可以使用raw-loader
。
数据文件处理
在项目中,有时我们还会碰到引入数据文件的问题,比如我们的省市区数据,一般会是个json
文件。
这里我们简单创建一个文件来测试下
// test.json
{
"name": "randy"
}
对于json
文件,其实webpack
是已经内置json-loader
了的,不需要另外再安装loader
了
// json-loader 加载 JSON 文件(默认包含)
import json from "./test.json";
console.log(json);
所以下面我们能直接输出。
使用xml-loader处理xml数据文件
有时我们的数据来源并不是json
,而是xml
文件。那应该怎么办呢?
// test.xml
<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Mary</to>
<from>randy</from>
<heading>Reminder</heading>
<body>Call Cindy on Tuesday</body>
</note>
在入口文件中引入
// index.js
// xml
import xml from "./test.xml";
console.log(xml);
当然也是需要安装对应的loader
啦,对于xml
文件我们可以使用xml-loader
来处理
首先我安装这个loader
。
npm i xml-loader -D
然后在webpack.config.js
中进行配置。
// xml
{
test: /\.xml$/,
use: "xml-loader",
},
再次运行webpack-file
,我们来看看效果
xml
文件的内容被直接识别出来了。
使用csv-loader处理csv数据文件
还有时我们的数据来源可能又是csv、tsv
文件。那应该怎么办呢?
// test.csv
我是randy
哈哈哈
在入口文件中引入
// index.js
// csv
import csv from "./test.csv";
console.log(csv);
当然也是需要安装对应的loader
啦,对于csv
文件我们可以使用csv-loader
来处理
首先我安装这个loader
。
npm i csv-loader -D
然后在webpack.config.js
中进行配置。
// csv tsv
{
test: /\.(csv|tsv)$/,
use: "csv-loader",
},
再次运行webpack-file
,我们来看看效果
csv
文件的内容被直接识别出来了。
webpack5对资源的处理
webpack5
新增资源模块(asset module),允许使用资源文件(字体,图标等)而无需配置额外的 loader
。
资源模块支持以下四个配置:
-
asset/resource
将资源分割为单独的文件,并导出url
,类似之前的file-loader
的功能. -
asset/inline
将资源导出为dataUrl
的形式,类似之前的url-loader
的小于limit
参数时功能. -
asset/source
将资源导出为源码(source code). 类似的raw-loader
功能. -
asset
会根据文件大小来选择使用哪种类型,当文件小于 8 KB(默认) 的时候会使用asset/inline
,否则会使用asset/resource
接下来我们分别测试下
asset/inline
我们将图片的配置改一下,将之前使用use
并配置file-loader
注释掉,直接配置type
// 图片处理
{
test: /\.(png|jpg|gif|jpeg|webp|svg)$/,
// webpack5用法 不需要再使用file-loader和url-loader,已经内置了
type: "asset/inline"
}
我们运行webpack-file
,我们来看看效果
页面显示正常,并且三图片都已dataUrl
的形式内联到js
文件里面了。
asset/resource
接下来我们把字体的配置设置成asset/resource
,这样他就会被直接复制到打包目录下了。我们来试试。
// 字体处理
{
test: /\.(eot|ttf|woff|woff2)$/,
// webpack5用法 不需要再使用file-loader和url-loader,已经内置了
type: "asset/resource",
}
我们运行webpack-file
,我们来看看效果
页面字体也显示正常,并且打包后的目录多了个字体文件。
asset/source
接下来我们将文本文件使用asset/source
来处理。
// 原始文件
{
test: /\.txt$/,
type: "asset/source",
},
我们运行webpack-file
,我们来看看效果
文件被直接读取出来了。
asset
接下来我们再把图片的配置设置成asset
,并做如下配置
// 图片处理
{
test: /\.(png|jpg|gif|jpeg|webp|svg)$/,
// webpack5用法 不需要再使用file-loader和url-loader,已经内置了
type: "asset",
generator: {
// 输出文件位置以及文件名
filename: "[name].[ext]",
},
parser: {
dataUrlCondition: {
maxSize: 10 * 1024, // 超过10kb不转 base64
},
},
}
我们运行webpack-file
,我们来看看效果
可以看到,构建后两张大于10kb
的图片是直接复制过来的,小于10kb
的那张图片被直接以dataUrl
的形式内联到js
文件里面了。
总结
好啦,关于webpack
中对文件的处理基本上讲得差不多啦。小伙伴们是否都掌握了呢。
-
对于图片和字体,我们可以使用
file-loader
和url-loader
来处理。url-loader
的优势是可以设置limit
阈值来生成DataUrl
链接进行优化。 -
对于一些文本文件,想直接输出文件内容的我们都可以使用
raw-loader
来进行处理。 -
对于
json
数据文件,webpack
已经内置了,不需要再单独安装loader
,可以直接使用。 -
对于其他的数据文件,比如
xml、csv、tsv
文件,webpack不能直接识别,我们需要安装对应的xml-loader、csv-loader
来处理。 -
如果使用的是
webpack5
,我们可以不需要再使用file-loader
和url-loader
,因为已经内置了。我们直接配置type
就可以啦。
后记
感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!