2021-05-12 14:32:11
webpack專案如何正確打包引入的自定義字型
一. 如何在Vue或React專案中使用自定義字型
在開發前端專案時,經常會遇到UI同事希望在專案中使用一個炫酷字型的需求。那麼怎麼在專案中使用自定義字型呢?
其實實現起來並不複雜,可以借用CSS3 @font-face 來實現。
本文著重介紹一下 webpack 專案如何正確打包引入的自定義字型。
可以存取 這裡 檢視更多關於巨量資料平臺建設的原創文章 或 webpack系列之loader及簡單的使用。
@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 請求字型包的路徑不一致,因此導致找不到字型包;
-
關注微信公眾號
歡迎大家關注我的微信公眾號閱讀更多原創文章:
相關文章