基于 Taro 的微信小程序開發(fā)實戰(zhàn):如何支持高亮代碼塊
如果我們想要開發(fā)一款程序員使用的社區(qū)小程序,那么對 markdown 格式的解析與渲染是一個非常重要的功能。不過要完善的支持 .md 格式,在微信小程序中并不是一件容易的事情。好在微信小程序目前已經(jīng)支持 html 標(biāo)簽渲染,因此我們有許多的 web 方案可以借鑒。
我實現(xiàn)的最終的效果如上圖所示。引入成功,并且在真機測試通過。接下來具體跟大家分享一下實現(xiàn)步驟。
// 我的開發(fā)環(huán)境
Taro 3.6.6
Node 16.19.1
一、支持引入 .md 文件
正常情況下,我們應(yīng)該從接口中獲取到當(dāng)前文件的 markdown 內(nèi)容,不過偶爾也需要支持本地 .md 文件的渲染,因此首先我們要在工程里支持引入 .md 文件。
首先支持如下操作,引入 raw-loader。
pnpm add raw-loader
然后在工程配置文件中 config/index.ts 新增如下配置。
module.exports = {
// ...
mini: {
// ...
webpackChain(chain, webpack) {
chain.merge({
module: {
rule: {
myloader: {
test: /\.md$/,
use: [
{
loader: 'raw-loader',
options: {},
},
],
},
},
},
})
},
},
}
由于我的項目中使用了 ts,因此直接引入 .md 文件還會報錯。
在 types/global.d.ts 中,新增 md 文件的配置即可解決該問題。
...
declare module '*.scss';
declare module '*.sass';
declare module '*.styl';
+ declare module '*.md';
二、引入 markdown 解析器
我使用了一款名為 wemark 的 Markdown 渲染庫。不過由于年久失修,如果按照該作者的方式直接使用的話會有一些問題。因此請盡量按照我的步驟來在項目中配置。
首先我們需要下載該項目。
git clone https://github.com/TooBug/wemark.git
然后將該項目中的文件 wemark 復(fù)制到 Taro 項目中 src 目錄中。
設(shè)置編譯時復(fù)制 wemark 目錄。修改 config/index.ts,在 copy 設(shè)置項中增加 wemark。
copy: {
patterns: [
{
from: 'src/wemark',
to: 'dist/wemark',
},
],
options: {}
},
我們可以通過如下方式在頁面中引入 wemark,創(chuàng)建頁面時,我們會創(chuàng)建一個 index.config.ts 的文件,使用 usingComponents 配置好。
export default definePageConfig({
navigationBarTitleText: '代碼塊高亮',
navigationStyle: 'default',
usingComponents: {
wemark: '../../wemark/wemark'
}
})
這樣我們可以直接在頁面中使用。
import { View } from '@tarojs/components'
import code from './code.md'
import './index.scss'
function Parse() {
return (
<View>
<wemark md={code} link highlight type='wemark' />
</View>
)
}
export default Parse
我們可以在 src/wemark/wemark.wxss 中,修改渲染之后的樣式。
調(diào)整好之后,樣式如下:
目前已基本完成,但是字體有點不好看,因此我們需要引入一個專門用來展示代碼的等寬字體,這里我們引入的是 SF Mono。
三、引入自定義字體
在微信小程序中引入自定義字體也并非易事。
我們可以使用它官方文檔中提供的方案通過網(wǎng)絡(luò)地址來引入。
wx.loadFontFace({
family: 'FZSuXSLSJW',
source: 'url("https://we7.stuyun.com/FZSuXSLSJW.ttf")',
success: res => {
console.log('font load success', res)
},
fail: err => {
console.log('font load fail', err)
}
})
但是這種方案有一些不太爽的限制,該地址必須與小程序同源,或者設(shè)置了可以跨域訪問。并且不支持本地的字體文件。
因此我們只能通過把字體文件轉(zhuǎn)成 base64 的格式,然后通過 @font-face 來自定義字體。
transfonter.org 可以免費的幫助我們將字體文件轉(zhuǎn)換成 base64。
拿到對應(yīng)字體的 base64 之后,然后自定義樣式即可。
@font-face {
font-family: 'SFMono';
src: url('data:font/ttf;charset=utf-8;base64,AAEAAAANAIAAAwBQRkZUTYhof28AAoBMAAAAHE....
}
最后,在src/wemark/wemark.wxss 中,給代碼塊設(shè)置樣式屬性。
.wemark_block_code{
font-family: SFMono;
...
}
搞定!
四、按需加載
微信小程序?qū)Πw積有嚴(yán)格的限制。這樣處理之后,包體積可能會有點大。字體文件有接近 200k,remark 也不小。因此我們還需要進一步做優(yōu)化。
仔細觀察 wemark 文件,我們發(fā)現(xiàn)他其實是基于 remark 實現(xiàn)的一個自定義小程序組件。
因此,我們可以把自定義字體的樣式寫在 wemark.wxss 中,然后將該組件設(shè)置為按需引入,那么在小程序啟動時,就可以不用加載該組件。
微信小程序目前已經(jīng)支持了按需引入。在 wemark.json 中,添加如下配置。
{
"lazyCodeLoading": "requiredComponents"
}
五、總結(jié)
因為微信小程序現(xiàn)在已經(jīng)支持 html 標(biāo)簽的渲染,因此我們有很多在 web 上能使用的方案也能運用于小程序中,但是由于微信小程序?qū)Υ虬w積有限制,因此,功能驗證成功之后,要多考慮這方面的問題。