2023-11-14 ~ 10 min read
部署到vercel和自己定义代码高亮

本文是接《用MDX和Remix创建自己的Blog》的,如果你还没有看过,可以先看一下。
前提
为了开始,您首先需要一个域名。本例中使用了通过 Cloudflare 托管的域名。如果您还没有域名,可以选择使用 Vercel 提供的免费二级域名。
接下来,您将需要一个 Vercel 账户。如果您还未注册,可以轻松地在 Vercel 官网 创建一个账户。
最后,您还需要拥有 GitHub、GitLab 或 Bitbucket 中的任何一个账户。这是为了实现代码的托管和自动部署。
部署到Vercel
登录Vercel,点击Add New...,选Project然后跟着向导完成即可。
关于Vercel和Cloudflare的使用可以参考《Vercel and Cloudflare Integration》,我用的是“Using Cloudflare as Your DNS Provider”。
自定义代码高亮
因为rehype-highlight没有显示脚本类型和复制按钮功能,所以我们需要自定义代码高亮。
我的思路是对rehype-highlight进行扩展,让它可以加载自己写的Pre组件进行展示。
扩展rehype-highlight插件:
jsimport rh from "rehype-highlight";
function enhancedRehypHighlight(options) {
const _rh = rh(options);
return (tree, file) => {
visit(tree, (node) => {
if (node?.type === "element" && node?.tagName === "pre") {
const [codeElement] = node.children;
if (codeElement.tagName !== "code") {
return;
}
node.properties.code = codeElement.children[0].value;
if (!codeElement.properties.className) {
return;
}
node.properties.language = codeElement.properties.className[0].slice(
"language-".length
);
}
});
_rh(tree, file);
visit(tree, (node) => {
if (node?.type === "element" && node?.tagName === "pre") {
node.tagName = "Pre";
}
});
tree.children.push(preComponentImport);
};
}
const preComponentImport = {
type: "mdxjsEsm",
data: {
estree: {
type: "Program",
body: [
{
type: "ImportDeclaration",
specifiers: [
{
type: "ImportDefaultSpecifier",
local: {
type: "Identifier",
name: "Pre",
},
},
],
source: {
type: "Literal",
value: "~/components/pre",
raw: '"~/components/pre"',
},
},
],
sourceType: "module",
},
},
};
export default enhancedRehypHighlight;
这里的preComponentImport是为了在MDX中引入自定义的Pre组件,代码如下:
tsximport { useCallback, type PropsWithChildren } from "react";
import { Button } from "./ui/button";
type PreProps = PropsWithChildren<{ code: string; language?: string }>;
export default function Pre({
children,
code,
language = "",
...other
}: PreProps) {
const copyHandler = useCallback(() => {
navigator.clipboard.writeText(code);
}, [code]);
return (
<pre {...other}>
<div className="border-b h-8 flex bg-muted items-center justify-between">
<span className="text-muted-foreground text-sm pl-4">{language}</span>
<Button
variant="link"
className="text-muted-foreground text-sm hover:hover:no-underline p-0 pr-4 h-fit"
onClick={copyHandler}
>
copy
</Button>
</div>
{children}
</pre>
);
}
剩下的就是把enhancedRehypHighlight放到remix.config.js中即可。
diff+ import enhancedRehypHighlight from "./tools/rehype-highlight";
...
export const config: UserConfig = {
...
rehypePlugins: [
...
+ enhancedRehypHighlight,
...
],
...
};