test: css addWatchFile in load hook

This commit is contained in:
bluwy 2024-09-13 22:12:07 +08:00
parent ba56cf43b5
commit 16603203ca
7 changed files with 70 additions and 16 deletions

View File

@ -999,11 +999,20 @@ if (!isBuild) {
await untilUpdated(() => el.evaluate((it) => `${it.clientHeight}`), '40')
})
test('CSS HMR with this.addWatchFile', async () => {
test('CSS HMR with this.addWatchFile in transform hook', async () => {
await page.goto(viteTestUrl + '/css-deps/index.html')
expect(await getColor('.css-deps')).toMatch('red')
editFile('css-deps/dep.js', (code) => code.replace(`red`, `green`))
await untilUpdated(() => getColor('.css-deps'), 'green')
expect(await getColor('.css-deps-transform')).toMatch('red')
editFile('css-deps/dep-transform.js', (code) =>
code.replace(`red`, `green`),
)
await untilUpdated(() => getColor('.css-deps-transform'), 'green')
})
test('CSS HMR with this.addWatchFile in load hook', async () => {
await page.goto(viteTestUrl + '/css-deps/index.html')
expect(await getColor('.css-deps-load')).toMatch('red')
editFile('css-deps/dep-load.js', (code) => code.replace(`red`, `green`))
await untilUpdated(() => getColor('.css-deps-load'), 'green')
})
test('hmr should happen after missing file is created', async () => {

View File

@ -1,4 +1,4 @@
// This file is depended by main.css via this.addWatchFile
// This file is depended by main-load.css via this.addWatchFile
export const color = 'red'
// Self-accept so that updating this file would not trigger a page reload.

View File

@ -0,0 +1,8 @@
// This file is depended by main-transform.css via this.addWatchFile
export const color = 'red'
// Self-accept so that updating this file would not trigger a page reload.
// We only want to observe main.css updating itself.
if (import.meta.hot) {
import.meta.hot.accept()
}

View File

@ -1,8 +1,11 @@
<div class="css-deps">should be red</div>
<div class="css-deps-transform">should be red</div>
<div class="css-deps-load">should be red</div>
<script type="module">
import './main.css'
import './main-transform.css'
import 'virtual:css-deps-load.css'
// Import dep.js so that not only the CSS depends on dep.js, as Vite will do
// a full page reload if the only importers are CSS files.
import './dep.js'
import './dep-transform.js'
import './dep-load.js'
</script>

View File

@ -0,0 +1,3 @@
.css-deps-transform {
color: replaced;
}

View File

@ -1,3 +0,0 @@
.css-deps {
color: replaced;
}

View File

@ -29,7 +29,8 @@ export default defineConfig({
},
virtualPlugin(),
transformCountPlugin(),
watchCssDepsPlugin(),
watchCssDepsTransformPlugin(),
watchCssDepsLoadPlugin(),
],
})
@ -76,14 +77,15 @@ function transformCountPlugin(): Plugin {
}
}
function watchCssDepsPlugin(): Plugin {
// `addWatchFile` called from `transform` hook
function watchCssDepsTransformPlugin(): Plugin {
return {
name: 'watch-css-deps',
name: 'watch-css-deps-transform',
async transform(code, id) {
// replace the `replaced` identifier in the CSS file with the adjacent
// `dep.js` file's `color` variable.
if (id.includes('css-deps/main.css')) {
const depPath = path.resolve(__dirname, './css-deps/dep.js')
if (id.includes('css-deps/main-transform.css')) {
const depPath = path.resolve(__dirname, './css-deps/dep-transform.js')
const dep = await fs.readFile(depPath, 'utf-8')
const color = dep.match(/color = '(.+?)'/)[1]
this.addWatchFile(depPath)
@ -92,3 +94,35 @@ function watchCssDepsPlugin(): Plugin {
},
}
}
// `addWatchFile` called from `load` hook
function watchCssDepsLoadPlugin(): Plugin {
return {
name: 'watch-css-deps-load',
resolveId(id) {
if (id === 'virtual:css-deps-load.css') {
return '\0virtual:css-deps-load.css'
}
},
async load(id) {
if (id === '\0virtual:css-deps-load.css') {
const depPath = path.resolve(__dirname, './css-deps/dep.js')
this.addWatchFile(depPath)
return `\
.css-deps-load {
color: replaced;
}`
}
},
async transform(code, id) {
// replace the `replaced` identifier in the CSS file with the adjacent
// `dep.js` file's `color` variable.
if (id === '\0virtual:css-deps-load.css') {
const depPath = path.resolve(__dirname, './css-deps/dep-load.js')
const dep = await fs.readFile(depPath, 'utf-8')
const color = dep.match(/color = '(.+?)'/)[1]
return code.replace('replaced', color)
}
},
}
}