Open PullJosh opened 3 years ago
Provide all components to all lessons, but lazy-load the components that are used infrequently. This requires maintaining a list of components that might be used in a separate place from where they are actually being defined and used. So maintenance is a bit of a pain, but initial setup is very straightforward.
To my taste, this option actually seems pretty good. I think the maintenance cost is actually pretty minimal since it's just a list where you put something once while making the component. It also means that the markdown for the article can be totally agnostic to whether the components it uses are special or not. This feels like a nice conceptual separation between content and code, whereas having import statements feels like a little leakage between the two (admittedly a small amount).
I would recommend against a separate list. As the website grows bigger and more complex, it will be harder remember than you have to also update some random file somewhere else in order for your interactive to work. It also may be a pain to lazy load these components.
My upcoming PR has the above ImportComponent
solution, which hopefully works when the site is actually built and not running in dev mode. I also think this component somewhat makes sense because we'll probably want a consistent wrapper for all of the interactives.
All of that said, I think mdx-bundler
should be very strongly investigated in the near future to see if it simplifies things in pages.js
and elsewhere. I also think importing right in the MDX, assuming that they're truly one-off components, makes the most sense. Co-located, simple, and no need for dynamic importing; everything handled at compile time.
All of that said, I think
mdx-bundler
should be very strongly investigated in the near future
I agree. There's a good chance that mdx-bundler
turns out to be the right tool for the job, that makes all the discussion about handling one-off components totally unnecessary. I will probably look into it more soon.
Trying out mdx-bundler
. The first roadblock is this error, where backslashes in math expressions cause issues:
> __mdx_bundler_fake_dir__/_mdx_bundler_entry_point.mdx:94:40: error: [plugin: esbuild-xdm] Could not parse expression with acorn: Expecting Unicode escape sequence \uXXXX
94 │ An example of inline math $f(x) = e^{i \pi} + sin(x)$ in the middle of a sentence.
╵ ^
The error appears whether or not I have the math plugins enabled. I don't have any solution yet; just documenting what I see.
That looks like the math plugin isn’t properly enabled btw, it should work
There are a lot of different ways to use MDX files within Next.js. All of them have pros and cons. (We are currently pursuing
next-mdx-remote
with the final option listed under the header below. After typing up this list of pros and cons, mdx-bundler also looks attractive.)@next/mdx
is built by the Next.js team, but it seems abandoned/poorly documented. It works by configuring webpack.next-mdx-enhanced
This library seems to do a lot of what we want, but it has a big giant warning in the readme which says to usenext-mdx-remote
instead, which scared us away from using it.next-mdx-remote
seems to be the most popular method. It works by parsing mdx files as strings.mdx-bundler
works by parsing mdx files and their Javascript dependencies (such as one-off interactive components) as strings.@next/mdx
next-mdx-remote
mdx-bundler
import
ing one-off components within .mdx file?* Handling one-off components (like interactives)
Many components are shared between almost all lessons, and it is totally reasonable to always load their source code when viewing a lesson.
But other components, such as the special interactive elements, are only used occasionally, perhaps in one or two lessons. We need a way to include those one-off components on the pages where they're used, but not include them when they aren't.
Some tools allow importing those components directly from the .mdx file (see row 2 of the table), but even when that isn't an option, there are alternatives available:
We are yet to try it, but if it works it would be a nice editing experience.