Skip to content

Commit

Permalink
fix(css): ensure code is valid after empty css chunk imports are remo…
Browse files Browse the repository at this point in the history
…ved (fix #14515) (#14517)
  • Loading branch information
susnux authored Oct 27, 2023
1 parent cf80e40 commit 72f6a52
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 6 deletions.
31 changes: 28 additions & 3 deletions packages/vite/src/node/__tests__/plugins/css.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@ import "other-module";`
expect(replaced.length).toBe(code.length)
expect(replaced).toMatchInlineSnapshot(`
"import \\"some-module\\";
/* empty css */import \\"other-module\\";"
/* empty css */
import \\"other-module\\";"
`)
})

Expand All @@ -298,7 +299,8 @@ require("other-module");`
expect(replaced.length).toBe(code.length)
expect(replaced).toMatchInlineSnapshot(`
"require(\\"some-module\\");
/* empty css */require(\\"other-module\\");"
;/* empty css */
require(\\"other-module\\");"
`)
})

Expand All @@ -309,7 +311,30 @@ require("other-module");`
const replaced = replacer(code)
expect(replaced.length).toBe(code.length)
expect(replaced).toMatchInlineSnapshot(
'"require(\\"some-module\\");/* empty css */require(\\"other-module\\");"',
'"require(\\"some-module\\");;/* empty css */require(\\"other-module\\");"',
)
})

test('replaces require call in minified code that uses comma operator', () => {
const code =
'require("some-module"),require("pure_css_chunk.js"),require("other-module");'

const replacer = getEmptyChunkReplacer(['pure_css_chunk.js'], 'cjs')
const newCode = replacer(code)
expect(newCode).toMatchInlineSnapshot(
'"require(\\"some-module\\"),/* empty css */require(\\"other-module\\");"',
)
// So there should be no pure css chunk anymore
expect(newCode.match(/pure_css_chunk\.js/)).toBeNull()
})

test('replaces require call in minified code that uses comma operator followed by assignment', () => {
const code =
'require("some-module"),require("pure_css_chunk.js");const v=require("other-module");'

const replacer = getEmptyChunkReplacer(['pure_css_chunk.js'], 'cjs')
expect(replacer(code)).toMatchInlineSnapshot(
'"require(\\"some-module\\");/* empty css */const v=require(\\"other-module\\");"',
)
})
})
12 changes: 9 additions & 3 deletions packages/vite/src/node/plugins/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -828,18 +828,24 @@ export function getEmptyChunkReplacer(
.join('|')
.replace(/\./g, '\\.')

// for cjs, require calls might be chained by minifier using the comma operator.
// in this case we have to keep one comma if a next require is chained
// or add a semicolon to terminate the chain.
const emptyChunkRE = new RegExp(
outputFormat === 'es'
? `\\bimport\\s*["'][^"']*(?:${emptyChunkFiles})["'];\n?`
: `\\brequire\\(\\s*["'][^"']*(?:${emptyChunkFiles})["']\\);\n?`,
? `\\bimport\\s*["'][^"']*(?:${emptyChunkFiles})["'];`
: `(\\b|,\\s*)require\\(\\s*["'][^"']*(?:${emptyChunkFiles})["']\\)(;|,)`,
'g',
)

return (code: string) =>
code.replace(
emptyChunkRE,
// remove css import while preserving source map location
(m) => `/* empty css ${''.padEnd(m.length - 15)}*/`,
(m) =>
outputFormat === 'es'
? `/* empty css ${''.padEnd(m.length - 15)}*/`
: `${m.at(-1)}/* empty css ${''.padEnd(m.length - 16)}*/`,
)
}

Expand Down

0 comments on commit 72f6a52

Please sign in to comment.