Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"ENOENT: no such file or directory" when trying to use image bundling #127

Open
chemicalkosek opened this issue Nov 14, 2021 · 3 comments
Open

Comments

@chemicalkosek
Copy link

chemicalkosek commented Nov 14, 2021

Hi. I'm having a problem bundling images. (Sorry upfront if it's wrong posting in issues, couldn't find any community. Enable Discussions maybe?)

I'm using Next.js
When trying to copy the images as per docs, I'm getting the following error when accessing the mdx page:

Server Error
Error: ENOENT: no such file or directory, open '../../public/img/first-post/_mdx_bundler_entry_point-1bc7683e-0501-46a8-a3f9-58c40044932c.js'

On each refresh it creates another _mdx_bundler_entry_point with different hash. (?)

My mdx setup:

import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { bundleMDX } from 'mdx-bundler';
import { remarkMdxImages } from 'remark-mdx-images';

export const POSTS_PATH = path.join(process.cwd(), 'data/posts');

export const getSourceOfFile = (fileName) =>
  fs.readFileSync(path.join(POSTS_PATH, fileName));

export const getAllPosts = () =>
  fs
    .readdirSync(POSTS_PATH)
    .filter((currentPath) => /\.mdx?$/.test(currentPath))
    .map((fileName) => {
      const source = getSourceOfFile(fileName);
      const slug = fileName.replace(/\.mdx?$/, '');
      const { data } = matter(source);

      return {
        frontmatter: data,
        slug,
      };
    });

export const getSinglePost = async (slug) => {
  if (process.platform === 'win32') {
    process.env.ESBUILD_BINARY_PATH = path.join(
      process.cwd(),
      'node_modules',
      'esbuild',
      'esbuild.exe'
    );
  } else {
    process.env.ESBUILD_BINARY_PATH = path.join(
      process.cwd(),
      'node_modules',
      'esbuild',
      'bin',
      'esbuild'
    );
  }
  const source = getSourceOfFile(`${slug}.mdx`);
  const { code, frontmatter } = await bundleMDX(source, {
    cwd: POSTS_PATH,
    xdmOptions: (options) => {
      options.remarkPlugins = [
        ...(options.remarkPlugins ?? []),
        remarkMdxImages,
      ];

      return options;
    },
    esbuildOptions: (options) => {
      options.outdir = `../../public/img/${slug}`;
      options.loader = {
        ...options.loader,
        '.jpg': 'file',
      };
      options.publicPath = `img/${slug}`;
      options.write = true;

      return options;
    },
  });

  return {
    frontmatter,
    code,
  };
};

The mdx file:

---
title: First Post
---

## This is a h2

This is my first post

![altText](../../images/basen-nowy.jpg)

The image is actually copied with hash to the public folder:
image

What am I doing wrong? I have tried different configurations for outdir and publicPath with no luck

@Hartha-aloufi
Copy link

I have the same issue when trying to use esbuild-replace plugin to replace some strings in the .md file! Any support please?

@deadcoder0904
Copy link

@chemicalkosek @Hartha-aloufi both use import rather than markdown image syntax like this:

---
title: First Post
---

import pic from './pic.png'

## This is a h2

This is my first post

<img src={pic} />

@konstantinmuenster
Copy link

konstantinmuenster commented May 3, 2022

I experience the same issue. Also that each refresh creates a different _mdx_bundler_entry_point seems odd?

@deadcoder0904 Tried your solution without luck, unfortunately.

EDIT: After some testing, I came to a solution that works for me:

const getCompiledMDX = async (source: string, slug: string) => {
  try {
    setEsbuildExecutable();
    return await bundleMDX({
      source,
      cwd: path.join(BLOG_DIR, slug),
      mdxOptions(options) {
        options.remarkPlugins = [
          ...(options.remarkPlugins ?? []),
          remarkMdxImages,
          remarkAutolinkHeadings,
          remarkSlug,
        ];
        return options;
      },
      esbuildOptions: options => {
        options.outdir = path.join(process.cwd(), 'public', 'images', slug);
        options.publicPath = `/images/${slug}`;
        options.write = true;
        options.loader = {
          ...options.loader,
          '.png': 'file',
          '.jpeg': 'file',
          '.jpg': 'file',
          '.JPG': 'file',
        };
        return options;
      },
    });
  } catch (error) {
    throw error;
  }
};

@chemicalkosek maybe this works for you as well 🤞 I used path.join() to build the options.outdir value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants