-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
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
Allow to specify filename of emitted CSS when build.cssCodeSplit: false
#4863
Comments
style.css
Finally found this issue after several attempts to configure the CSS filename. Thought this would work... css: { postcss: { to: "custom.css" } }, ...but nope. |
Me as a vite's newbie. Following config works but not elegant export default defineConfig({
build: {
rollupOptions: {
output: {
assetFileNames: (assetInfo) => {
if (assetInfo.name === 'style.css') return 'custom.css';
return assetInfo.name;
},
},
},
},
}); |
rollupOptions: {
output: [
assetFileNames: (assetInfo) => {
const { source } = assetInfo
return `[name][hash][extname]`
}
]
} You can try these two methods
|
neither solutions work for me at the moment. it's as if the css file is never seen by |
This comment was marked as spam.
This comment was marked as spam.
long story short - config.build.lib.rollupOptions.output.assetFileNames = (assetInfo) => { ... }
+ config.build .rollupOptions.output.assetFileNames = (assetInfo) => { ... } so this works |
How can we use the entry name to construct two files with the name export default {
build : {
rollupOptions : {
input : {
L : 'login/index.less',
X : 'X/index.less'
}
}
}
}; Inside the |
Having the same issue with library-mode of multi-entry. each entry has css (LESS actually) inclusion along the "import" lane. tried using "config.build.rollupOptions.output.assetFileNames" but assetInfo is always: |
build.cssCodeSplit: false
I'm quite amazed at the amount of bullshit code i had to write to make this possible, when old solutions like grunt where just 1 line. I'm leaving it here in case someone else still needs it: import { defineConfig } from "vite";
const inputs = {
"css/built.css": "./htdocs/css/src/main.scss",
"unlogged/css/main.css": "./htdocs/unlogged/css/main.scss",
"js/built": "./htdocs/js/index.js",
};
let i = 0;
export default defineConfig({
build: {
emptyOutDir: false,
outDir: "htdocs/",
sourcemap: true,
cssCodeSplit: true,
rollupOptions: {
input: inputs,
output: {
assetFileNames: (file) => {
// those are input file names, we don't care about them
if (Object.values(inputs).includes(file.name) || Object.values(inputs).includes("./" + file.name)) {
return `[name].[ext]`;
}
const endPath = Object.keys(inputs)[i];
i++;
return endPath;
},
entryFileNames: `[name].js`, // otherwise it will add the hash
chunkFileNames: `[name].js`, // otherwise it will add the hash
},
},
},
}); |
This worked for me: export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, "src/main.js"),
name: "libraryName",
fileName: "libraryName",
},
rollupOptions: {
output: {
assetFileNames: "libraryName.[ext]",
},
},
},
}); |
Here is one potentially dangerous way to solve for multiple entrypoint apps (instead of auto-incrementing index.css files. Ex: index1.css, index2.css) it if you're into potentially dangerous solves. If you have a better way to do this (and there has to be one, right?) please share it. You can see it working as intended here. import { resolve } from "path"
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react-swc"
const inputNames = ["door_one", "door_two", "door_three"]
export const mapCSSFileNames = {
name: 'mapCSSFileNames',
generateBundle(opts, bundle) {
const cssNamesMap = {}
// This is dumb... why do I have to do this... oh golly im so clueless..
Object.entries(bundle).forEach(([fileName, fileInfo]) => {
if (inputNames.includes(fileInfo.name)) {
const ambiguous_css_name = [...fileInfo.viteMetadata.importedCss][0]
const mapped_css_name = `${fileInfo.name}.css`
bundle[ambiguous_css_name].fileName = mapped_css_name
bundle[ambiguous_css_name].name = mapped_css_name
cssNamesMap[ambiguous_css_name] = mapped_css_name
}
})
},
writeBundle(opts, bundle) {
const cssNamesMap = {}
Object.keys(bundle).forEach((key) => {
const file = bundle[key]
if(file.fileName.endsWith(".css")) {
cssNamesMap[key] = file.fileName
}
})
Object.entries(bundle).forEach(([fileName, fileInfo]) => {
const cssFileNames = Object.keys(cssNamesMap)
if(fileName.endsWith(".html")) {
cssFileNames.forEach((cssFileName) => {
if(fileInfo.source.includes(cssFileName)) {
console.log(`Pattern: ${cssFileName} found in ${fileName} replacing it with: ${cssNamesMap[cssFileName]}`);
fileInfo.source = fileInfo.source.replace(cssFileName, cssNamesMap[cssFileName])
}
})
}
})
},
}
export default defineConfig(({ mode }) => {
const config = {
root: "src",
build: {
outDir: "../static/",
emptyOutDir: true,
rollupOptions: {
maxParallelFileOps: 100,
input: {
door_one: resolve(__dirname, "src", "DoorOne", "index.html"),
door_two: resolve(__dirname, "src", "DoorTwo", "index.html"),
door_three: resolve(__dirname, "src", "DoorThree", "index.html"),
},
output: {
entryFileNames: "[name].js",
},
},
commonjsOptions: { include: [] },
},
plugins: [
react({
include: [/\.jsx?$/, /\.js$/],
}),
mapCSSFileNames,
],
resolve: {
alias: {
"~": resolve(__dirname, "src/"),
},
},
optimizeDeps: {
disabled: false,
},
}
return config
}) |
We've discussed this in the last meeting. We think deriving the CSS file name from For now, you can use the workaround in #4863 (comment). Maybe we can have a |
In Vite 5, the build step now prints the CSS filename for each JS format: $ vite build
vite v5.0.0 building for production...
✓ 3 modules transformed.
dist/libraryName.css 17.22 kB │ gzip: 6.70 kB
dist/libraryName.js 4.22 kB │ gzip: 1.29 kB
dist/libraryName.css 17.22 kB │ gzip: 6.70 kB
dist/libraryName.umd.js 3.48 kB │ gzip: 1.33 kB
dist/libraryName.css 17.22 kB │ gzip: 6.70 kB
dist/libraryName.iife.js 3.31 kB │ gzip: 1.24 kB
✓ built in 220ms I hope it doesn't mean that the same file is being build three times... 😅 (edit: it does 😕) |
@kytta Would you create a new issue with reproduction? |
Will do later today 👌 |
Doesn't work for me anymore in Vite |
if someone is not injecting an index.css file, and use the default name generated by the styleX plugin, here a plugin i created for my case to rename the file. import { rename, readdirSync } from "fs";
const renameCss = ({
folder,
filename,
}: {
folder: string;
filename: string;
}) => ({
name: "vite-plugin-rename-css",
writeBundle() {
const files = readdirSync(folder);
const file = files[0];
rename(`${folder}/${file}`, `${folder}/${filename}`, () => {
console.log("renamed css!");
});
},
}); then use it as a normal plugin after the styleX() plugin call passing the build folder the css it's in and the new filename you want. plugins: [
react(),
styleX(),
renameCss({
folder: "./lib/assets",
filename: "style.css",
}),
dts(),
] Of course you can extend it or change it as you wish, was just a quick one for my case, hope it helps! |
Tried it with Vite 5.2.9 and it worked fine. |
This comment was marked as duplicate.
This comment was marked as duplicate.
这个问题, 将我这边终结,不可不说 vite 这个构建配置是恶心到我了。 好了 请看我的解决方案
2 使用这个插件
3 开启 cssCodeSplit, 为什么要开启呢?看注释
4 重要 禁用掉已有的 build.rollupOptions.output.assetFileNames 设置
|
what a heavy thread |
Clear and concise description of the problem
When building in library mode for a
.js
file that imports styles, Vite generates astyle.css
file in the target directory alongside the.js
file.Using build.lib.fileName we can already specify the filename for the
.js
file. Currently there seems to be no way to specify the filename for the.css
file, as it always defaults tostyle.css
.Suggested solution
Maybe a
build.lib.fileNameCSS
option?Alternative
A workaround is renaming the
style.css
in apostbuild
script. But this isn't ideal since it involves yet another build step, and doing it in Vite itself would be more coherent.Additional context
No response
Validations
The text was updated successfully, but these errors were encountered: