arnoson / kirby-vite

Use Kirby CMS together with Vite
MIT License
81 stars 7 forks source link

Vite `base` option not supported in dev mode #37

Closed fvsch closed 12 months ago

fvsch commented 12 months ago

Using vite-plugin-kirby@5.0.1 and arnoson/kirby-vite@5.0.1.

I have a vite.config.js that uses Vite's base option:

import kirby from 'vite-plugin-kirby';

export default {
  plugins: [kirby()],
  // Needed so that generated assets have URLs starting with `/dist/` and not `/` in prod
  base: '/dist/',
  build: {
    copyPublicDir: false,
    emptyOutDir: true,
    outDir: 'public/dist',
    assetsDir: '',
    rollupOptions: {
      input: ['src/common.js', 'src/home.js'],
    },
  },
};

The generated site/config/vite.config.php looks like:

<?php
// This is an auto-generated file. Please avoid making changes here.
// Configure your settings in the "vite.config.js" file instead.
return [
  'outDir' => 'public/dist',
  'assetsDir' => '',
  'legacy' => false
];

With a production build, everything works well. I can use vite()->js('src/common.js') and it outputs a URL like /dist/common-{hash}.js.

In development, things break. The generated HTML looks like:

<script src="http://localhost:5173/@vite/client" type="module"></script>
<script src="http://localhost:5173/src/common.js" type="module"></script>

When visiting http://localhost:5173/src/common.js, Vite is showing an error:

The server is configured with a public base URL of /dist/ - did you mean to visit /dist/src/common.js instead?

Quick investigation

That's probably because the base value is not used anywhere in site/config/vite.config.php or in the .dev file, which reads:

VITE_SERVER=http://localhost:5173

And the implementation of the arnoson\KirbyVite\Vite::assetDev method basically returns "$VITE_SERVER/$file" where $file is the first param passed to vite()->js(…).

Possible workarounds

  1. You can set Vite's server.origin to something like http://localhost:5173/dist, but then it breaks URLs from CSS to assets referenced in the CSS (ends up linking to http://localhost:5173/dist/dist/some-image.jpg). So that's a hack more than a fix.
  2. You can set the base to different values for development and production:
// vite.config.js
import kirby from 'vite-plugin-kirby';

export default function({ mode }) {
  return {
    plugins: [kirby()],
    // Needed so that generated assets have URLs starting with `/dist/` and not `/` in prod
    base: mode === 'production' ? '/dist/' : '/',
    build: {
      copyPublicDir: false,
      emptyOutDir: true,
      outDir: 'public/dist',
      assetsDir: '',
      rollupOptions: {
        input: ['src/common.js', 'src/home.js'],
      },
    },
  };
}

The second one seems to be working pretty well. It compensates well for kirby-vite hardcoding / as the URL base in dev mode.

fvsch commented 12 months ago

I just noticed that the example/vite.config.js file uses

base: mode === 'development' ? '/' : '/dist/',

I’m wondering if that's a good pattern to use in this project's README.md as well?

Is there a project setup where not setting the base for production just works?

Maybe if the outDir is the public root (project root dir in the default Kirby setup, or the ./public dir in most custom setups), and Vite assets are written to ./assets/* or ./public/assets/*, then you don't need to set a base because Vite's manifest will contain a path like "assets/foo-{hash}.js" and you can link to /assets/foo-{hash}.js and it'll just work.

fvsch commented 12 months ago

(By the way, thanks a bunch for this plugin! Much appreciated.)

arnoson commented 12 months ago

Thanks for mentioning this! Indeed I use a a different base for development and production in all examples and the starter kit, but i forgot to add this in the readme, will add this soon :)

I guess this setting could also be set by the vite plugin, but I prefer to keep as much config standard vite as possible.

arnoson commented 12 months ago

@fvsch, maybe I closed this a bit too soon, do you think the updated readme solves your issue?

fvsch commented 11 months ago

@arnoson I think so, yes.

The docs update is a good solution. This could be handled in code instead (by passing the configured base into .dev or config/config/vite.config.php), but there would be complexity and edge cases there, so I doubt it's worth it, at least currently.