Skip to content

Commit

Permalink
fix(css): hoist external @import for non-split css (#8022)
Browse files Browse the repository at this point in the history
  • Loading branch information
sapphi-red committed May 6, 2022
1 parent 63cd53d commit 5280908
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 13 deletions.
7 changes: 7 additions & 0 deletions packages/playground/lib/__tests__/lib.spec.ts
Expand Up @@ -35,6 +35,13 @@ if (isBuild) {
)
expect(code).not.toMatch('__vitePreload')
})

test('@import hoist', async () => {
serverLogs.forEach((log) => {
// no warning from esbuild css minifier
expect(log).not.toMatch('All "@import" rules must come first')
})
})
} else {
test('dev', async () => {
expect(await page.textContent('.demo')).toBe('It works')
Expand Down
14 changes: 13 additions & 1 deletion packages/playground/lib/__tests__/serve.js
Expand Up @@ -9,13 +9,17 @@ const { ports } = require('../../testUtils')

const port = (exports.port = ports.lib)

global.serverLogs = []

/**
* @param {string} root
* @param {boolean} isBuildTest
*/
exports.serve = async function serve(root, isBuildTest) {
// build first

setupConsoleWarnCollector()

if (!isBuildTest) {
const { createServer } = require('vite')
process.env.VITE_INLINE = 'inline-serve'
Expand Down Expand Up @@ -55,7 +59,7 @@ exports.serve = async function serve(root, isBuildTest) {

await build({
root,
logLevel: 'silent',
logLevel: 'warn', // output esbuild warns
configFile: path.resolve(__dirname, '../vite.dyimport.config.js')
})

Expand Down Expand Up @@ -89,3 +93,11 @@ exports.serve = async function serve(root, isBuildTest) {
})
}
}

function setupConsoleWarnCollector() {
const warn = console.warn
console.warn = (...args) => {
global.serverLogs.push(args.join(' '))
return warn.call(console, ...args)
}
}
4 changes: 4 additions & 0 deletions packages/playground/lib/src/dynamic.css
@@ -0,0 +1,4 @@
@import 'https://cdn.jsdelivr.net/npm/@mdi/font@5.9.55/css/materialdesignicons.min.css';
.dynamic {
color: red;
}
3 changes: 3 additions & 0 deletions packages/playground/lib/src/index.css
@@ -0,0 +1,3 @@
.index {
color: blue;
}
5 changes: 5 additions & 0 deletions packages/playground/lib/src/main2.js
@@ -1,4 +1,9 @@
import './index.css'

export default async function message(sel) {
const message = await import('./message.js')

await import('./dynamic.css')

document.querySelector(sel).textContent = message.default
}
1 change: 0 additions & 1 deletion packages/playground/lib/vite.dyimport.config.js
Expand Up @@ -6,7 +6,6 @@ const path = require('path')
*/
module.exports = {
build: {
minify: false,
lib: {
entry: path.resolve(__dirname, 'src/main2.js'),
formats: ['es'],
Expand Down
28 changes: 17 additions & 11 deletions packages/vite/src/node/plugins/css.ts
Expand Up @@ -443,13 +443,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
}
})
// only external @imports and @charset should exist at this point
// hoist them to the top of the CSS chunk per spec (#1845 and #6333)
if (css.includes('@import') || css.includes('@charset')) {
css = await hoistAtRules(css)
}
if (minify && config.build.minify) {
css = await minifyCSS(css, config)
}
css = await finalizeCss(css, minify, config)
return css
}

Expand Down Expand Up @@ -559,10 +553,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
let extractedCss = outputToExtractedCSSMap.get(opts)
if (extractedCss && !hasEmitted) {
hasEmitted = true
// minify css
if (config.build.minify) {
extractedCss = await minifyCSS(extractedCss, config)
}
extractedCss = await finalizeCss(extractedCss, true, config)
this.emitFile({
name: 'style.css',
type: 'asset',
Expand Down Expand Up @@ -922,6 +913,21 @@ function combineSourcemapsIfExists(
: map1
}

async function finalizeCss(
css: string,
minify: boolean,
config: ResolvedConfig
) {
// hoist external @imports and @charset to the top of the CSS chunk per spec (#1845 and #6333)
if (css.includes('@import') || css.includes('@charset')) {
css = await hoistAtRules(css)
}
if (minify && config.build.minify) {
css = await minifyCSS(css, config)
}
return css
}

interface PostCSSConfigResult {
options: PostCSS.ProcessOptions
plugins: PostCSS.Plugin[]
Expand Down

0 comments on commit 5280908

Please sign in to comment.