首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Webpack5在CSS文件中内联字体和图像?

用Webpack5在CSS文件中内联字体和图像?
EN

Stack Overflow用户
提问于 2022-07-14 11:22:52
回答 1查看 42关注 0票数 2

我需要导入一些CSS文件到我的项目Webpack 5,我需要内联所有这些资源(这是一个可悲的要求)。CSS内部有一些具有相对URI的字体和图像,如下所示:

代码语言:javascript
复制
@font-face { font-family: "MyFont"; src: url(./fonts/Roboto-Regular.ttf) format("truetype"); font-weight: normal;}
@font-face { font-family: "MyFont"; src: url(./fonts/Roboto-Bold.ttf) format("truetype"); font-weight: bold;}
@font-face { font-family: "MyFont"; src: url(./fonts/Roboto-Italic.ttf) format("truetype"); font-weight: normal; font-style: italic;}
@font-face { font-family: "MyFont"; src: url(./fonts/Roboto-BoldItalic.ttf) format("truetype"); font-weight: bold; font-style: italic;}
@font-face { font-family: 'Material Icons'; font-style: normal; font-weight: 400; src: url(./fonts/material-icons.woff2) format('woff2'); }
@font-face { font-family: 'Material Icons Outlined'; font-style: normal; font-weight: 400; src: url(./fonts/material-icons-outlined.woff2) format('woff2'); }
    

 * { font-family: "MyFont", "Roboto-Light", "Noto Sans CJK SC", "DejaVu Sans"; }

.UICheckbox         { width:80px; height:89px; background-image:url("img/checkboxOFF.png"); background-repeat:no-repeat; }
.UICheckbox.checked { background-image:url("img/checkboxON.png"); }

由于我需要作为base64导入CSS文件,所以实际上无法自动处理在其中找到的资源(与使用PostCSS或模拟文件的方式不同)。我目前的webpack配置如下,但它忽略了url()语句:

代码语言:javascript
复制
      {
        test: /\.(png|jpg|gif)$/i,
        type: "asset/inline",
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: "asset/inline",
      },
      {
        test: /\.css$/i,
        type: "asset/inline",
      },

有更好的方法来处理这件事吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-19 15:35:29

我找到了一个解决方案,这个解决方案并不是真正的通用或坚实的,而是完成了工作,至少在我的情况下是这样。

导入与固定的源路径相关联,所以我们的想法是读取在url()规则中找到的资源,并以DataURI的形式进行base64编码。

我发现数据金刚的使用非常有用,它提供了一种方法,可以像外部资源一样在线地包含数据,并自动管理mimetype。

代码语言:javascript
复制
npm install datauri --save

然后,我必须修改webpack.config.js内部的生成器处理程序,以手工处理资源,利用datauri包。

代码语言:javascript
复制
const path = require("path");
const Datauri = require("datauri/sync");

const EXTERNAL_ROOT_PATH = "./src/external/dev/";

module.exports = {
  ...

  module: {
    rules: [
       {
        test: /\.css$/i,
        type: "asset/inline",
        generator: {
          dataUrl: (content) => {
            content = content.toString();

            // Get the resource paths inside the CSS url() rules
            let asset_urls = [];
            let match,
              regex = /url\((.*?)\)/gi;
            while ((match = regex.exec(content))) {
              asset_urls.push(match[1]);
            }
            // console.log(asset_urls);

            // Convert the resource to a DataURI and replace it inside url()
            asset_urls.forEach((file_path) => {
              // Sanitize the file path first
              sanitized_file_path = file_path.replace(/[\"\']/g, "").replace(/^(?:\.\.\/)+/, "");

              const data_uri = Datauri(path.join(EXTERNAL_ROOT_PATH, sanitized_file_path));
              // console.log(data_uri.content); //=> "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
              // console.log(data_uri.mimetype); //=> "image/png"
              // console.log(data_uri.base64); //=> "iVBORw0KGgoAAAANSUhEUgAA..."
              // console.log(data_uri.buffer); //=> file buffer

              content = content.replace(file_path, data_uri.content);
            });

            return "data:text/css;base64," + Buffer.from(content).toString("base64");
          },
        },
      },
    ],
  },
};
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72979726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档