Support vite build --watch mode

This commit is contained in:
Philipp Spiess 2024-08-28 17:19:33 +02:00
parent a36ca437db
commit d7393f95bc
2 changed files with 124 additions and 122 deletions

View file

@ -219,135 +219,131 @@ import {
},
)
// test(
// 'watch mode',
// {
// fs: {
// 'package.json': json`{}`,
// 'pnpm-workspace.yaml': yaml`
// #
// packages:
// - project-a
// `,
// 'project-a/package.json': json`
// {
// "type": "module",
// "dependencies": {
// "@tailwindcss/vite": "workspace:^",
// "tailwindcss": "workspace:^"
// },
// "devDependencies": {
// "vite": "^5.3.5"
// }
// }
// `,
// 'project-a/vite.config.ts': ts`
// import tailwindcss from '@tailwindcss/vite'
// import { defineConfig } from 'vite'
test.only(
'watch mode',
{
fs: {
'package.json': json`{}`,
'pnpm-workspace.yaml': yaml`
#
packages:
- project-a
`,
'project-a/package.json': json`
{
"type": "module",
"dependencies": {
"@tailwindcss/vite": "workspace:^",
"tailwindcss": "workspace:^"
},
"devDependencies": {
"vite": "^5.3.5"
}
}
`,
'project-a/vite.config.ts': ts`
import tailwindcss from '@tailwindcss/vite'
import { defineConfig } from 'vite'
// export default defineConfig({
// build: { cssMinify: false },
// plugins: [tailwindcss()],
// })
// `,
// 'project-a/index.html': html`
// <head>
// <link rel="stylesheet" href="./src/index.css" />
// </head>
// <body>
// <div class="underline">Hello, world!</div>
// </body>
// `,
// 'project-a/src/index.css': css`
// @import 'tailwindcss/theme' theme(reference);
// @import 'tailwindcss/utilities';
// @source '../../project-b/src/**/*.js';
// `,
// 'project-b/src/index.js': js`
// const className = "content-['project-b/src/index.js']"
// module.exports = { className }
// `,
// },
// },
// async ({ root, spawn, fs }) => {
// await spawn(`pnpm vite build --watch`, {
// cwd: path.join(root, 'project-a'),
// })
export default defineConfig({
build: { cssMinify: false },
plugins: [tailwindcss()],
})
`,
'project-a/index.html': html`
<head>
<link rel="stylesheet" href="./src/index.css" />
</head>
<body>
<div class="underline">Hello, world!</div>
</body>
`,
'project-a/src/index.css': css`
@import 'tailwindcss/theme' theme(reference);
@import 'tailwindcss/utilities';
@source '../../project-b/src/**/*.js';
`,
'project-b/src/index.js': js`
const className = "content-['project-b/src/index.js']"
module.exports = { className }
`,
},
},
async ({ root, spawn, fs }) => {
await spawn(`pnpm vite build --watch`, {
cwd: path.join(root, 'project-a'),
})
// let filename = ''
// await retryAssertion(async () => {
// let files = await fs.glob('project-a/dist/**/*.css')
// expect(files).toHaveLength(1)
// filename = files[0][0]
// })
let filename = ''
await retryAssertion(async () => {
let files = await fs.glob('project-a/dist/**/*.css')
expect(files).toHaveLength(1)
filename = files[0][0]
})
// await fs.expectFileToContain(filename, [candidate`underline`])
await fs.expectFileToContain(filename, [candidate`underline`])
// await new Promise((resolve) => setTimeout(resolve, 1000))
await new Promise((resolve) => setTimeout(resolve, 1000))
// // Updates are additive and cause new candidates to be added.
// await fs.write(
// 'project-a/index.html',
// html`
// <head>
// <link rel="stylesheet" href="./src/index.css" />
// </head>
// <body>
// <div class="underline m-2">Hello, world!</div>
// </body>
// `,
// )
// await retryAssertion(async () => {
// let files = await fs.glob('project-a/dist/**/*.css')
// let filenames = files.map(([filename]) => filename)
// // Expect a rebuild to have a different .css hash
// expect(filenames).not.toContain(filename)
// expect(filenames).toHaveLength(1)
// filename = filenames[0]
// })
// await fs.expectFileToContain(filename, [candidate`underline`, candidate`m-2`])
// Updates are additive and cause new candidates to be added.
await fs.write(
'project-a/index.html',
html`
<head>
<link rel="stylesheet" href="./src/index.css" />
</head>
<body>
<div class="underline m-2">Hello, world!</div>
</body>
`,
)
await retryAssertion(async () => {
let files = await fs.glob('project-a/dist/**/*.css')
expect(files).toHaveLength(1)
let [, css] = files[0]
expect(css).toContain(candidate`underline`)
expect(css).toContain(candidate`m-2`)
})
// // Manually added `@source`s are watched and trigger a rebuild
// await fs.write(
// 'project-b/src/index.js',
// js`
// const className = "[.changed_&]:content-['project-b/src/index.js']"
// module.exports = { className }
// `,
// )
// await fs.expectFileToContain(filename, [
// candidate`underline`,
// candidate`m-2`,
// candidate`[.changed_&]:content-['project-b/src/index.js']`,
// ])
// Manually added `@source`s are watched and trigger a rebuild
await fs.write(
'project-b/src/index.js',
js`
const className = "[.changed_&]:content-['project-b/src/index.js']"
module.exports = { className }
`,
)
await retryAssertion(async () => {
let files = await fs.glob('project-a/dist/**/*.css')
expect(files).toHaveLength(1)
let [, css] = files[0]
expect(css).toContain(candidate`underline`)
expect(css).toContain(candidate`m-2`)
expect(css).toContain(candidate`[.changed_&]:content-['project-b/src/index.js']`)
})
// // After updates to the CSS file, all previous candidates should still be in
// // the generated CSS
// await fs.write(
// 'project-a/src/index.css',
// css`
// ${await fs.read('project-a/src/index.css')}
// After updates to the CSS file, all previous candidates should still be in
// the generated CSS
await fs.write(
'project-a/src/index.css',
css`
${await fs.read('project-a/src/index.css')}
// .red {
// color: red;
// }
// `,
// )
// await retryAssertion(async () => {
// let files = await fs.glob('project-a/dist/**/*.css')
// let filenames = files.map(([filename]) => filename)
// // Expect a rebuild to have a different .css hash
// expect(filenames).not.toContain(filename)
// expect(filenames).toHaveLength(1)
// filename = filenames[0]
// })
// await fs.expectFileToContain(filename, [
// candidate`red`,
// candidate`underline`,
// candidate`m-2`,
// candidate`[.changed_&]:content-['project-b/src/index.js']`,
// ])
// },
// )
.red {
color: red;
}
`,
)
await retryAssertion(async () => {
let files = await fs.glob('project-a/dist/**/*.css')
expect(files).toHaveLength(1)
let [, css] = files[0]
expect(css).toContain(candidate`underline`)
expect(css).toContain(candidate`m-2`)
expect(css).toContain(candidate`[.changed_&]:content-['project-b/src/index.js']`)
expect(css).toContain(candidate`red`)
})
},
)
})
})

View file

@ -333,6 +333,12 @@ export default function tailwindcss(): Plugin[] {
apply: 'build',
enforce: 'pre',
buildStart() {
for (let [, file] of Object.entries(cssModules)) {
file.handled = false
}
},
async transform(src, id) {
if (!isTailwindCssFile(id, src)) return
onFileChange(id)