Skip to content

Commit

Permalink
refactor: use url instead of id
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Jan 10, 2024
1 parent 14583b7 commit add3bda
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ describe(
it('hmr options are defined', async ({ runtime }) => {
expect(runtime.hmrClient).toBeDefined()

const mod = await runtime.executeId('./fixtures/hmr.js')
const mod = await runtime.executeUrl('/fixtures/hmr.js')
expect(mod).toHaveProperty('hmr')
expect(mod.hmr).toHaveProperty('accept')
})

it('correctly populates hmr client', async ({ runtime }) => {
const mod = await runtime.executeId('./fixtures/d')
const mod = await runtime.executeUrl('/fixtures/d')
expect(mod.d).toBe('a')

const fixtureC = resolvePath(import.meta.url, './fixtures/c.ts')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('vite-runtime hmr works as expected', async () => {
it("hmr client is not defined if it's disabled", async ({ runtime }) => {
expect(runtime.hmrClient).toBeUndefined()

const mod = await runtime.executeId('./fixtures/hmr.js')
const mod = await runtime.executeUrl('/fixtures/hmr.js')
expect(mod).toHaveProperty('hmr')
expect(mod.hmr).toBeUndefined()
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ describe('vite-runtime initialization', async () => {
const it = await createViteRuntimeTester()

it('correctly runs ssr code', async ({ runtime }) => {
const mod = await runtime.executeId('./fixtures/simple.js')
const mod = await runtime.executeUrl('/fixtures/simple.js')
expect(mod.test).toEqual('I am initialized')
})
})
2 changes: 1 addition & 1 deletion packages/vite/src/node/ssr/runtime/__tests__/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export async function createViteRuntimeTester(
): Promise<TestAPI<TestClient>> {
function waitForWatcher(server: ViteDevServer) {
return new Promise<void>((resolve) => {
if (Object.keys(server.watcher.getWatched()).length) {
if ((server.watcher as any)._readyEmitted) {
resolve()
} else {
server.watcher.once('ready', () => resolve())
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/node/ssr/runtime/hmrHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export async function handleHMRUpdate(
}
})
for (const id of runtime.entrypoints) {
await runtime.executeId(id, false) // they are already marked as entrypoints
await runtime.executeUrl(id, false) // they are already marked as entrypoints
}
break
case 'prune':
Expand Down
30 changes: 19 additions & 11 deletions packages/vite/src/node/ssr/runtime/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,27 +63,35 @@ export class ViteRuntime {
({ acceptedPath, ssrInvalidates }) => {
this.moduleCache.delete(acceptedPath)
ssrInvalidates.forEach((id) => this.moduleCache.delete(id))
return this.executeId(acceptedPath, false)
return this.executeUrl(acceptedPath, false)
},
)
}
}

public async executeId<T = any>(
rawId: string,
// TODO: should we make sure the URL is correct? (e.g. it's not a file path)
// if it's an absolute file path on Windows/Linux, then HMR will not work correctly
// because of packages/vite/src/node/plugins/importAnalysis.ts:toAbsoluteUrl
/**
* URL to execute. Should be in the format of "/file.ts" like in the browser
*/
public async executeUrl<T = any>(
url: string,
entrypoint = false,
): Promise<T> {
const id = rawId[0] === '.' ? posixResolve(this.options.root, rawId) : rawId
const fetchedModule = await this.cachedModule(unwrapId(id))
return await this.cachedRequest(id, fetchedModule, [], { entrypoint })
url = unwrapId(url)
const fetchedModule = await this.cachedModule(url)
return await this.cachedRequest(url, fetchedModule, [], { entrypoint })
}

public async executeEntrypoints<T extends any[]>(
entrypoints: string[],
): Promise<T> {
/**
* Entrypoiont URLs to execute. Expects server URLs in the format of "/file.ts" like in the browser
* In the case of a full reload triggered by HMR, these are the modules that will be reloaded
*/
public async executeEntrypoints<T extends any[]>(urls: string[]): Promise<T> {
const results: any[] = []
for (const entrypoint of entrypoints) {
results.push(await this.executeId(entrypoint, true))
for (const entrypoint of urls) {
results.push(await this.executeUrl(entrypoint, true))
}
return results as T
}
Expand Down
46 changes: 26 additions & 20 deletions playground/hmr-ssr/__tests__/hmr.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { createServer, createViteRuntime } from 'vite'
import { ViteRuntimeHMRLogger } from 'vite/runtime'
import type { ViteRuntime } from 'vite/runtime'
import type { RollupError } from 'rollup'
import { page, promiseWithResolvers, untilUpdated, viteTestUrl } from '~utils'
import { page, promiseWithResolvers, untilUpdated } from '~utils'

let server: ViteDevServer
const clientLogs: string[] = []
Expand Down Expand Up @@ -52,7 +52,7 @@ const invalidated = (file: string) => {

describe('hmr works correctly', () => {
beforeAll(async () => {
await setupViteRuntime('./hmr.ts')
await setupViteRuntime('/hmr.ts')
})

test('should connect', async () => {
Expand Down Expand Up @@ -362,7 +362,7 @@ describe('acceptExports', () => {

beforeAll(async () => {
await untilConsoleLogAfter(
() => setupViteRuntime(`./${testDir}/index`),
() => setupViteRuntime(`/${testDir}/index`),
[CONNECTED, />>>>>>/],
(logs) => {
expect(logs).toContain(`<<<<<< A0 B0 D0 ; ${dep}`)
Expand Down Expand Up @@ -490,7 +490,7 @@ describe('acceptExports', () => {

beforeAll(async () => {
await untilConsoleLogAfter(
() => setupViteRuntime(`${viteTestUrl}/${testDir}`),
() => setupViteRuntime(`/${testDir}`),
[CONNECTED, />>>>>>/],
(logs) => {
expect(logs).toContain(`<<< named: ${a} ; ${dep}`)
Expand Down Expand Up @@ -544,7 +544,7 @@ describe('acceptExports', () => {
const file = 'side-effects.ts'

await untilConsoleLogAfter(
() => setupViteRuntime(`${viteTestUrl}/${testDir}`),
() => setupViteRuntime(`/${testDir}`),
[CONNECTED, />>>/],
(logs) => {
expect(logs).toContain('>>> side FX')
Expand Down Expand Up @@ -573,7 +573,7 @@ describe('acceptExports', () => {
const url = '/' + file

await untilConsoleLogAfter(
() => setupViteRuntime(`${viteTestUrl}/${testDir}`),
() => setupViteRuntime(`/${testDir}`),
[CONNECTED, '-- unused --'],
(logs) => {
expect(logs).toContain('-- unused --')
Expand All @@ -596,7 +596,7 @@ describe('acceptExports', () => {
const file = `${testDir}/${fileName}`

await untilConsoleLogAfter(
() => setupViteRuntime(`${viteTestUrl}/${testDir}`),
() => setupViteRuntime(`/${testDir}`),
[CONNECTED, '-- used --', 'used:foo0'],
(logs) => {
expect(logs).toContain('-- used --')
Expand Down Expand Up @@ -629,7 +629,7 @@ describe('acceptExports', () => {
const url = '/' + file

await untilConsoleLogAfter(
() => setupViteRuntime(`${viteTestUrl}/${testDir}/index`),
() => setupViteRuntime(`/${testDir}/index`),
[CONNECTED, '>>> ready <<<'],
(logs) => {
expect(logs).toContain('loaded:all:a0b0c0default0')
Expand Down Expand Up @@ -663,7 +663,7 @@ describe('acceptExports', () => {
const file = `${testDir}/${fileName}`

await untilConsoleLogAfter(
() => setupViteRuntime(`${viteTestUrl}/${testDir}/`),
() => setupViteRuntime(`/${testDir}/`),
[CONNECTED, '>>> ready <<<'],
(logs) => {
expect(logs).toContain('loaded:some:a0b0c0default0')
Expand Down Expand Up @@ -691,23 +691,23 @@ describe('acceptExports', () => {
})

test('handle virtual module updates', async () => {
await setupViteRuntime('./hmr.ts')
await setupViteRuntime('/hmr.ts')
const el = () => hmr('.virtual')
expect(el()).toBe('[success]0')
editFile('importedVirtual.js', (code) => code.replace('[success]', '[wow]'))
await untilUpdated(el, '[wow]')
})

test('invalidate virtual module', async () => {
await setupViteRuntime('./hmr.ts')
await setupViteRuntime('/hmr.ts')
const el = () => hmr('.virtual')
expect(el()).toBe('[wow]0')
globalThis.__HMR__['virtual:increment']()
await untilUpdated(el, '[wow]1')
})

test.todo('should hmr when file is deleted and restored', async () => {
await setupViteRuntime('./hmr.ts')
await setupViteRuntime('/hmr.ts')

const parentFile = 'file-delete-restore/parent.js'
const childFile = 'file-delete-restore/child.js'
Expand Down Expand Up @@ -754,7 +754,7 @@ if (import.meta.hot) {
})

test.todo('delete file should not break hmr', async () => {
await page.goto(viteTestUrl)
// await page.goto(viteTestUrl)

await untilUpdated(
() => page.textContent('.intermediate-file-delete-display'),
Expand Down Expand Up @@ -805,7 +805,7 @@ test.todo('delete file should not break hmr', async () => {
})

test('import.meta.hot?.accept', async () => {
await setupViteRuntime('./hmr.ts')
await setupViteRuntime('/hmr.ts')
await untilConsoleLogAfter(
() =>
editFile('optional-chaining/child.js', (code) =>
Expand All @@ -817,7 +817,7 @@ test('import.meta.hot?.accept', async () => {
})

test('hmr works for self-accepted module within circular imported files', async () => {
await setupViteRuntime('./self-accept-within-circular/index')
await setupViteRuntime('/self-accept-within-circular/index')
const el = () => hmr('.self-accept-within-circular')
expect(el()).toBe('c')
editFile('self-accept-within-circular/c.js', (code) =>
Expand All @@ -833,7 +833,7 @@ test('hmr works for self-accepted module within circular imported files', async
})

test('hmr should not reload if no accepted within circular imported files', async () => {
await setupViteRuntime('./circular/index')
await setupViteRuntime('/circular/index')
const el = () => hmr('.circular')
expect(el()).toBe(
// tests in the browser check that there is an error, but vite runtime just returns undefined in those cases
Expand All @@ -849,7 +849,7 @@ test('hmr should not reload if no accepted within circular imported files', asyn
})

test('assets HMR', async () => {
await setupViteRuntime('./hmr.ts')
await setupViteRuntime('/hmr.ts')
const el = () => hmr('#logo')
await untilConsoleLogAfter(
() =>
Expand Down Expand Up @@ -987,7 +987,8 @@ async function untilConsoleLog(

function waitForWatcher(server: ViteDevServer) {
return new Promise<void>((resolve) => {
if (Object.keys(server.watcher.getWatched()).length) {
if ((server.watcher as any)._readyEmitted) {
console.log('watcher resolved immediately', server.watcher.getWatched())
resolve()
} else {
server.watcher.once('ready', () => resolve())
Expand Down Expand Up @@ -1047,7 +1048,12 @@ async function setupViteRuntime(
customLogger: createInMemoryLogger(serverLogs),
server: {
middlewareMode: true,
watch: {},
watch: {
// During tests we edit the files too fast and sometimes chokidar
// misses change events, so enforce polling for consistency
usePolling: true,
interval: 100,
},
hmr: {
port: 9609,
},
Expand All @@ -1073,7 +1079,7 @@ async function setupViteRuntime(

await waitForWatcher(server)

await runtime.executeId(entrypoint, true)
await runtime.executeUrl(entrypoint, true)

return {
runtime,
Expand Down

0 comments on commit add3bda

Please sign in to comment.