webpack項目如何正確打包引入的自定義字體


一. 如何在Vue或React項目中使用自定義字體

在開發前端項目時,經常會遇到UI同事希望在項目中使用一個炫酷字體的需求。那么怎么在項目中使用自定義字體呢?

其實實現起來並不復雜,可以借用CSS3 @font-face 來實現。

本文着重介紹一下 webpack 項目如何正確打包引入的自定義字體。

可以訪問 這里 查看更多關於大數據平台建設的原創文章 或 webpack系列的原創文章

 

@font-face有什么用

總結一下就是:用戶借助該規則,可以為引入的字體包命一個名字,並指定在哪里可以找到它(指定字體包的存儲路徑)后,就可以像使用通用字體那樣去使用它了。

具體實現步驟

例如現在的需求是:需要在項目中使用 KlavikaMedium-Italic 字體。

則只需以下三個步驟即可。

1. 將字體包放入項目目錄下

這里放到根目錄下的 tool/fonts 文件夾里。

2. 在index.css文件中定義

@font-face {
  font-family: 'myFont';
  src: url(tool/fonts/KlavikaMedium-Italic.otf);
}

  

3. 使用自定義字體

新建一個index.vue文件,引入樣式:

import './index.css'
<template>
<h1>使用自定義字體</h1>
<style>
  h1 {
    font-family: 'myFont'
  }
</style>
</template>

效果如下:

 

 

 

 

二. webpack項目如何正確打包自定義的字體

1. 打包時報錯

既然在本地開發環境實現了效果,於是就使用 webpack 打包准備上線,卻發現 webpack 在打包過程中報錯:

2. 打包時為什么會報錯

我們在定義自定義字體時使用URL指定了字體包的路徑,由於 webpack 默認是無法處理 css 中的 url 地址的,因此這里會報錯。

3. 解決報錯

3.1 認識file-loader

這時就需要借助 loader 來大顯身手了,解決這個問題需要使用 file-loader,它主要干了兩件事兒:

  • 根據配置修改打包后圖片、字體包的存放路徑;

  • 再根據配置修改我們引用的路徑,使之對應引入。

3.2 安裝file-loader

yarn add file-loader

  

3.3 配置file-loader

在 webpack.config.js 中,配置file-loader:

module.exports = {
  module: {
    rules: [
      {
        // 命中字體包
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        // 只命中指定 目錄下的文件,加快Webpack 搜索速度
        include: [paths.toolSrc],
        // 排除 node_modules 目錄下的文件
        exclude: /(node_modules)/,
        loader: 'file-loader',
      },
    ]
  }
}

  

再次執行打包命令,不再報錯。

4. 自定義字體為什么不生效

於是將打包出來的 dist 目錄重新部署到服務器上后訪問頁面,卻發現由於找不到字體導致沒有生效:

從圖中可以看出,http請求字體包的路徑為:根目錄下(打包出來的靜態文件index.html所在目錄)的 css/620db1b997cd78cd373003282ee4453f.otf

4.1 字體不生效的原因

看了一下打包命令生成的 dist 目錄結構:

├── 620db1b997cd78cd373003282ee4453f.otf
├── css
│   ├── backend.66a35.css
│   └── backend.66a35.css.map
├── favicon.ico
├── images
│   ├── bg.5825f.svg
│   ├── data-baseTexture.c2963.jpg
│   ├── data-heightTexture.6f50d.jpg
│   └── logo.7227a.png
├── index.html
└── js
    ├── backend.66a35.js

  

卻發現,字體包和 index.html 是在同一級。因此字體無法生效的原因就很明朗了:

  • 由於http請求的字體包路徑與實際的存放路徑一致,就導致了404;

  • 找不到字體包的實際路徑,因此使用的字體無法生效。

4.2 字體不生效的解決辦法

可以通過修改字體包打包后的實際存儲路徑去解決這個問題,在 webpack.config.js 中,借助 options 參數可以繼續給 file-loader 設置更多的配置項:

module.exports = {
  module: {
    rules: [
      {
        // 命中字體包
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        // 只命中指定 目錄下的文件,加快Webpack 搜索速度
        include: [paths.toolSrc],
        // 排除 node_modules 目錄下的文件
        exclude: /(node_modules)/,
        loader: 'file-loader',
        // 新增options配置參數:關於file-loader的配置項
        options: {
          limit: 10000,
          // 定義打包完成后最終導出的文件路徑
          outputPath: 'css/fonts/',
          // 文件的最終名稱
          name: '[name].[hash:7].[ext]'
        }
      },
    ]
  }
}

  

再次打包,生成的 dist 目錄結構如下:

├── css
│   ├── backend.66a35.css
│   ├── backend.66a35.css.map
│   └── fonts
│       └── KlavikaMedium-Italic.620db1b.otf
├── favicon.ico
├── images
│   ├── bg.5825f.svg
│   ├── data-baseTexture.c2963.jpg
│   ├── data-heightTexture.6f50d.jpg
│   └── logo.7227a.png
├── index.html
└── js
    ├── backend.66a35.js

  

可以看到字體包正如配置時預期的那樣存儲在 css/fonts 目錄下面。

重新部署項目,再次查看:

這一次 http 請求的字體包路徑與實際的存放路徑一致,因此自定義字體生效。

可以通過下面這個梳理流程圖看的更清楚一些:

 

三. 總結

為什么本地開發的時候可以看到字體,部署到服務器后卻看不到了呢?

  • 由於 webpack 項目在本地開發中使用的是 webpack-dev-server,實時編譯后的文件都保存到了內存當中,引用字體包的時候使用的是絕對路徑,因此在本地開發中使用的自定義字體能夠生效;

  • 使用webpack打包后的 dist 目錄,字體包的實際存儲路徑與 http 請求字體包的路徑不一致,因此導致找不到字體包;

  • 借助 file-loader 解決 webpack 打包報錯,通過使用 options 參數去設置字體包在打包后的實際存儲路徑,從而解決問題。

 

更多文章

 歡迎訪問 webpack 系列文章:

關注微信公眾號

歡迎大家關注我的微信公眾號閱讀 更多 原創文章:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM