vite
vite copied to clipboard
Vite4 build does not respect the assets path
Describe the bug
Vite4 does not generate the same path for associated assets when building than Vite3.
I'm working with a Vite+Django integration. When building assets, it's important to keep the same path to allow Django found related files. With vite3 when building the file "/my-code/index.js" an asset was build at "/my-code/index.css". Now with vite4, the assets for file "/my-code/index.js" it's build at "/index.css". I've tried to get the right info with the "assetFileNames" functions to no avail. I've used the "build.rollupOptions.input" and the "build.lib.entry" configurations, but nothing changes. There is a link with a repo with a setup to see the difference with both versions.
Reproduction
https://github.com/jorrete/vite-styles-build.git
Steps to reproduce
npm install && npm run build
System Info
System:
OS: Linux 6.0 Fedora Linux 37 (Workstation Edition)
CPU: (12) x64 AMD Ryzen 5 PRO 4650U with Radeon Graphics
Memory: 13.25 GB / 22.70 GB
Container: Yes
Shell: 5.2.9 - /bin/bash
Binaries:
Node: 18.12.1 - /usr/bin/node
npm: 8.19.2 - /usr/bin/npm
Browsers:
Chrome: 108.0.5359.124
Firefox: 108.0
Used Package Manager
npm
Logs
No response
Validations
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guidelines.
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [X] Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to vuejs/core instead.
- [X] Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- [X] The provided reproduction is a minimal reproducible example of the bug.
I have the same issue since I have started using vite4.
try
"rollupOptions": {
"output": {
"assetFileNames": "my-folder/[name][extname]"
},
}
From what I understand, there's something wrong with vite4: According to the documentation:
Note that it is possible when using the object form to put entry points into different sub-folders by adding a / to the name. The following will generate at least two entry chunks with the names entry-a.js and entry-b/index.js, i.e. the file index.js is placed in the folder entry-b:
try
"rollupOptions": { "output": { "assetFileNames": "my-folder/[name][extname]" }, }
Yes, that works, but it is not exactly the "problem" I want to point. In Vite3 the base name ([name]) had already his path embed, where in Vite4 [name] is the basename only. My use case is to gather files from a folder and pass it with the "input" object. The keys of the object are the relative paths and I expect that the assets also are placed at the same folder of the "entryFileNames".
I have the same issue.
assetFileNames: (assetInfo: any) => {
const base = dirname(assetInfo.name)
return `${base}/[name].[hash].[ext]`
},
I used this to have /app/css/style.css in /app/dist/css/style.css
This no longer works. You cannot have './[name].[hash].[ext]' as value either in 4.0.0. It doesn't allow having a relative path which starts with ./
I've run into this same issue. Nested paths to assets in my source are getting flattened during build in the output directory.
This is pretty frustrating since it worked before.
Same issue, can't keep assets path tree after build. Everithing goes into one big heap. It was broken in v4.0.0-alpha.2
This commit? https://github.com/vitejs/vite/commit/78c77beb5bf6112588581c0cbb47bc4d3bfed681
@patak-dev
@kuoruan I think so, because in v4.0.0-alpha.1 it is ok.
Has anyone found a workaround?
How to get all original paths of all assets?
Example:
entry point - main.js
import './style.css'
style.css
.block { background-image: url(/images/javascript.svg); }
I can't get this asset in any hook
I'm facing the same issue. I'm trying to have a library build setup to have separated React components with their own CSS next to them. So I can load the component alongside its CSS in a separate project with some sort of loader. But the result is always the same.
├── dist
├── Foo
│ └── index.js
├── Bar
│ └── index.js
└── index.css
So I end up creating a script to wrap around the build function.
import { build } from "vite";
import { resolve } from "path";
const dirs = ["Foo", "Bar"];
dirs.forEach(async (dir) => {
await build({
build: {
lib: {
entry: resolve("src", dir),
name: dir,
formats: ["es"],
fileName: `${dir}/index`,
},
rollupOptions: {
external: ["react", "react/jsx-runtime"],
output: {
assetFileNames: `${dir}/[name][extname]`,
},
},
},
});
});
So the result looks like
├── dist
├── Foo
│ ├── index.css
│ └── index.js
└── Bar
├── index.css
└── index.js
But there is a problem with this setup. If there is shared code, it won’t be an extra chunk next to the build result but included in every index.js
which imports it.
It could be nice to have a new token for entry
different from the name
token to be used in a assetFileNames
config under lib. And also respect the build.cssCodeSplit
. Something like this.
{
build: {
cssCodeSplit: true,
lib: {
entry: {
Foo: resolve("src", "Foo"),
Bar: resolve("src", "Bar"),
},
formats: ["es"],
fileName: `[entry]/index`,
assetFileNames: `[entry]/[name][extname]`,
},
rollupOptions: {
external: ["react", "react/jsx-runtime"],
},
},
}
Duplicate of #12072
me too I want to make the image path of the code and the path of the build file the same ex) code src ---- assets -------- comoponentA ---------------- ***.png -------- componentB ---------------- ***.png
after build _dist ---- img -------- comoponentA ---------------- ***.png -------- componentB ---------------- ***.png
like this
but vite 4.0 not working any more it's work in only vite 3.x.x because vite 4.0 does not respect the assets path
assetFileNames(assetInfo) {
const dirMaintain = (assetName: string) => {
const assetIndex = assetName.indexOf("assets");
const dirArray = assetName.substring(assetIndex).split("/");
return dirArray.splice(1, dirArray.length - 2).join("/");
};
let extType = assetInfo.name.split(".").at(1);
const base = dirname(assetInfo.name);
if (/\.css$/.test(base)) {
extType = "css";
} else if (/\.png|\.webp|\.svg$/.test(base)) {
extType = dirMaintain(base);
}
return `${extType}/[name][extname]`;
},
anyone solve this provlem??