remix: Vite build fails, recursively creates public build directories when using assetsBuildDirectory
Reproduction
https://stackblitz.com/edit/remix-run-remix-fa3huu?file=package.json
System Info
System:
OS: Linux 5.0 undefined
CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 0 Bytes / 0 Bytes
Shell: 1.0 - /bin/jsh
Binaries:
Node: 18.18.0 - /usr/local/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 9.4.2 - /usr/local/bin/npm
pnpm: 8.9.2 - /usr/local/bin/pnpm
npmPackages:
@remix-run/css-bundle: * => 2.2.0
@remix-run/dev: * => 2.2.0
@remix-run/eslint-config: * => 2.2.0
@remix-run/node: * => 2.2.0
@remix-run/react: * => 2.2.0
@remix-run/serve: * => 2.2.0
vite: ^4.5.0 => 4.5.0
Used Package Manager
npm
Expected Behavior
When running npm run build in an app setup with vite that has assetsBuildDirectory set to public/mybase/build, it is expected that the build would succeed and produce the public build artifacts at public/mybase/build.
Actual Behavior
If the public folder does not exist at all, then the build passes and creates public/mybase/build.
However, if the public directory exists, it tries to recursively create directories:
public
- mybase
- - build
- - - mybase
- - - - build
Eventually, the build fails with the error:
error during build:
Error: ENAMETOOLONG: name too long, mkdir '/path/to/app/public/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase/build/mybase'
About this issue
- Original URL
- State: closed
- Created 8 months ago
- Comments: 17 (15 by maintainers)
I’ve opened a PR to fix this, but to confirm whether this works for you in the short term, try setting
build.copyPublicDirtofalsein your Vite config:It seems like the way Remix has worked up to this point clashes with the way Vite typically works in terms of the
publicdirectory.For now at least I think we’d want to maintain the same directory structure as the existing Remix compiler to make migration as painless as possible. To do this, we’ll probably need to disable Vite’s build.copyPublicDir option internally.
Anyone else getting this warning?
That’s on the default settings.
Thanks for the reproduction! I was also seeing some tricky behavior when customizing
assetsBuildDirectoryin my remix app (not well organized for others to see, but just for reference https://github.com/hi-ogawa/ytsub-v3/pull/519/). What I ended up was to disable vite’s automatic./publicdirectory copying behavior by passingpublicDir: falsewhenvite build. I forked your repro to test this idea and it seems okay: https://stackblitz.com/edit/remix-run-remix-qnj73f?file=vite.config.tsThis workaround might require extra script to copy some assets afterwards, but for the setup of your repro,
./publicis assumed to be the root of the app, so I think it’s fine. I confirmedfavicon.icois served for each case:Regarding this, I think this might have fundamentally different technical challenge since this will not be only about vite’s
baseoption to control where vite recognize/emits assets, but also remix/react-router has to be aware of “base” path for the entire routing/navigation logic. I’m not sure if react-router already has such feature now, or any plan to do this.Also FYI, remix plugin currently sets remix config’s
publicPathas vite’sbaseoption internally.https://github.com/remix-run/remix/blob/bfa2bbcece0ee4bfe7f501bbde935e5fcdfa20f1/packages/remix-dev/vite/plugin.ts#L513
So by default (which is
vite base = remix publicPath = /build/), the generated assets look like this:I was wondering if there is a way to achieve something similar without relying on
base(for example, only by manipulating viteoutDir?).EDIT: I forgot about current remix’s
publicPathis also intended to be used with external domain, example from https://remix.run/docs/en/main/file-conventions/remix-config#publicpathSo, the usage of
baseseems actually correct for this scenario.I tried it briefly and it appears that it’s working as intended. I didn’t test too deeply or deploy anything yet, but at the very least the build passes and there are no recursive directories being created at build time.
It would be nice to support the vite
baseoption that can be provided tovite.config.tsand respect that for the build outputs. This is something that we’ve wanted at my company since Remix launched, because we host many apps on the same origin, just different base paths.