diff --git a/playground/css/__tests__/postcss-plugins-different-dir/postcss-plugins-different-dir.spec.ts b/playground/css/__tests__/postcss-plugins-different-dir/postcss-plugins-different-dir.spec.ts
index fb748bf2c8fff2..1d21eb760dabfd 100644
--- a/playground/css/__tests__/postcss-plugins-different-dir/postcss-plugins-different-dir.spec.ts
+++ b/playground/css/__tests__/postcss-plugins-different-dir/postcss-plugins-different-dir.spec.ts
@@ -21,7 +21,7 @@ test.runIf(isServe)('postcss plugins in different dir', async () => {
await server.listen()
try {
await page.goto(`http://localhost:${port}`)
- const tailwindStyle = await page.$('.tailwind-style')
+ const tailwindStyle = page.locator('#tailwind-style')
expect(await getBgColor(tailwindStyle)).toBe('rgb(254, 226, 226)')
expect(await getColor(tailwindStyle)).toBe('rgb(136, 136, 136)')
} finally {
diff --git a/playground/tailwind/__test__/tailwind.spec.ts b/playground/tailwind/__test__/tailwind.spec.ts
index e639678331e9e5..c67ef115073b69 100644
--- a/playground/tailwind/__test__/tailwind.spec.ts
+++ b/playground/tailwind/__test__/tailwind.spec.ts
@@ -1,84 +1,82 @@
import { expect, test } from 'vitest'
import {
editFile,
- getBgColor,
getColor,
- isBuild,
+ isServe,
page,
untilBrowserLogAfter,
untilUpdated,
} from '~utils'
test('should render', async () => {
- expect(await page.textContent('#pagetitle')).toBe('|Page title|')
+ expect(await page.textContent('#pagetitle')).toBe('Page title')
})
-if (!isBuild) {
- test('regenerate CSS and HMR (glob pattern)', async () => {
- const el = await page.$('#pagetitle')
- const el2 = await page.$('#helloroot')
- expect(await getColor(el)).toBe('rgb(11, 22, 33)')
+test.runIf(isServe)('regenerate CSS and HMR (glob pattern)', async () => {
+ const el = page.locator('#view1-text')
+ expect(await getColor(el)).toBe('rgb(22, 163, 74)')
- await untilBrowserLogAfter(
- () =>
- editFile('src/views/Page.vue', (code) =>
- code.replace('|Page title|', '|Page title updated|'),
- ),
- [
- '[vite] css hot updated: /index.css',
- '[vite] hot updated: /src/views/Page.vue',
- ],
- false,
- )
- await untilUpdated(() => el.textContent(), '|Page title updated|')
+ await untilBrowserLogAfter(
+ () =>
+ editFile('src/views/view1.js', (code) =>
+ code.replace('|view1|', '|view1 updated|'),
+ ),
+ [
+ '[vite] css hot updated: /index.css',
+ '[vite] hot updated: /src/views/view1.js via /src/main.js',
+ ],
+ false,
+ )
+ await untilUpdated(() => el.textContent(), '|view1 updated|')
- await untilBrowserLogAfter(
- () =>
- editFile('src/components/HelloWorld.vue', (code) =>
- code.replace('text-gray-800', 'text-[rgb(10,20,30)]'),
- ),
- [
- '[vite] css hot updated: /index.css',
- '[vite] hot updated: /src/components/HelloWorld.vue',
- ],
- false,
- )
- await untilUpdated(() => getColor(el2), 'rgb(10, 20, 30)')
- })
+ await untilBrowserLogAfter(
+ () =>
+ editFile('src/views/view1.js', (code) =>
+ code.replace('text-green-600', 'text-orange-600'),
+ ),
+ [
+ '[vite] css hot updated: /index.css',
+ '[vite] hot updated: /src/views/view1.js via /src/main.js',
+ ],
+ false,
+ )
+ // await new Promise(resolve => setTimeout(resolve, 10))
+ await untilUpdated(async () => getColor(el), 'rgb(234, 88, 12)')
+})
- test('regenerate CSS and HMR (relative path)', async () => {
- const el = await page.$('h1')
- expect(await getColor(el)).toBe('black')
+test.runIf(isServe)(
+ 'same file duplicated in module graph (#4267)',
+ async () => {
+ const el = page.locator('#component1')
+ expect(await getColor(el)).toBe('rgb(220, 38, 38)')
+ // when duplicated, page reload happens
await untilBrowserLogAfter(
() =>
- editFile('src/App.vue', (code) =>
- code.replace('text-black', 'text-[rgb(11,22,33)]'),
+ editFile('src/components/component1.js', (code) =>
+ code.replace('text-red-600', 'text-blue-600'),
),
[
'[vite] css hot updated: /index.css',
- '[vite] hot updated: /src/App.vue',
+ '[vite] hot updated: /src/components/component1.js',
],
false,
)
- await untilUpdated(() => getColor(el), 'rgb(11, 22, 33)')
- })
+ await untilUpdated(() => getColor(el), 'rgb(37, 99, 235)')
+ },
+)
- test('regenerate CSS and HMR (pug template)', async () => {
- const el = await page.$('.pug')
- expect(await getBgColor(el)).toBe('rgb(248, 113, 113)')
+test.runIf(isServe)('regenerate CSS and HMR (relative path)', async () => {
+ const el = page.locator('#pagetitle')
+ expect(await getColor(el)).toBe('rgb(124, 58, 237)')
- await untilBrowserLogAfter(
- () =>
- editFile('src/components/PugTemplate.vue', (code) =>
- code.replace('bg-red-400', 'bg-red-600'),
- ),
- [
- '[vite] css hot updated: /index.css',
- '[vite] hot updated: /src/components/PugTemplate.vue?vue&type=template&lang.js',
- ],
- false,
- )
- await untilUpdated(() => getBgColor(el), 'rgb(220, 38, 38)')
- })
-}
+ await untilBrowserLogAfter(
+ () =>
+ editFile('src/main.js', (code) =>
+ code.replace('text-violet-600', 'text-cyan-600'),
+ ),
+ ['[vite] css hot updated: /index.css', '[vite] hot updated: /src/main.js'],
+ false,
+ )
+ await untilUpdated(() => getColor(el), 'rgb(8, 145, 178)')
+})
diff --git a/playground/tailwind/index.html b/playground/tailwind/index.html
index d28c699ba6d465..0c7bee6b26884f 100644
--- a/playground/tailwind/index.html
+++ b/playground/tailwind/index.html
@@ -1,14 +1,5 @@
-
-
-
-
-
-
- Vite App
-
-
-
-
-
-
-
+
+
+
+
+
diff --git a/playground/tailwind/src/App.vue b/playground/tailwind/src/App.vue
deleted file mode 100644
index 25835fc414a06f..00000000000000
--- a/playground/tailwind/src/App.vue
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
Tailwind app
- {{ foo }}
-
-
-
-
-
diff --git a/playground/tailwind/src/assets/logo.png b/playground/tailwind/src/assets/logo.png
deleted file mode 100644
index f3d2503fc2a44b..00000000000000
Binary files a/playground/tailwind/src/assets/logo.png and /dev/null differ
diff --git a/playground/tailwind/src/components/HelloWorld.vue b/playground/tailwind/src/components/HelloWorld.vue
deleted file mode 100644
index b1ce4248557b39..00000000000000
--- a/playground/tailwind/src/components/HelloWorld.vue
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- HelloWorld - {{ count }}
-
-
-
-
diff --git a/playground/tailwind/src/components/PugTemplate.vue b/playground/tailwind/src/components/PugTemplate.vue
deleted file mode 100644
index 4169b534dee4ef..00000000000000
--- a/playground/tailwind/src/components/PugTemplate.vue
+++ /dev/null
@@ -1,3 +0,0 @@
-
-.bg-red-400.pug Pug template
-
diff --git a/playground/tailwind/src/components/component1.js b/playground/tailwind/src/components/component1.js
new file mode 100644
index 00000000000000..df5e36f0bacd56
--- /dev/null
+++ b/playground/tailwind/src/components/component1.js
@@ -0,0 +1,9 @@
+export const component1 = /* html */ `
+ component1
+`
+
+import.meta.hot?.accept((mod) => {
+ document.querySelectorAll('[data-id="component1"]').forEach((d) => {
+ d.outerHTML = mod.component1
+ })
+})
diff --git a/playground/tailwind/src/main.js b/playground/tailwind/src/main.js
index 78494e75b4741d..b9f0c5956232d5 100644
--- a/playground/tailwind/src/main.js
+++ b/playground/tailwind/src/main.js
@@ -1,6 +1,18 @@
-import { createApp } from 'vue'
-import App from './App.vue'
-import router from './router'
-// import '../index.css';
+import { view1 } from './views/view1'
-createApp(App).use(router).mount('#app')
+export const main = (view1Content) => /* html */ `
+ Page title
+ ${view1Content}
+
+ style
+`
+
+document.getElementById('app').innerHTML = main(view1)
+
+import.meta.hot?.accept((mod) => {
+ document.getElementById('app').innerHTML = mod.main(view1)
+})
+
+import.meta.hot?.accept(['./views/view1'], ([mod]) => {
+ document.getElementById('app').innerHTML = main(mod.view1)
+})
diff --git a/playground/tailwind/src/router.ts b/playground/tailwind/src/router.ts
deleted file mode 100644
index 10e3980cb07cb8..00000000000000
--- a/playground/tailwind/src/router.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { createRouter, createWebHistory } from 'vue-router'
-import Page from './views/Page.vue'
-
-const history = createWebHistory()
-
-const router = createRouter({
- history: history,
- routes: [
- {
- path: '/',
- component: Page,
- },
- ],
-})
-
-export default router
diff --git a/playground/tailwind/src/utils.ts b/playground/tailwind/src/utils.ts
deleted file mode 100644
index 38c21ae7a0f8d8..00000000000000
--- a/playground/tailwind/src/utils.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export const NAME = 'Tailwind'
-export const INITIAL_COUNT = 1
diff --git a/playground/tailwind/src/views/Page.vue b/playground/tailwind/src/views/Page.vue
deleted file mode 100644
index 76f8aabf13d7d3..00000000000000
--- a/playground/tailwind/src/views/Page.vue
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
|Page title|
-
{{ val }}
-
- {{ name }} style
-
-
-
-
-
-
-
diff --git a/playground/tailwind/src/views/view1.js b/playground/tailwind/src/views/view1.js
new file mode 100644
index 00000000000000..c9e0c0d1745fe2
--- /dev/null
+++ b/playground/tailwind/src/views/view1.js
@@ -0,0 +1,8 @@
+import { component1 } from '../components/component1'
+
+export const view1 = /* html */ `
+
+
|view1|
+ ${component1}
+
+`
diff --git a/playground/tailwind/tailwind.config.js b/playground/tailwind/tailwind.config.js
index 1b80b08aba2ef1..e4504c499e78f0 100644
--- a/playground/tailwind/tailwind.config.js
+++ b/playground/tailwind/tailwind.config.js
@@ -2,10 +2,10 @@
module.exports = {
content: [
- // Before editing this section, make sure no paths are matching with `/src/App.vue`
+ // Before editing this section, make sure no paths are matching with `/src/main.js`
// Look https://github.com/vitejs/vite/pull/6959 for more details
- __dirname + '/src/{components,views}/**/*.vue',
- __dirname + '/src/App.vue',
+ __dirname + '/src/{components,views}/**/*.js',
+ __dirname + '/src/main.js',
],
theme: {
extend: {},
diff --git a/playground/tailwind/vite.config.ts b/playground/tailwind/vite.config.ts
index d3680f6c39c3e3..5b97ed1053e382 100644
--- a/playground/tailwind/vite.config.ts
+++ b/playground/tailwind/vite.config.ts
@@ -1,5 +1,4 @@
import { defineConfig } from 'vite'
-import vue from '@vitejs/plugin-vue'
export default defineConfig({
resolve: {
@@ -7,7 +6,6 @@ export default defineConfig({
'/@': __dirname,
},
},
- plugins: [vue()],
build: {
// to make tests faster
minify: false,
@@ -17,4 +15,15 @@ export default defineConfig({
// although it should not affect the build
origin: 'http://localhost:8080',
},
+ plugins: [
+ {
+ name: 'delay view',
+ enforce: 'pre',
+ async transform(_code, id) {
+ if (id.includes('views/view1.js')) {
+ await new Promise((resolve) => setTimeout(resolve, 100))
+ }
+ },
+ },
+ ],
})
diff --git a/playground/test-utils.ts b/playground/test-utils.ts
index df68dce9c5e66f..39e2f56c5e6a86 100644
--- a/playground/test-utils.ts
+++ b/playground/test-utils.ts
@@ -4,7 +4,11 @@
import fs from 'node:fs'
import path from 'node:path'
import colors from 'css-color-names'
-import type { ConsoleMessage, ElementHandle } from 'playwright-chromium'
+import type {
+ ConsoleMessage,
+ ElementHandle,
+ Locator,
+} from 'playwright-chromium'
import type { DepOptimizationMetadata, Manifest } from 'vite'
import { normalizePath } from 'vite'
import { fromComment } from 'convert-source-map'
@@ -74,7 +78,9 @@ function rgbToHex(rgb: string): string {
const timeout = (n: number) => new Promise((r) => setTimeout(r, n))
-async function toEl(el: string | ElementHandle): Promise {
+async function toEl(
+ el: string | ElementHandle | Locator,
+): Promise {
if (typeof el === 'string') {
const realEl = await page.$(el)
if (realEl == null) {
@@ -82,21 +88,30 @@ async function toEl(el: string | ElementHandle): Promise {
}
return realEl
}
+ if ('elementHandle' in el) {
+ return el.elementHandle()
+ }
return el
}
-export async function getColor(el: string | ElementHandle): Promise {
+export async function getColor(
+ el: string | ElementHandle | Locator,
+): Promise {
el = await toEl(el)
const rgb = await el.evaluate((el) => getComputedStyle(el as Element).color)
return hexToNameMap[rgbToHex(rgb)] ?? rgb
}
-export async function getBg(el: string | ElementHandle): Promise {
+export async function getBg(
+ el: string | ElementHandle | Locator,
+): Promise {
el = await toEl(el)
return el.evaluate((el) => getComputedStyle(el as Element).backgroundImage)
}
-export async function getBgColor(el: string | ElementHandle): Promise {
+export async function getBgColor(
+ el: string | ElementHandle | Locator,
+): Promise {
el = await toEl(el)
return el.evaluate((el) => getComputedStyle(el as Element).backgroundColor)
}