question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support for server-side rendering via a Babel plugin?

See original GitHub issue

This project is super cool! I was just trying to figure out the best way to add markdown support to the JSX-based static site generator I’m working on and then I found this—it’s exactly what I’m looking for!

I’m struggling to figure out how to use it, though. I see that there is a Webpack loader, but I’m not using Webpack—the files aren’t being bundled for the browser. I see there is also an API for transforming MDX strings/files, but the problem is I need to actually require/run the JavaScript locally, because the JSX/MDX is being rendered server-side by React.

I think the general thing people do is hook into Node’s require using babel-register.

babelRegister({
  extensions: [".jsx"],
  presets: [
    "react",
    [
      "env",
      {
        node: "current",
      }
    ]
  ],
})

Then you can require the JSX file/module and render it. If the module requires/imports other files they’ll also get transpiled because of babel-register.

let component = require(modulePath)
component = component.default || component

let element = React.createElement(component)

return ReactDOMServer.renderToStaticMarkup(element)

I found a relatively old project babel-plugin-transform-mdx. I tried using it but it seems to be broken.

❯ cat test.mdx 
# Hello, world!

❯ babel --plugins transform-mdx test.mdx
SyntaxError: test.mdx: Unexpected character '#' (1:0)
> 1 | # Hello, world!
    | ^
  2 | 

I’ve got some experience with ASTs so I’d normally get my hands dirty and figure out how to make this work, but after reading the MDX transform in that repo and the JSX transform included with Babel, I’m finding the barrier to entry to be extremely high. 😞

Some time ago JSX became ubiquitous enough that it seemingly made sense for Babel to take ownership of JSX transformation. Since MDX is dependent on (or a sibling of) JSX, it makes sense to me that it should be usable in the same way that JSX is. Does the MDX team agree? Would you be willing to add support for a Babel plugin? 🙏

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
brandonweisscommented, Aug 2, 2018

Alright, here’s what I wound up doing.

The first part is setting up the transformation hook.

import { addHook as overrideRequire } from "pirates"
import { sync as mdxTransform } from "@mdx-js/mdx"
import { transform as babelTransform } from "babel-core"

const transform = (code) => {
  let jsxWithMDXTags = mdxTransform(code)

  let jsx = `
    import { MDXTag } from "@mdx-js/tag"

    ${jsxWithMDXTags}
  `

  let result = babelTransform(jsx, {
    plugins: "babel-plugin-react-require",
    presets: [
      "babel-preset-react",
      [
        "babel-preset-env",
        {
          node: "9.7.1",
        },
      ],
    ],
  })

  return result.code
}

overrideRequire(transform, { exts: [".mdx"] })

The second part is actually importing/requiring the file which triggers the transformation.

import React from "react"
import ReactDOMServer from "react-dom/server"

export default async (modulePath, props) => {
  let component = await import(modulePath)
  let element = React.createElement(component.default, props)
  let html = ReactDOMServer.renderToStaticMarkup(element)

  return `<!DOCTYPE html>\n\n${html}`
}

This isn’t the exact code—I’ve simplified it to make it easier to understand, but this is the general idea. Also this uses ES6. You’ll need to convert to CommonJS or use esm.

0reactions
timneutkenscommented, Jun 25, 2018

Feel free to share the solution you figure out here 🙏

Read more comments on GitHub >

github_iconTop Results From Across the Web

Server Side Rendering - Loadable Components
1. Install @loadable/babel-plugin · 2. Install @loadable/webpack-plugin · 3. Setup ChunkExtractor server-side · 4. Add loadableReady client-side.
Read more >
Server-Side Rendering with React, Node, Webpack & Babel
An easy to follow explanation of how to implement server side rendering using React, Node, Webpack & Babel.
Read more >
Server-Side Rendering | Reactant
SSR (Server-Side Rendering) can greatly improve the first rendering time, the most popular React SSR framework is Next.js. Currently, Reactant has supported ......
Read more >
Server Side Rendering - Reactive Manual
Server Side Rendering enables us to pre-render the results on the server enabling better SEO for the app, and faster delivery of relevant...
Read more >
Server-Side Rendering - SurviveJS
To demonstrate SSR, you can use webpack to compile a client-side build that then gets picked up by a server that renders it...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found