kentcdodds / mdx-bundler

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

Could not resolve node:fs #129

Open szmarci opened 2 years ago

szmarci commented 2 years ago

Relevant code or config

import { bundleMDX } from "mdx-bundler";

What you did:

I try to do the remix blog tutorial, but instead of .md, I try to do it with .mdx files with mdx-bundler. As soon as I import it - it is not called just imported - and run remix dev, it blows up with the message below.

What happened:

  > node_modules/mdx-bundler/node_modules/xdm/lib/integration/esbuild.js:16:29: error: Could not resolve "node:fs" (mark it as external to exclude it from the bundle)
    16 │ import {promises as fs} from 'node:fs'
       ╵                              ~~~~~~~~~

  > node_modules/mdx-bundler/node_modules/xdm/lib/integration/esbuild.js:17:20: error: Could not resolve "node:process" (mark it as external to exclude it from the bundle)
    17 │ import process from 'node:process'
       ╵                     ~~~~~~~~~~~~~~

Package.json

{
  "private": true,
  "name": "remix-app-template",
  "description": "",
  "license": "",
  "scripts": {
    "build": "remix build",
    "dev": "remix dev",
    "postinstall": "remix setup node",
    "start": "remix-serve build"
  },
  "dependencies": {
    "@remix-run/react": "^1.0.6",
    "@remix-run/serve": "^1.0.6",
    "add": "^2.0.6",
    "esbuild": "^0.14.0",
    "front-matter": "^4.0.2",
    "mdx-bundler": "^8.0.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "remix": "^1.0.6",
    "tiny-invariant": "^1.2.0"
  },
  "devDependencies": {
    "@remix-run/dev": "^1.0.6",
    "@types/react": "^17.0.24",
    "@types/react-dom": "^17.0.9",
    "typescript": "^4.1.2"
  },
  "engines": {
    "node": ">=14"
  },
  "sideEffects": false
}
n18l commented 2 years ago

I ran into this exact problem yesterday (with the one exception that I do have to call the function, not just import it) while working through the Remix tutorial and trying to implement mdx-bundler (since it's one of the suggestions elsewhere in their docs). I ended up banging my head against it for several hours without any meaningful progress.

I tried a few versions each of node and esbuild to make sure it wasn't a compatibility issue. I also spent a good chunk of time poring over the source of Kent's own site to understand his own environment and implementation (including migrating my Remix example over to express for parity's sake), but I wasn't ever able to replicate a successful build.

For completeness, here's where my package.json ended up by the time I gave up, in case it points out an obvious issue:

{
  "private": true,
  "name": "remix-app-template",
  "description": "",
  "license": "",
  "scripts": {
    "build": "remix build",
    "dev": "remix watch",
    "postinstall": "remix setup node",
    "start": "cross-env NODE_ENV=production node server/index.js",
    "start:dev": "cross-env NODE_ENV=development node server/index.js"
  },
  "dependencies": {
    "@remix-run/express": "^1.0.6",
    "@remix-run/react": "^1.0.6",
    "compression": "^1.7.4",
    "cross-env": "^7.0.3",
    "express": "^4.17.1",
    "front-matter": "^4.0.2",
    "morgan": "^1.10.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "remix": "^1.0.6",
    "tiny-invariant": "^1.2.0"
  },
  "devDependencies": {
    "@remix-run/dev": "^1.0.6",
    "@types/react": "^17.0.24",
    "@types/react-dom": "^17.0.9",
    "typescript": "^4.1.2"
  },
  "engines": {
    "node": ">=14"
  },
  "sideEffects": false
}
CanRau commented 2 years ago

Just had the issue today and found the "trick" in Kent's codebase.

Make sure to only import mdx-bundler within a file with the suffix .server.ts(x) like mdx.server.ts you can even just export { bundleMDX } from 'mdx-bundler' then in your route import from this file instead, or use it to wrap bundleMDX and predefine settings etc like Kent is doing

More at data-loading#basics

n18l commented 2 years ago

Thanks for that @CanRau! That got me where I needed to go and it seems to be working just fine now.

I had a feeling from the fact that the modules in the error were from node that it had to do with the division between server and client, but I hadn't absorbed the way the .server.{js,ts,tsx} suffix was used in Remix.

kwiat1990 commented 2 years ago

@CanRau it gives me then another error:

mdx-bundler warning: esbuild maybe unable to find its binary, if your build fails you'll need to set ESBUILD_BINARY_PATH. Learn more: https://github.com/kentcdodds/mdx-bundler/blob/main/README.md#nextjs-esbuild-enoent
There was an error running the data loader for route routes/$article
Error: No "exports" main defined in /Users/mateusz.kwiatkowski/Playground/remix-mantine/node_modules/periscopic/package.json
    at new NodeError (node:internal/errors:371:5)
    at throwExportsNotFound (node:internal/modules/esm/resolve:453:9)
    at packageExportsResolve (node:internal/modules/esm/resolve:671:7)
    at resolveExports (node:internal/modules/cjs/loader:482:36)
    at Function.Module._findPath (node:internal/modules/cjs/loader:522:31)
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:919:27)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at node_modules/@mdx-js/mdx/lib/plugin/recma-document.js (/Users/mateusz.kwiatkowski/Playground/remix-mantine/node_modules/@mdx-js/mdx/lib/plugin/recma-document.js:42:23)

The part about setting ESBUILD_BINARY_PATH seems a bit odd as I use Remix and not Nextjs.