Skip to content

Commit

Permalink
test: hmr tests
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Dec 23, 2020
1 parent d76557e commit a0d48fc
Show file tree
Hide file tree
Showing 14 changed files with 176 additions and 40 deletions.
4 changes: 2 additions & 2 deletions packages/playground/assets/__tests__/assets.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'fs'
import path from 'path'
import { getBg, getColor, browserLogs, isBuild, testDir } from '../../testUtils'
import { getBg, getColor, isBuild, testDir } from '../../testUtils'

const assetMatch = isBuild
? /\/foo\/assets\/asset\.\w{8}\.png/
Expand All @@ -9,7 +9,7 @@ const assetMatch = isBuild
const iconMatch = isBuild ? `/foo/icon.png` : `icon.png`

test('should have no 404s', () => {
browserLogs.forEach((msg) => {
pageLogs.forEach((msg) => {
expect(msg).not.toMatch('404')
})
})
Expand Down
113 changes: 113 additions & 0 deletions packages/playground/hmr/__tests__/hmr.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { isBuild, editFile, untilUpdated } from '../../testUtils'

test('should render', async () => {
expect(await page.textContent('.app')).toBe('1')
expect(await page.textContent('.dep')).toBe('1')
expect(await page.textContent('.nested')).toBe('1')
})

if (!isBuild) {
test('should connect', async () => {
expect(pageLogs.length).toBe(2)
expect(pageLogs.some((msg) => msg.match('connected'))).toBe(true)
pageLogs.length = 0
})

test('self accept', async () => {
const el = await page.$('.app')

editFile('hmr.js', (code) => code.replace('const foo = 1', 'const foo = 2'))
await untilUpdated(() => el.textContent(), '2')

expect(pageLogs).toMatchObject([
'foo was: 1',
'(self-accepting 1) foo is now: 2',
'(self-accepting 2) foo is now: 2',
'[vite] hot updated: /hmr.js'
])
pageLogs.length = 0

editFile('hmr.js', (code) => code.replace('const foo = 2', 'const foo = 3'))
await untilUpdated(() => el.textContent(), '3')

expect(pageLogs).toMatchObject([
'foo was: 2',
'(self-accepting 1) foo is now: 3',
'(self-accepting 2) foo is now: 3',
'[vite] hot updated: /hmr.js'
])
pageLogs.length = 0
})

test('accept dep', async () => {
const el = await page.$('.dep')

editFile('hmrDep.js', (code) =>
code.replace('const foo = 1', 'const foo = 2')
)
await untilUpdated(() => el.textContent(), '2')

expect(pageLogs).toMatchObject([
'(dep) foo was: 1',
'(dep) foo from dispose: 1',
'(single dep) foo is now: 2',
'(single dep) nested foo is now: 1',
'(multi deps) foo is now: 2',
'(multi deps) nested foo is now: 1',
'[vite] hot updated: /hmrDep.js via /hmr.js'
])
pageLogs.length = 0

editFile('hmrDep.js', (code) =>
code.replace('const foo = 2', 'const foo = 3')
)
await untilUpdated(() => el.textContent(), '3')

expect(pageLogs).toMatchObject([
'(dep) foo was: 2',
'(dep) foo from dispose: 2',
'(single dep) foo is now: 3',
'(single dep) nested foo is now: 1',
'(multi deps) foo is now: 3',
'(multi deps) nested foo is now: 1',
'[vite] hot updated: /hmrDep.js via /hmr.js'
])
pageLogs.length = 0
})

test('nested dep propagation', async () => {
const el = await page.$('.nested')

editFile('hmrNestedDep.js', (code) =>
code.replace('const foo = 1', 'const foo = 2')
)
await untilUpdated(() => el.textContent(), '2')

expect(pageLogs).toMatchObject([
'(dep) foo was: 3',
'(dep) foo from dispose: 3',
'(single dep) foo is now: 3',
'(single dep) nested foo is now: 2',
'(multi deps) foo is now: 3',
'(multi deps) nested foo is now: 2',
'[vite] hot updated: /hmrDep.js via /hmr.js'
])
pageLogs.length = 0

editFile('hmrNestedDep.js', (code) =>
code.replace('const foo = 2', 'const foo = 3')
)
await untilUpdated(() => el.textContent(), '3')

expect(pageLogs).toMatchObject([
'(dep) foo was: 3',
'(dep) foo from dispose: 3',
'(single dep) foo is now: 3',
'(single dep) nested foo is now: 3',
'(multi deps) foo is now: 3',
'(multi deps) nested foo is now: 3',
'[vite] hot updated: /hmrDep.js via /hmr.js'
])
pageLogs.length = 0
})
}
31 changes: 22 additions & 9 deletions packages/playground/hmr/hmr.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
import './hmrDep.js'
import './style.css'
import { foo as depFoo, nestedFoo } from './hmrDep'

export const foo = 222233
export const foo = 1
text('.app', foo)
text('.dep', depFoo)
text('.nested', nestedFoo)

if (import.meta.hot) {
import.meta.hot.accept(({ foo }) => {
console.log('(self-accepting)1.foo is now:', foo)
console.log('(self-accepting 1) foo is now:', foo)
})

import.meta.hot.accept(({ foo }) => {
console.log('(self-accepting)2.foo is now:', foo)
console.log('(self-accepting 2) foo is now:', foo)
})

import.meta.hot.accept('./hmrDep', ({ foo }) => {
console.log('(single dep) foo is now:', foo)
const handleDep = (type, newFoo, newNestedFoo) => {
console.log(`(${type}) foo is now: ${newFoo}`)
console.log(`(${type}) nested foo is now: ${newNestedFoo}`)
text('.dep', newFoo)
text('.nested', newNestedFoo)
}

import.meta.hot.accept('./hmrDep', ({ foo, nestedFoo }) => {
handleDep('single dep', foo, nestedFoo)
})

import.meta.hot.accept(['./hmrDep'], (modules) => {
console.log('(multiple deps) foo is now:', modules[0].foo)
import.meta.hot.accept(['./hmrDep'], ([{ foo, nestedFoo }]) => {
handleDep('multi deps', foo, nestedFoo)
})

import.meta.hot.dispose(() => {
console.log(`foo was:`, foo)
})
}

function text(el, text) {
document.querySelector(el).textContent = text
}
7 changes: 3 additions & 4 deletions packages/playground/hmr/hmrDep.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import './hmrNestedDep'

export const foo = 'from depppp'
export const foo = 1
export { foo as nestedFoo } from './hmrNestedDep'

if (import.meta.hot) {
const data = import.meta.hot.data
Expand All @@ -10,6 +9,6 @@ if (import.meta.hot) {

import.meta.hot.dispose((data) => {
console.log(`(dep) foo was: ${foo}`)
data.fromDispose = foo * 1033
data.fromDispose = foo
})
}
2 changes: 1 addition & 1 deletion packages/playground/hmr/hmrNestedDep.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
console.log('I should log?')
export const foo = 1
5 changes: 5 additions & 0 deletions packages/playground/hmr/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script type="module" src="./hmr.js"></script>

<div class="app"></div>
<div class="dep"></div>
<div class="nested"></div>
10 changes: 10 additions & 0 deletions packages/playground/hmr/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "test-hmr",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"debug": "node --inspect-brk ../../vite/bin/vite"
}
}
1 change: 1 addition & 0 deletions packages/playground/testEnv.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import { Page } from 'playwright-chromium'
declare global {
// injected by the custom jest env in scripts/jestEnv.js
const page: Page
const pageLogs: string[]
const __viteTestDir__: string
}
10 changes: 1 addition & 9 deletions packages/playground/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@ import slash from 'slash'
import colors from 'css-color-names'
import { ElementHandle } from 'playwright-chromium'

export const browserLogs = []

beforeAll(() => {
page.on('console', (msg) => {
browserLogs.push(msg.text())
})
})

export const isBuild = !!process.env.VITE_TEST_BUILD

const testPath = expect.getState().testPath
Expand Down Expand Up @@ -79,7 +71,7 @@ export function editFile(filename: string, replacer: (str: string) => string) {
* Poll a getter until the value it returns includes the expected value.
*/
export async function untilUpdated(
poll: () => Promise<string>,
poll: () => string | Promise<string>,
expected: string
) {
if (isBuild) return
Expand Down
10 changes: 2 additions & 8 deletions packages/playground/vue/__tests__/vue.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import {
browserLogs,
editFile,
getColor,
isBuild,
untilUpdated
} from 'testUtils'
import { editFile, getColor, isBuild, untilUpdated } from 'testUtils'

test('should render', async () => {
expect(await page.textContent('h1')).toMatch('Vue SFCs')
Expand Down Expand Up @@ -74,7 +68,7 @@ describe('template asset reference', () => {
: '/assets/asset.png'

test('should not 404', () => {
browserLogs.forEach((msg) => {
pageLogs.forEach((msg) => {
expect(msg).not.toMatch('404')
})
})
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ async function fetchUpdate({ path, accpetedPath, timestamp }: Update) {
// dep update
for (const { deps } of mod.callbacks) {
deps.forEach((dep) => {
if (accpetedPath.startsWith(dep)) {
if (accpetedPath === dep) {
modulesToUpdate.add(dep)
}
})
Expand Down
8 changes: 5 additions & 3 deletions packages/vite/src/node/plugins/importsAnalysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,13 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {

// normalize and rewrite accepted urls
const normalizedAcceptedUrls = new Set<string>()
acceptedUrls.forEach(({ url, start, end }) => {
const normalized = toAbsoluteUrl(markExplicitImport(url))
for (const { url, start, end } of acceptedUrls) {
const [normalized] = await moduleGraph.resolveUrl(
toAbsoluteUrl(markExplicitImport(url))
)
normalizedAcceptedUrls.add(normalized)
str().overwrite(start, end, JSON.stringify(normalized))
})
}

// update the module graph for HMR analysis.
// node CSS imports does its own graph update in the css plugin so we
Expand Down
7 changes: 4 additions & 3 deletions packages/vite/src/node/server/moduleGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { isCSSRequest } from '../plugins/css'
import { cleanUrl, normalizePath, removeTimestampQuery } from '../utils'
import { TransformResult } from './transformRequest'
import { PluginContainer } from './pluginContainer'
import { parse as parseUrl } from 'url'

export class ModuleNode {
/**
Expand Down Expand Up @@ -157,9 +158,9 @@ export class ModuleGraph {
url = removeTimestampQuery(url)
const resolvedId = (await this.container.resolveId(url)).id
const ext = extname(cleanUrl(resolvedId))
const [pathname, query] = url.split('?')
if (ext && !pathname.endsWith(ext)) {
url = pathname + ext + (query ? `?${query}` : ``)
const { pathname, search, hash } = parseUrl(url)
if (ext && !pathname!.endsWith(ext)) {
url = pathname + ext + (search || '') + (hash || '')
}
return [url, resolvedId]
}
Expand Down
6 changes: 6 additions & 0 deletions scripts/jestPerTestSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ let server: ViteDevServer | http.Server
let tempDir: string
let err: Error

const logs = ((global as any).pageLogs = [])

beforeAll(async () => {
try {
const testPath = expect.getState().testPath
Expand Down Expand Up @@ -46,6 +48,10 @@ beforeAll(async () => {
}
}

page.on('console', (msg) => {
logs.push(msg.text())
})

if (!isBuildTest) {
server = await (await createServer(options)).listen()
// use resolved port from server
Expand Down

0 comments on commit a0d48fc

Please sign in to comment.