一. 如何在Vue或React項目中使用自定義字體
在開發(fā)前端項目時,經(jīng)常會遇到UI同事希望在項目中使用一個炫酷字體的需求。那么怎么在項目中使用自定義字體呢?
其實實現(xiàn)起來并不復(fù)雜画畅,可以借用CSS3 @font-face 來實現(xiàn)。
本文著重介紹一下 webpack 項目如何正確打包引入的自定義字體宋距。
可以訪問 這里 查看更多關(guān)于大數(shù)據(jù)平臺建設(shè)的原創(chuàng)文章 或 webpack系列的原創(chuàng)文章轴踱。
@font-face有什么用
總結(jié)一下就是:用戶借助該規(guī)則,可以為引入的字體包命一個名字谚赎,并指定在哪里可以找到它(指定字體包的存儲路徑)后淫僻,就可以像使用通用字體那樣去使用它了诱篷。
具體實現(xiàn)步驟
例如現(xiàn)在的需求是:需要在項目中使用 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. 打包時報錯
既然在本地開發(fā)環(huán)境實現(xiàn)了效果悯辙,于是就使用 webpack 打包準備上線琳省,卻發(fā)現(xiàn) webpack 在打包過程中報錯:
2. 打包時為什么會報錯
我們在定義自定義字體時使用URL指定了字體包的路徑,由于 webpack 默認是無法處理 css 中的 url 地址的躲撰,因此這里會報錯针贬。
3. 解決報錯
3.1 認識file-loader
這時就需要借助 loader 來大顯身手了,解決這個問題需要使用 file-loader拢蛋,它主要干了兩件事兒:
根據(jù)配置修改打包后圖片桦他、字體包的存放路徑;
再根據(jù)配置修改我們引用的路徑谆棱,使之對應(yīng)引入快压。
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',
},
]
}
}
再次執(zhí)行打包命令嗓节,不再報錯。
4. 自定義字體為什么不生效
于是將打包出來的 dist 目錄重新部署到服務(wù)器上后訪問頁面皆警,卻發(fā)現(xiàn)由于找不到字體導(dǎo)致沒有生效:
從圖中可以看出拦宣,http請求字體包的路徑為:根目錄下(打包出來的靜態(tài)文件index.html所在目錄)的 css/620db1b997cd78cd373003282ee4453f.otf。
4.1 字體不生效的原因
看了一下打包命令生成的 dist 目錄結(jié)構(gòu):
├── 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
卻發(fā)現(xiàn)信姓,字體包和 index.html 是在同一級鸵隧。因此字體無法生效的原因就很明朗了:
由于http請求的字體包路徑與實際的存放路徑一致,就導(dǎo)致了404意推;
找不到字體包的實際路徑豆瘫,因此使用的字體無法生效。
4.2 字體不生效的解決辦法
可以通過修改字體包打包后的實際存儲路徑去解決這個問題菊值,在 webpack.config.js 中外驱,借助 options 參數(shù)可以繼續(xù)給 file-loader 設(shè)置更多的配置項:
module.exports = {
module: {
rules: [
{
// 命中字體包
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
// 只命中指定 目錄下的文件,加快Webpack 搜索速度
include: [paths.toolSrc],
// 排除 node_modules 目錄下的文件
exclude: /(node_modules)/,
loader: 'file-loader',
// 新增options配置參數(shù):關(guān)于file-loader的配置項
options: {
limit: 10000,
// 定義打包完成后最終導(dǎo)出的文件路徑
outputPath: 'css/fonts/',
// 文件的最終名稱
name: '[name].[hash:7].[ext]'
}
},
]
}
}
再次打包腻窒,生成的 dist 目錄結(jié)構(gòu)如下:
├── 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
可以看到字體包正如配置時預(yù)期的那樣存儲在 **css/fonts **目錄下面昵宇。
重新部署項目,再次查看:
這一次 http 請求的字體包路徑與實際的存放路徑一致儿子,因此自定義字體生效瓦哎。
可以通過下面這個梳理流程圖看的更清楚一些:
三. 總結(jié)
為什么本地開發(fā)的時候可以看到字體,部署到服務(wù)器后卻看不到了呢?
由于 webpack 項目在本地開發(fā)中使用的是 webpack-dev-server蒋譬,實時編譯后的文件都保存到了內(nèi)存當(dāng)中割岛,引用字體包的時候使用的是絕對路徑,因此在本地開發(fā)中使用的自定義字體能夠生效犯助;
使用webpack打包后的 dist 目錄癣漆,字體包的實際存儲路徑與 http 請求字體包的路徑不一致,因此導(dǎo)致找不到字體包剂买;
借助 file-loader 解決 webpack 打包報錯惠爽,通過使用 options 參數(shù)去設(shè)置字體包在打包后的實際存儲路徑,從而解決問題雷恃。