webpack入门之图片、字体、文本、数据文件处理

携手创作,共同成长!这是我参与「掘金日新计划 · 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-pluginclean-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-loaderurl-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命令,进行打包。成功了。我们来看下效果

image.png

css中的两张背景图和js创建的img总共三张图片都显示出来了。

我们来看看打包后的目录,可以看到,源文件夹中的三张图片被file-loader直接拷贝到assets目录下了。

image.png

前面说了,图片还可以使用url-loader来处理,那url-loaderfile-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命令,进行打包。我们来看下打包后的目录

image.png

果不其然,只剩下一张compute.svg图片了。我们来看看页面样式

image.png

可以发现,这两张图使用的是DataURL链接。

看到这,小伙伴们应该都知道在webpack中怎么处理图片了吧,并且也清楚了file-loaderurl-loader这两者的区别了吧。

字体处理

字体常用的格式有eot|ttf|woff|woff2。对于字体的处理,我们也是使用file-loaderurl-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命令,进行打包。我们来看看页面效果

image.png

字体真的被改变了。

我们来看看打包后的目录

image.png

字体文件直接被复制到打包目录下了,前面说了,我们还可以使用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命令,进行打包。我们来打包后的效果

image.png

哈哈,字体文件不见了,被直接内联到js文件里面去了。

对于大文件,笔者推荐还是直接复制过去,不建议转成DataURL链接。

文本处理

有时项目中需要读取一些文件,比如.txt

// test.txt

我的名字是randy

在入口文件中引入。

// index.js

// text
import text from "./test.txt";
console.log(text);

如果直接运行webpack-file构建会发现会报错,因为对于.txt文件webpack照样不认识,所以也是需要安装对应的loader来处理。

image.png

对于这种文本文件,我们需要使用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,我们来看看效果

image.png

文件内容被直接输出出来了。

对于想把文件内容当做字符串直接输出的我们都可以使用raw-loader

数据文件处理

在项目中,有时我们还会碰到引入数据文件的问题,比如我们的省市区数据,一般会是个json文件。

这里我们简单创建一个文件来测试下

// test.json
{
  "name": "randy"
}

对于json文件,其实webpack是已经内置json-loader了的,不需要另外再安装loader

// json-loader 加载 JSON 文件(默认包含)

import json from "./test.json";
console.log(json);

所以下面我们能直接输出。

image.png

使用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,我们来看看效果

image.png

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,我们来看看效果

image.png

csv文件的内容被直接识别出来了。

webpack5对资源的处理

webpack5 新增资源模块(asset module),允许使用资源文件(字体,图标等)而无需配置额外的 loader

资源模块支持以下四个配置:

  1. asset/resource 将资源分割为单独的文件,并导出 url,类似之前的 file-loader 的功能.

  2. asset/inline 将资源导出为 dataUrl 的形式,类似之前的 url-loader 的小于 limit 参数时功能.

  3. asset/source 将资源导出为源码(source code). 类似的 raw-loader 功能.

  4. 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,我们来看看效果

image.png

页面显示正常,并且三图片都已dataUrl的形式内联到js文件里面了。

asset/resource

接下来我们把字体的配置设置成asset/resource,这样他就会被直接复制到打包目录下了。我们来试试。

// 字体处理
{
  test: /\.(eot|ttf|woff|woff2)$/,

  // webpack5用法 不需要再使用file-loader和url-loader,已经内置了
  type: "asset/resource",
}

我们运行webpack-file,我们来看看效果

image.png

页面字体也显示正常,并且打包后的目录多了个字体文件。

asset/source

接下来我们将文本文件使用asset/source来处理。

// 原始文件
{
  test: /\.txt$/,
  type: "asset/source",
},

我们运行webpack-file,我们来看看效果

image.png

文件被直接读取出来了。

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,我们来看看效果

image.png

可以看到,构建后两张大于10kb的图片是直接复制过来的,小于10kb的那张图片被直接以dataUrl的形式内联到js文件里面了。

总结

好啦,关于webpack中对文件的处理基本上讲得差不多啦。小伙伴们是否都掌握了呢。

  1. 对于图片和字体,我们可以使用file-loaderurl-loader来处理。url-loader的优势是可以设置limit阈值来生成DataUrl链接进行优化。

  2. 对于一些文本文件,想直接输出文件内容的我们都可以使用raw-loader来进行处理。

  3. 对于json数据文件,webpack已经内置了,不需要再单独安装loader,可以直接使用。

  4. 对于其他的数据文件,比如xml、csv、tsv文件,webpack不能直接识别,我们需要安装对应的xml-loader、csv-loader来处理。

  5. 如果使用的是webpack5,我们可以不需要再使用file-loaderurl-loader,因为已经内置了。我们直接配置type就可以啦。

后记

感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!

猜你喜欢

转载自juejin.im/post/7126012733018865695