honojs / honox

HonoX - Hono based meta framework
https://hono.dev
MIT License
1.65k stars 43 forks source link

Importing image assets missing in prod build #100

Closed emmanuelchucks closed 8 months ago

emmanuelchucks commented 8 months ago

What version of HonoX are you using?

0.1.4

What steps can reproduce the bug?

Here's a minimal reproduction

What is the expected behavior?

Imported image should be available in prod build and visible on the index page

What do you see instead?

Imported image only works in dev but returns 404 in prod

Additional information

I suspect I'm doing something wrong but can't figure it out yet. Any help pointing me in the right direction will be appreciated

yusukebe commented 8 months ago

Hi @emmanuelchucks

This is not a bug, not a HonoX matter. I think "vite-imagetools" does not support SSR, but actually, I don't know.

emmanuelchucks commented 8 months ago

Thanks for the swift reply @yusukebe

I have removed the vite-imagetools dep in the repro linked to prove the issue still persists with/without it. The image displays in dev but throws 404 in prod.

My best guess is it has to do with vite bundling config but I can't tell what to change.

Luzefiru commented 8 months ago

Hi @emmanuelchucks

This is not a bug, not a HonoX matter. I think "vite-imagetools" does not support SSR, but actually, I don't know.

Can confirm this. It seems that the images are bundled properly and copied to the build directory (/dist in HonoX's case) when importing them in the /app/islands folder.

Otherwise, Vite does not bundle images outside the islands folder unless it's a small image that satisfies the build.assetsInlineLimit in your vite.config.ts.

My Solution

This was what I changed in my vite.config.ts to make it work:

export default defineConfig(({ mode }) => {
  if (mode === 'client') {
    return {
      plugins: [client()],
    };
  } else {
    return {
      build: {
        assetsDir: 'static', // make all non-island asset imports map to the /dist/static directory when emitted
        ssrEmitAssets: true, // emit all the assets required during the SSR build
      },
      plugins: [honox(), pages()],
    };
  }
});

I believe this is because the vite-cloudflare-pages plugin only serves the Wrangler CLI directory argument's /static directory, as shown in this line of code, hence why we need to map our assets to the /dist/static directory.

Possible Enhancement

Make this a default behavior via the honox() or the pages() Vite plugin so that image imports via non-island (SSR) code may also work. I have a fork which adds this behavior to the vite-cloudflare-pages plugin with the option to change the SSR build asset directory when non-islands imports are made via pages({ assetsDir: 'somethingElse' }).

export default defineConfig(({ mode }) => {
  if (mode === 'client') {
    return {
      plugins: [client()],
    };
  } else {
    return {
      plugins: [honox(), pages({assetsDir: "somethingElse"})],
    };
  }
});

image

emmanuelchucks commented 8 months ago

My Solution

This was what I changed in my vite.config.ts to make it work:

export default defineConfig(({ mode }) => {
  if (mode === 'client') {
    return {
      plugins: [client()],
    };
  } else {
    return {
      build: {
        assetsDir: 'static', // make all non-island asset imports map to the /dist/static directory when emitted
        ssrEmitAssets: true, // emit all the assets required during the SSR build
      },
      plugins: [honox(), pages()],
    };
  }
});

OMG yes this fixed my issue. I did suspect it had something to do with vite. Thank you so much.

I also agree this should be the default.