Docusaurus:在 loadContent 期间写入文件系统对于插件来说是不好的做法吗?

问题描述 投票:0回答:1

我想使用“docs”插件和自定义(JavaScript)插件将文档填充到我的 Docusaurus 项目中,以将其连接到无头 CMS。目前,我正在使用 loadContent Lifecycle API 事件调用我的 Headless CMS API,然后使用 fs.writeFileSync 在“/docs”中创建物理 Markdown 文件并覆盖 ./sidebars.js 文件,以便“docs” ' 带有经典预设的插件可以工作。

./my-plugin/index.js:

module.exports = function (context, options) {
return {
  name: 'my-docusaurus-plugin',
  async loadContent() {
    //calls to Headless CMS API for documentation content
    let response =  await fetchArticles('documentation');
    // Adds the markdown files for 'docs' plugin using fs.writeFileSync   
    await buildArticles(response)

    //fetch homepage and navigation sections from CMS API
    let homepage = await fetchPages('homepage');
    let sidebarSection = await fetchPages('page');

    //overwrite ./sidebars.js with API navigation data using fs.writeFileSync
    await buildSidebar(homepage, sidebarSection);
  }
};

};

这是可行的,因为我从 CMS 和文档渲染中获取内容,但它似乎更像是一种解决方法,而不是连接无头 CMS 与 Docusaurus 的优雅解决方案。我是否缺少一些最佳实践,或者是否有使用其他生命周期事件的更好方法?

plugins docusaurus
1个回答
0
投票

前几天我在构建自己的 Docusaurus 插件时遇到了同样的问题,而且我也无法在文档中找到明确的答案。实现插件的预期方法似乎是:

  1. loadContent
    函数返回内容。
  2. contentLoaded
    函数中接收返回的内容,并使用它来创建数据以提供给路由。您也可以在此处创建显示数据的路线。

但是,该模型似乎不适用于检索要在文档中显示的数据。

@docusaurus/plugin-content-docs
插件似乎没有为其他插件提供任何方法来为其提供包含在文档中的数据,因此似乎唯一的方法是将 Markdown 文件写入
/docs
目录。

但是,正如 Gabin 的评论中提到的,这会导致无限循环。经过一番调查后,我能够解释原因。问题是,只要在 any 插件监视的目录中更新文件,就会触发重新加载,并在

all
插件上调用 loadContent 函数。因此,如果将自定义插件配置为写入
/docs
并且触发重新加载,则会调用自定义插件的
loadContent
函数并将文件重写为
/docs
。但由于
/docs
@docusaurus/plugin-content-docs
监视,自定义插件在
/docs
中更新的每个文件都会触发另一个重新加载,这会导致自定义插件的
loadContent
函数再次被调用...这会导致无限循环.

我确实找到了解决此问题的方法,即如果预期内容与实际内容之间没有不匹配,则避免写入

/docs
,从而防止再次重新加载。在三种不同的场景(并不相互排斥)中,插件需要更改
/docs

  1. /docs
    中现有文件的内容需要更改。
  2. 需要添加一个新文件到
    /docs
  3. 需要从
    /docs
    中删除旧文件。

对于上面的场景 1,我必须编写一些代码来检查我要写入的文件

/docs
是否已经存在,并检查它是否已经包含我要写入的相同内容。如果这些条件都成立,那么我会跳过写入文件,因为没有什么可更改的。

对于上面的场景 3,我必须将“清理”代码移至

loadContent
函数的末尾。由于序列更改,我还必须修改该代码,这样它不会删除目标目录中的所有文件,而是仅删除不希望出现的任何“额外”文件。

即使进行了这些更改,每当需要写入

loadContent
时,仍然会至少对自定义插件的
/docs
函数进行一次不必要的调用,因为对
/docs
的写入将触发重新加载,从而调用
loadContent
再次。但随后它会发现没有任何更改需要进行,并且它将避免再次写入
/docs
并触发另一次重新加载。这至少比无限循环好得多! 😅

我认为 Docusaurus 可以通过以下方式之一解决这个问题:

  1. 创建一种方法,让插件告诉 Docusaurus 仅在重新加载时调用其
    loadContent
    函数(如果重新加载是由插件的
    getPathsToWatch
    函数返回的目录更改触发的)。
  2. 创建一种向
    @docusaurus/plugin-content-docs
    等官方插件提供数据的方法。看起来这个 GitHub Issue 中已经提出了“中间件”功能,我认为这将是一个很好的解决方案。
© www.soinside.com 2019 - 2024. All rights reserved.