kentcdodds / mdx-bundler

🦤 Give me MDX/TSX strings and I'll give you back a component you can render. Supports imports!
MIT License
1.75k stars 75 forks source link

Compatability with twin.macro (and other babel-plugin-macro libs) #106

Open arlyon opened 2 years ago

arlyon commented 2 years ago

Relevant code or config

Sample mdx file using twin.macro (https://github.com/ben-rogerson/twin.macro)

import tw from "twin.macro"
<div tw="bg-red-500">Hello World</div>

Here's what happens during development:

Error: Build failed with 21 errors:
../../node_modules/babel-plugin-macros/dist/index.js:3:18: error: Could not resolve "path" (use "platform: 'node'" when building for node)
../../node_modules/cosmiconfig/dist/Explorer.js:8:43: error: Could not resolve "path" (use "platform: 'node'" when building for node)
../../node_modules/cosmiconfig/dist/ExplorerBase.js:9:43: error: Could not resolve "path" (use "platform: 'node'" when building for node)
../../node_modules/cosmiconfig/dist/ExplorerSync.js:8:43: error: Could not resolve "path" (use "platform: 'node'" when building for node)
../../node_modules/cosmiconfig/dist/getDirectory.js:9:43: error: Could not resolve "path" (use "platform: 'node'" when building for node)
...
    at failureErrorWithLog (/home/arlyon/Programming/gym-game/web/node_modules/esbuild/lib/main.js:1493:15)
    at /home/arlyon/Programming/gym-game/web/node_modules/esbuild/lib/main.js:1151:28
    at runOnEndCallbacks (/home/arlyon/Programming/gym-game/web/node_modules/esbuild/lib/main.js:941:63)
    at buildResponseToResult (/home/arlyon/Programming/gym-game/web/node_modules/esbuild/lib/main.js:1149:7)
    at /home/arlyon/Programming/gym-game/web/node_modules/esbuild/lib/main.js:1258:14
    at /home/arlyon/Programming/gym-game/web/node_modules/esbuild/lib/main.js:629:9
    at handleIncomingPacket (/home/arlyon/Programming/gym-game/web/node_modules/esbuild/lib/main.js:726:9)
    at Socket.readFromStdout (/home/arlyon/Programming/gym-game/web/node_modules/esbuild/lib/main.js:596:7)
    at Socket.emit (events.js:400:28)
    at Socket.emit (domain.js:532:15) {
  errors: [
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "path" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "path" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "path" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "path" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "path" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "os" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "fs" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "path" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "fs" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "path" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "module" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "fs" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "fs" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "path" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "path" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "fs" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "path" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "os" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "tty" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "path" (use "platform: 'node'" when building for node)`
    },
    {
      detail: undefined,
      location: [Object],
      notes: [],
      pluginName: '',
      text: `Could not resolve "fs" (use "platform: 'node'" when building for node)`
    }
  ],
  warnings: []
}

Problem description:

I am serving it over nextjs and, from what I understand, this issue arises because twin.macro is intended to be run at build time but isn't being invoked properly. My gut says esbuild isn't playing nicely since twin.macro uses babel-plugin-macros, so the question is does this support tools utilising babel-plugin-macros in the MDX and how do we make it happen? If it is supposed to 'just work', then I'll whip up a repro-repo as well.

dominik-sfl commented 2 years ago

I would also be very interested in this, since this is the only issue that keeps me from switching from next-mdx-remote to mdx-bundler, as all of my MDX components are using twin.macro. It seems to have to do with esbuild and babel-plugin-macros, but I'm also not entirely sure. Tried googling a bit, but haven't found much apart from a tweet, suspecting the same thing.

dominik-sfl commented 2 years ago

Any news on this one? Have you been able to find a working solution, @arlyon ? I haven't had much success, but would be very interested in figuring this one out, as it would really make a big difference to be able to use twin.macro with mdx-bundler. If @kentcdodds says this should just work as is, I will keep trying, but in the past 2 weeks I didn't really get anywhere with this.

kentcdodds commented 2 years ago

I'm afraid I haven't tried using any of these tools with mdx-bundler, but keep in mind that compilation is handled by esbuild which does not support babel plugins so I don't know that you'll be able to get these things working...

dominik-sfl commented 2 years ago

Thanks for your answer @kentcdodds. What would need to happen to get the two packages to work together? I am not so familiar with ESBuild / Babel etc., so I'm a bit stuck, but I would like to maybe at least give it a try, if it's in principle doable.

kentcdodds commented 2 years ago

I think in theory it's possible, but I don't know how I'm afraid. Sorry.