Skip to content

Commit

Permalink
vite-third-party-plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
philipp-spiess committed Nov 5, 2024
1 parent ca4e4ae commit 1cc0022
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 41 deletions.
153 changes: 153 additions & 0 deletions integrations/vite/other-transforms.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { describe, expect } from 'vitest'
import { css, fetchStyles, html, retryAssertion, test, ts, txt } from '../utils'

function createSetup(transformer: 'postcss' | 'lightningcss') {
return {
fs: {
'package.json': txt`
{
"type": "module",
"dependencies": {
"@tailwindcss/vite": "workspace:^",
"tailwindcss": "workspace:^"
},
"devDependencies": {
${transformer === 'lightningcss' ? `"lightningcss": "^1.26.0",` : ''}
"vite": "^5.3.5"
}
}
`,
'vite.config.ts': ts`
import tailwindcss from '@tailwindcss/vite'
import { defineConfig } from 'vite'
export default defineConfig({
css: ${transformer === 'postcss' ? '{}' : "{ transformer: 'lightningcss' }"},
build: { cssMinify: false },
plugins: [
tailwindcss(),
{
name: 'recolor',
transform(code, id) {
if (id.includes('.css')) {
return code.replace(/red/g, 'blue')
}
},
},
],
})
`,
'index.html': html`
<head>
<link rel="stylesheet" href="./src/index.css" />
</head>
<body>
<div class="foo">Hello, world!</div>
</body>
`,
'src/index.css': css`
@import 'tailwindcss/theme' theme(reference);
@import 'tailwindcss/utilities';
.foo {
color: red;
}
`,
},
}
}

for (let transformer of ['postcss', 'lightningcss'] as const) {
describe(transformer, () => {
test(`production build`, createSetup(transformer), async ({ fs, exec }) => {
await exec('pnpm vite build')

let files = await fs.glob('dist/**/*.css')
expect(files).toHaveLength(1)
let [filename] = files[0]

await fs.expectFileToContain(filename, [
css`
.foo {
color: blue;
}
`,
])
})

test(`dev mode`, createSetup(transformer), async ({ spawn, getFreePort, fs }) => {
let port = await getFreePort()
await spawn(`pnpm vite dev --port ${port}`)

await retryAssertion(async () => {
let styles = await fetchStyles(port, '/index.html')
expect(styles).toContain(css`
.foo {
color: blue;
}
`)
})

await retryAssertion(async () => {
await fs.write(
'src/index.css',
css`
@import 'tailwindcss/theme' theme(reference);
@import 'tailwindcss/utilities';
.foo {
background-color: red;
}
`,
)

let styles = await fetchStyles(port)
expect(styles).toContain(css`
.foo {
background-color: blue;
}
`)
})
})

test('watch mode', createSetup(transformer), async ({ spawn, fs }) => {
await spawn(`pnpm vite build --watch`)

await retryAssertion(async () => {
let files = await fs.glob('dist/**/*.css')
expect(files).toHaveLength(1)
let [, styles] = files[0]

expect(styles).toContain(css`
.foo {
color: blue;
}
`)
})

await retryAssertion(async () => {
await fs.write(
'src/index.css',
css`
@import 'tailwindcss/theme' theme(reference);
@import 'tailwindcss/utilities';
.foo {
background-color: red;
}
`,
)

let files = await fs.glob('dist/**/*.css')
expect(files).toHaveLength(1)
let [, styles] = files[0]

expect(styles).toContain(css`
.foo {
background-color: blue;
}
`)
})
})
})
}
39 changes: 19 additions & 20 deletions packages/@tailwindcss-vite/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ export default function tailwindcss(): Plugin[] {
let isSSR = false
let minify = false

// A list of css plugins defined in the Vite config. We need to retain these
// so that we can rerun the right transformations in build mode where we have
// to manually rebuild the css file after the compilation is done.
let cssPlugins: readonly Plugin[] = []

// The Vite extension has two types of sources for candidates:
//
// 1. The module graph: These are all modules that vite transforms and we want
Expand Down Expand Up @@ -109,8 +104,26 @@ export default function tailwindcss(): Plugin[] {
},
}

for (let plugin of cssPlugins) {
for (let plugin of config!.plugins) {
if (!plugin.transform) continue

if (plugin.name.startsWith('@tailwindcss/')) {
// We do not run any Tailwind transforms anymore
continue
} else if (
plugin.name.startsWith('vite:') &&
// Apply the vite:css plugin to generated CSS for transformations like
// URL path rewriting and image inlining.
plugin.name !== 'vite:css' &&
// In build mode, since `renderStart` runs after all transformations, we
// need to also apply vite:css-post.
plugin.name !== 'vite:css-post' &&
// The vite:vue plugin handles CSS specific post-processing for Vue
plugin.name !== 'vite:vue'
) {
continue
}

let transformHandler =
'handler' in plugin.transform! ? plugin.transform.handler : plugin.transform!

Expand Down Expand Up @@ -147,20 +160,6 @@ export default function tailwindcss(): Plugin[] {
config = _config
minify = config.build.cssMinify !== false
isSSR = config.build.ssr !== false && config.build.ssr !== undefined

let allowedPlugins = [
// Apply the vite:css plugin to generated CSS for transformations like
// URL path rewriting and image inlining.
'vite:css',

// In build mode, since renderChunk runs after all transformations, we
// need to also apply vite:css-post.
...(config.command === 'build' ? ['vite:css-post'] : []),
]

cssPlugins = config.plugins.filter((plugin) => {
return allowedPlugins.includes(plugin.name)
})
},

// Scan all non-CSS files for candidates
Expand Down
27 changes: 6 additions & 21 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1cc0022

Please sign in to comment.