graphql-markdown icon indicating copy to clipboard operation
graphql-markdown copied to clipboard

Extend existing doc plugin?

Open slorber opened this issue 4 years ago • 2 comments

Hi and thanks for working on this interesting plugin.

Don't hesitate to submit it to our community docs so users can more easily find it.

One suggestion I could make is, instead of generating the md docs with the CLI, maybe you could extend the docs plugin so that it creates the md files just before reading the md files?

You may find this interesting to try: https://github.com/facebook/docusaurus/issues/4138#issuecomment-771042127

Not sure it would be more convenient than a cli though, but can be worth giving it a try

slorber avatar Feb 17 '21 13:02 slorber

Hi @slorber

Thank you for the feedback.

I forgot to submit after releasing 1.0.0. I will do it this weekend ;-)

I did think about having the build at runtime, but I faced some issue, and it was not important for our internal project. But thanks for the pointer. I will definitively look into that direction, also rewrite the plugin in TS and with a proper theme for displaying the pages (currently it is more of a smart hack rather than a plugin). However, I think that the plugin should offer both options: cli and runtime, both have different use cases:

  • with the cli you can have documentation as a code in you repo
  • with the runtime you can keep the schema as source of truth, and avoid generated files in your repo
  • any many other combos are possible...

edno avatar Feb 20 '21 08:02 edno

thanks for the PR

sure, all this is just a suggestion :) having cli + runtime make sense

slorber avatar Feb 22 '21 17:02 slorber

@slorber - I am tagging you in this thread since you created it, but if you'd rather have this discussion under the Docusaurus repo, then just ask and I'll report it there.

I restarted, without success, the work on plugin extension following the docs for plugin lifecycle and the following discussion on the Docusaurus repo:

  • https://github.com/facebook/docusaurus/issues/4138#issuecomment-771042127
  • https://github.com/facebook/docusaurus/issues/6302
  • https://github.com/facebook/docusaurus/issues/4492

Here a simplified version of the implementation (full code here and in PR #991)

import * as PluginContentDocs from "@docusaurus/plugin-content-docs";

const pluginContentDocs = plugin.default ? plugin.default : plugin;

export default async function pluginGraphQLMarkdown(context, options) {
  const docsPluginInstance = await pluginContentDocs(context, options);

  const loadContent = async () => {
    // resolve configuration
    const config = await buildConfig(options);
    // generate MDX files from Schema
    await generateDocFromSchema(config);
    // Handover to @docusaurus/plugin-content-docs 
    return await docsPluginInstance.loadContent();
  };

  return {
    ...docsPluginInstance,
    name: "docusaurus-graphql-doc-generator",
    loadContent,
  };
}

The MDX files are correctly generated by generateDocFromSchema, but when contentLoaded is called I end up with the following error

[ERROR] MDX loader can't read MDX metadata file "/docusaurus2/.docusaurus/docusaurus-plugin-content-docs/schema_tweets/site-docs-groups-md-fd7.json". Maybe the isMDXPartial option function was not provided?
[ERROR] Error: ENOENT: no such file or directory, open '/docusaurus2/.docusaurus/docusaurus-plugin-content-docs/schema_tweets/site-docs-groups-md-fd7.json'

This let me assume that docsPluginInstance.loadContent() is not processing files previously created by my plugin :thinking:

edno avatar Sep 09 '23 17:09 edno

Hmmm I don't know, what are the files it generates, their content and path?

Maybe try to create a repro by hardcoding these files locally instead of generating them, so that I can inspect it?

slorber avatar Sep 14 '23 11:09 slorber

@slorber - Apologies for the late feedback.

I managed to create a simple repo reproducing the issue: https://github.com/edno/graphql-markdown-docusaurus-plugin-debug

edno avatar Sep 30 '23 18:09 edno

@slorber - I think I found a possible root cause.

If one wants to "extend" docusaurus-plugin-content-docs by intercepting the plugin lifecyle, it will break because the data is not generated under the temp folder docusaurus-plugin-content-docs. However, it is not possible to change the data location because of:

  1. Docusaurus creates a temp path for every plugin declared in docusaurus.config.js. However, the path is defined using the plugin name as declared in the config and not the plugin name as exported by the plugin. So, far I assume this is exactly how it should be (but undocumented). Subfolders with instance id are created below the plugin temp path.
  2. Plugin docusaurus-plugin-content-docs has a hardcoded path containing docusaurus-plugin-content-docs (https://github.com/facebook/docusaurus/blob/56410aa94665699f75cb889f477ccdffb98f2b21/packages/docusaurus-plugin-content-docs/src/index.ts#L77).

A possible solution would be to be able to override the path in 2. Ideally, this would be done by adding a pluginDataDirRoot to the Docusaurus context defined in 1. This would allow a plugin to be aware of the temp data path without calculating it, and avoid adding "extension" parameters.

If this solution makes sense to you, then I will investigate how to implement it and push a PR for Docusaurus.

edno avatar Oct 06 '23 21:10 edno

Hey, to be honest I have a hard time understanding your issue 🤪

If one wants to "extend" docusaurus-plugin-content-docs by intercepting the plugin lifecyle, it will break because the data is not generated under the temp folder docusaurus-plugin-content-docs.

Which data, what is the temp folder path exactly, and what does it mean to "break"?

  1. Docusaurus creates a temp path for every plugin declared in docusaurus.config.js. However, the path is defined using the plugin name as declared in the config and not the plugin name as exported by the plugin.

Can you give me a concrete example, what is this temp folder path exactly for the docs plugin?

VS the one you use for your inherited plugin?

And how is it a problem?

Where is the code that is supposed to create this behavior? Because I don't see what you mean here. Afaik we only create .docusaurus/docusaurus-plugin-content-docs/id and that's all (if .docusaurus is what you mean by "temp folder")

  1. Plugin docusaurus-plugin-content-docs has a hardcoded path.

Yes, and if you want to emit json bundle files in the same path you can hardcode this as well in your inherited plugin no?

  const pluginDataDirRoot = path.join(
    generatedFilesDir,
    'docusaurus-plugin-content-docs',
  );
  const dataDir = path.join(pluginDataDirRoot, pluginId);

A possible solution would be to be able to override the path in 2. Ideally, this would be done by adding a pluginDataDirRoot to the Docusaurus context defined in 1. This would allow a plugin to be aware of the temp data path without calculating it, and avoid adding "extension" parameters.

How would that pluginDataDirRoot in context be populated? To be able to read plugin.name you must first call the plugin function which receives that context, so you kind of have a circular dependency here.


All this is not super fresh in my mind sorry 😅 maybe we should first figure out what are the blockers exactly, on a super simple use case (like just generating one doc file) before trying to even make this plugin work entirely

slorber avatar Oct 09 '23 15:10 slorber

All this is not super fresh in my mind sorry 😅 maybe we should first figure out what are the blockers exactly, on a super simple use case (like just generating one doc file) before trying to even make this plugin work entirely

@slorber - Maybe the repo https://github.com/edno/graphql-markdown-docusaurus-plugin-debug will be more explanatory than my previous comment.

edno avatar Oct 09 '23 15:10 edno

Closing the issue as there's no straight forward solution without changing Docusaurus plugin handling (lifecycle hooks).

edno avatar Jan 14 '24 11:01 edno