将段落节点替换为 HTML 个节点
Replacing paragraph nodes with HTML nodes
问题
如何将“段落”节点替换为 MDX 的“html”节点?
背景
将每个“twitter.com”链接替换为扩展的 Twitter 嵌入 HTML 到 MDX 内容中。
可重现的 CodeSandbox:https://codesandbox.io/s/dazzling-curran-2bcwe?file=/src/index.mjs:2024-3439
问题
我有一个 MDX 内容,其中包含一个 Twitter 链接列表(例如 https://twitter.com/BrendanEich/status/1151317825908166656),替换段落节点会导致以下错误
../node_modules/esbuild/lib/main.js:869:27: error: [plugin:
esbuild-xdm] Cannot read property 'line' of undefined
at failureErrorWithLog (/sandbox/node_modules/esbuild/lib/main.js:1449:15)
at /sandbox/node_modules/esbuild/lib/main.js:1131:28
at runOnEndCallbacks (/sandbox/node_modules/esbuild/lib/main.js:921:63)
at buildResponseToResult (/sandbox/node_modules/esbuild/lib/main.js:1129:7)
at /sandbox/node_modules/esbuild/lib/main.js:1236:14
at /sandbox/node_modules/esbuild/lib/main.js:609:9
at handleIncomingPacket (/sandbox/node_modules/esbuild/lib/main.js:706:9)
at Socket.readFromStdout (/sandbox/node_modules/esbuild/lib/main.js:576:7)
at Socket.emit (events.js:315:20)
at addChunk (internal/streams/readable.js:309:12)
有问题的代码
const remarkTwitter = (options) => {
return transformer;
async function transformer(tree) {
// gather Twitter links
visit(tree, "paragraph", (node) => {
if (isTwitterLink(node)) {
const tweetLink = node.children[0].value;
tweetNodeList.push([node, tweetLink]);
}
});
// Build Tweet embed HTML
// and replace the current node
for (let i = 0; i < tweetNodeList.length; i++) {
const twitterNode = tweetNodeList[i];
const node = twitterNode[0];
const tweetLink = twitterNode[1];
try {
const embedData = await getEmbeddedTweet(tweetLink, options);
node.type = "html";
node.value = embedData.html;
return node;
} catch (err) {
console.error(err);
}
}
}
};
我使用的不是我的自定义插件,而是 @remark-embedder/core 插件
这是使用插件的部分代码。
import remarkEmbedder from "@remark-embedder/core";
// other imports...
const getMDXOptions = (year: number, slug: string) => {
const cwd = `${getBlogRoot(year, slug)}`;
const imagesUrl = `/images/blog/${year}/${slug}`;
return {
cwd,
xdmOptions: (options: any) => {
options.format = "mdx";
options.allowDangerousRemoteMdx = true;
options.rehypePlugins = [twitterWidgetScriptPlugin];
options.remarkPlugins = [
remarkMdxImages,
[
remarkEmbedder,
{
transformers: [
githubGistTransformer,
codeSandboxTransformer,
[oembedTransformer, oembedConfig],
],
handleHTML,
},
],
];
return options;
},
esbuildOptions: (options: BuildOptions) => {
options.outdir = path.join(process.cwd(), "public", imagesUrl);
options.loader = {
...options.loader,
".png": "file",
".jpg": "file",
".gif": "file",
".svg": "file",
};
options.publicPath = imagesUrl;
options.write = true;
return options;
},
};
};
问题
如何将“段落”节点替换为 MDX 的“html”节点?
背景
将每个“twitter.com”链接替换为扩展的 Twitter 嵌入 HTML 到 MDX 内容中。
可重现的 CodeSandbox:https://codesandbox.io/s/dazzling-curran-2bcwe?file=/src/index.mjs:2024-3439
问题
我有一个 MDX 内容,其中包含一个 Twitter 链接列表(例如 https://twitter.com/BrendanEich/status/1151317825908166656),替换段落节点会导致以下错误
../node_modules/esbuild/lib/main.js:869:27: error: [plugin: esbuild-xdm] Cannot read property 'line' of undefined at failureErrorWithLog (/sandbox/node_modules/esbuild/lib/main.js:1449:15) at /sandbox/node_modules/esbuild/lib/main.js:1131:28 at runOnEndCallbacks (/sandbox/node_modules/esbuild/lib/main.js:921:63) at buildResponseToResult (/sandbox/node_modules/esbuild/lib/main.js:1129:7) at /sandbox/node_modules/esbuild/lib/main.js:1236:14 at /sandbox/node_modules/esbuild/lib/main.js:609:9 at handleIncomingPacket (/sandbox/node_modules/esbuild/lib/main.js:706:9) at Socket.readFromStdout (/sandbox/node_modules/esbuild/lib/main.js:576:7) at Socket.emit (events.js:315:20) at addChunk (internal/streams/readable.js:309:12)
有问题的代码
const remarkTwitter = (options) => {
return transformer;
async function transformer(tree) {
// gather Twitter links
visit(tree, "paragraph", (node) => {
if (isTwitterLink(node)) {
const tweetLink = node.children[0].value;
tweetNodeList.push([node, tweetLink]);
}
});
// Build Tweet embed HTML
// and replace the current node
for (let i = 0; i < tweetNodeList.length; i++) {
const twitterNode = tweetNodeList[i];
const node = twitterNode[0];
const tweetLink = twitterNode[1];
try {
const embedData = await getEmbeddedTweet(tweetLink, options);
node.type = "html";
node.value = embedData.html;
return node;
} catch (err) {
console.error(err);
}
}
}
};
我使用的不是我的自定义插件,而是 @remark-embedder/core 插件
这是使用插件的部分代码。
import remarkEmbedder from "@remark-embedder/core";
// other imports...
const getMDXOptions = (year: number, slug: string) => {
const cwd = `${getBlogRoot(year, slug)}`;
const imagesUrl = `/images/blog/${year}/${slug}`;
return {
cwd,
xdmOptions: (options: any) => {
options.format = "mdx";
options.allowDangerousRemoteMdx = true;
options.rehypePlugins = [twitterWidgetScriptPlugin];
options.remarkPlugins = [
remarkMdxImages,
[
remarkEmbedder,
{
transformers: [
githubGistTransformer,
codeSandboxTransformer,
[oembedTransformer, oembedConfig],
],
handleHTML,
},
],
];
return options;
},
esbuildOptions: (options: BuildOptions) => {
options.outdir = path.join(process.cwd(), "public", imagesUrl);
options.loader = {
...options.loader,
".png": "file",
".jpg": "file",
".gif": "file",
".svg": "file",
};
options.publicPath = imagesUrl;
options.write = true;
return options;
},
};
};