Skip to content
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

fix(css): cachedPostcssConfig reused for multiple builds #3906

Merged
merged 4 commits into from
Jul 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/playground/css/postcss-caching/blue-app/imported.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.postcss-a {
color: pink;
}
12 changes: 12 additions & 0 deletions packages/playground/css/postcss-caching/blue-app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div class="wrapper">
<h1>CSS</h1>

<p>Imported css string:</p>
<pre class="imported-css"></pre>

<p class="postcss-a">This should be blue</p>

<p class="postcss-b">This should be black</p>
</div>

<script type="module" src="./main.js"></script>
6 changes: 6 additions & 0 deletions packages/playground/css/postcss-caching/blue-app/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import css from './imported.css'
text('.imported-css', css)

function text(el, text) {
document.querySelector(el).textContent = text
}
11 changes: 11 additions & 0 deletions packages/playground/css/postcss-caching/blue-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "blue-app",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"debug": "node --inspect-brk ../../vite/bin/vite",
"serve": "vite preview"
}
}
15 changes: 15 additions & 0 deletions packages/playground/css/postcss-caching/blue-app/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
plugins: [replacePinkWithBlue]
}

function replacePinkWithBlue() {
return {
postcssPlugin: 'replace-pink-with-blue',
Declaration(decl) {
if (decl.value === 'pink') {
decl.value = 'blue'
}
}
}
}
replacePinkWithBlue.postcss = true
29 changes: 29 additions & 0 deletions packages/playground/css/postcss-caching/css.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { getColor } from '../../testUtils'
import { createServer } from 'vite'
import path from 'path'

test('postcss config', async () => {
const port = 5005
const blueAppDir = path.join(__dirname, 'blue-app')
const greenAppDir = path.join(__dirname, 'green-app')

process.chdir(blueAppDir)
const blueApp = await createServer()
await blueApp.listen(port)
await page.goto(`http://localhost:${port}`)
const blueA = await page.$('.postcss-a')
expect(await getColor(blueA)).toBe('blue')
const blueB = await page.$('.postcss-b')
expect(await getColor(blueB)).toBe('black')
await blueApp.close()

process.chdir(greenAppDir)
const greenApp = await createServer()
await greenApp.listen(port)
await page.goto(`http://localhost:${port}`)
const greenA = await page.$('.postcss-a')
expect(await getColor(greenA)).toBe('black')
const greenB = await page.$('.postcss-b')
expect(await getColor(greenB)).toBe('green')
await greenApp.close()
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.postcss-b {
color: pink;
}
12 changes: 12 additions & 0 deletions packages/playground/css/postcss-caching/green-app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div class="wrapper">
<h1>CSS</h1>

<p>Imported css string:</p>
<pre class="imported-css"></pre>

<p class="postcss-a">This should be black</p>

<p class="postcss-b">This should be green</p>
</div>

<script type="module" src="./main.js"></script>
6 changes: 6 additions & 0 deletions packages/playground/css/postcss-caching/green-app/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import css from './imported.css'
text('.imported-css', css)

function text(el, text) {
document.querySelector(el).textContent = text
}
11 changes: 11 additions & 0 deletions packages/playground/css/postcss-caching/green-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "green-app",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"debug": "node --inspect-brk ../../vite/bin/vite",
"serve": "vite preview"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
plugins: [replacePinkWithGreen]
}

function replacePinkWithGreen() {
return {
postcssPlugin: 'replace-pink-with-green',
Declaration(decl) {
if (decl.value === 'pink') {
decl.value = 'green'
}
}
}
}
replacePinkWithGreen.postcss = true
46 changes: 27 additions & 19 deletions packages/vite/src/node/plugins/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ export const chunkToEmittedCssFileMap = new WeakMap<
Set<string>
>()

const postcssConfigCache = new WeakMap<
ResolvedConfig,
PostCSSConfigResult | null
>()

/**
* Plugin applied before user plugins
*/
Expand Down Expand Up @@ -720,37 +725,40 @@ interface PostCSSConfigResult {
plugins: Postcss.Plugin[]
}

let cachedPostcssConfig: PostCSSConfigResult | null | undefined

async function resolvePostcssConfig(
config: ResolvedConfig
): Promise<PostCSSConfigResult | null> {
if (cachedPostcssConfig !== undefined) {
return cachedPostcssConfig
let result = postcssConfigCache.get(config)
if (result !== undefined) {
return result
}

// inline postcss config via vite config
const inlineOptions = config.css?.postcss
if (isObject(inlineOptions)) {
const result = {
options: { ...inlineOptions },
const options = { ...inlineOptions }

delete options.plugins
result = {
options,
plugins: inlineOptions.plugins || []
}
delete result.options.plugins
return (cachedPostcssConfig = result)
}

try {
const searchPath =
typeof inlineOptions === 'string' ? inlineOptions : config.root
// @ts-ignore
return (cachedPostcssConfig = await postcssrc({}, searchPath))
} catch (e) {
if (!/No PostCSS Config found/.test(e.message)) {
throw e
} else {
try {
const searchPath =
typeof inlineOptions === 'string' ? inlineOptions : config.root
// @ts-ignore
result = await postcssrc({}, searchPath)
} catch (e) {
if (!/No PostCSS Config found/.test(e.message)) {
throw e
}
result = null
}
return (cachedPostcssConfig = null)
}

postcssConfigCache.set(config, result)
return result
}

type CssUrlReplacer = (
Expand Down