Skip to content

Commit b2873ac

Browse files
authored
fix: empty CSS file was output when only .css?url is used (#15846)
1 parent cfdd0c0 commit b2873ac

File tree

1 file changed

+78
-80
lines changed
  • packages/vite/src/node/plugins

1 file changed

+78
-80
lines changed

packages/vite/src/node/plugins/css.ts

+78-80
Original file line numberDiff line numberDiff line change
@@ -718,92 +718,90 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
718718
}
719719
}
720720

721-
if (!chunkCSS && !s) {
722-
return null
723-
}
724-
725-
if (config.build.cssCodeSplit) {
726-
if (opts.format === 'es' || opts.format === 'cjs') {
727-
if (isPureCssChunk) {
728-
// this is a shared CSS-only chunk that is empty.
729-
pureCssChunks.add(chunk)
730-
}
721+
if (chunkCSS) {
722+
if (config.build.cssCodeSplit) {
723+
if (opts.format === 'es' || opts.format === 'cjs') {
724+
if (isPureCssChunk) {
725+
// this is a shared CSS-only chunk that is empty.
726+
pureCssChunks.add(chunk)
727+
}
731728

732-
const isEntry = chunk.isEntry && isPureCssChunk
733-
const cssFullAssetName = ensureFileExt(chunk.name, '.css')
734-
// if facadeModuleId doesn't exist or doesn't have a CSS extension,
735-
// that means a JS entry file imports a CSS file.
736-
// in this case, only use the filename for the CSS chunk name like JS chunks.
737-
const cssAssetName =
738-
chunk.isEntry &&
739-
(!chunk.facadeModuleId || !isCSSRequest(chunk.facadeModuleId))
740-
? path.basename(cssFullAssetName)
741-
: cssFullAssetName
742-
const originalFilename = getChunkOriginalFileName(
743-
chunk,
744-
config.root,
745-
opts.format,
746-
)
729+
const isEntry = chunk.isEntry && isPureCssChunk
730+
const cssFullAssetName = ensureFileExt(chunk.name, '.css')
731+
// if facadeModuleId doesn't exist or doesn't have a CSS extension,
732+
// that means a JS entry file imports a CSS file.
733+
// in this case, only use the filename for the CSS chunk name like JS chunks.
734+
const cssAssetName =
735+
chunk.isEntry &&
736+
(!chunk.facadeModuleId || !isCSSRequest(chunk.facadeModuleId))
737+
? path.basename(cssFullAssetName)
738+
: cssFullAssetName
739+
const originalFilename = getChunkOriginalFileName(
740+
chunk,
741+
config.root,
742+
opts.format,
743+
)
747744

748-
chunkCSS = resolveAssetUrlsInCss(chunkCSS, cssAssetName)
745+
chunkCSS = resolveAssetUrlsInCss(chunkCSS, cssAssetName)
749746

750-
// wait for previous tasks as well
751-
chunkCSS = await codeSplitEmitQueue.run(async () => {
752-
return finalizeCss(chunkCSS, true, config)
753-
})
747+
// wait for previous tasks as well
748+
chunkCSS = await codeSplitEmitQueue.run(async () => {
749+
return finalizeCss(chunkCSS, true, config)
750+
})
754751

755-
// emit corresponding css file
756-
const referenceId = this.emitFile({
757-
name: cssAssetName,
758-
type: 'asset',
759-
source: chunkCSS,
760-
})
761-
generatedAssets
762-
.get(config)!
763-
.set(referenceId, { originalName: originalFilename, isEntry })
764-
chunk.viteMetadata!.importedCss.add(this.getFileName(referenceId))
765-
} else if (!config.build.ssr) {
766-
// legacy build and inline css
767-
768-
// Entry chunk CSS will be collected into `chunk.viteMetadata.importedCss`
769-
// and injected later by the `'vite:build-html'` plugin into the `index.html`
770-
// so it will be duplicated. (https://github.com/vitejs/vite/issues/2062#issuecomment-782388010)
771-
// But because entry chunk can be imported by dynamic import,
772-
// we shouldn't remove the inlined CSS. (#10285)
773-
774-
chunkCSS = await finalizeCss(chunkCSS, true, config)
775-
let cssString = JSON.stringify(chunkCSS)
776-
cssString =
777-
renderAssetUrlInJS(
778-
this,
779-
config,
780-
chunk,
781-
opts,
782-
cssString,
783-
)?.toString() || cssString
784-
const style = `__vite_style__`
785-
const injectCode =
786-
`var ${style} = document.createElement('style');` +
787-
`${style}.textContent = ${cssString};` +
788-
`document.head.appendChild(${style});`
789-
let injectionPoint
790-
const wrapIdx = code.indexOf('System.register')
791-
if (wrapIdx >= 0) {
792-
const executeFnStart = code.indexOf('execute:', wrapIdx)
793-
injectionPoint = code.indexOf('{', executeFnStart) + 1
794-
} else {
795-
const insertMark = "'use strict';"
796-
injectionPoint = code.indexOf(insertMark) + insertMark.length
752+
// emit corresponding css file
753+
const referenceId = this.emitFile({
754+
name: cssAssetName,
755+
type: 'asset',
756+
source: chunkCSS,
757+
})
758+
generatedAssets
759+
.get(config)!
760+
.set(referenceId, { originalName: originalFilename, isEntry })
761+
chunk.viteMetadata!.importedCss.add(this.getFileName(referenceId))
762+
} else if (!config.build.ssr) {
763+
// legacy build and inline css
764+
765+
// Entry chunk CSS will be collected into `chunk.viteMetadata.importedCss`
766+
// and injected later by the `'vite:build-html'` plugin into the `index.html`
767+
// so it will be duplicated. (https://github.com/vitejs/vite/issues/2062#issuecomment-782388010)
768+
// But because entry chunk can be imported by dynamic import,
769+
// we shouldn't remove the inlined CSS. (#10285)
770+
771+
chunkCSS = await finalizeCss(chunkCSS, true, config)
772+
let cssString = JSON.stringify(chunkCSS)
773+
cssString =
774+
renderAssetUrlInJS(
775+
this,
776+
config,
777+
chunk,
778+
opts,
779+
cssString,
780+
)?.toString() || cssString
781+
const style = `__vite_style__`
782+
const injectCode =
783+
`var ${style} = document.createElement('style');` +
784+
`${style}.textContent = ${cssString};` +
785+
`document.head.appendChild(${style});`
786+
let injectionPoint
787+
const wrapIdx = code.indexOf('System.register')
788+
if (wrapIdx >= 0) {
789+
const executeFnStart = code.indexOf('execute:', wrapIdx)
790+
injectionPoint = code.indexOf('{', executeFnStart) + 1
791+
} else {
792+
const insertMark = "'use strict';"
793+
injectionPoint = code.indexOf(insertMark) + insertMark.length
794+
}
795+
s ||= new MagicString(code)
796+
s.appendRight(injectionPoint, injectCode)
797797
}
798-
s ||= new MagicString(code)
799-
s.appendRight(injectionPoint, injectCode)
800-
}
801-
} else {
802-
// resolve public URL from CSS paths, we need to use absolute paths
803-
chunkCSS = resolveAssetUrlsInCss(chunkCSS, cssBundleName)
804-
// finalizeCss is called for the aggregated chunk in generateBundle
798+
} else {
799+
// resolve public URL from CSS paths, we need to use absolute paths
800+
chunkCSS = resolveAssetUrlsInCss(chunkCSS, cssBundleName)
801+
// finalizeCss is called for the aggregated chunk in generateBundle
805802

806-
chunkCSSMap.set(chunk.fileName, chunkCSS)
803+
chunkCSSMap.set(chunk.fileName, chunkCSS)
804+
}
807805
}
808806

809807
if (s) {

0 commit comments

Comments
 (0)