Skip to content

Commit

Permalink
fix: handle addWatchFile in load hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
bluwy committed Nov 13, 2023
1 parent 55335cc commit b1a456c
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 6 deletions.
25 changes: 22 additions & 3 deletions packages/vite/src/node/server/pluginContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ import { FS_PREFIX } from '../constants'
import type { ResolvedConfig } from '../config'
import { createPluginHookUtils, getHookHandler } from '../plugins'
import { buildErrorMessage } from './middlewares/error'
import type { ModuleGraph } from './moduleGraph'
import type { ModuleGraph, ModuleNode } from './moduleGraph'

const noop = () => {}

Expand Down Expand Up @@ -182,6 +182,11 @@ export async function createPluginContainer(
// ---------------------------------------------------------------------------

const watchFiles = new Set<string>()
// _addedFiles from the `load()` hook gets saved here so it can be reused in the `transform()` hook
const moduleNodeToLoadAddedImports = new WeakMap<
ModuleNode,
Set<string> | null
>()

const minimalContext: MinimalPluginContext = {
meta: {
Expand Down Expand Up @@ -273,6 +278,13 @@ export async function createPluginContainer(
}
}

function updateModuleLoadAddedImports(id: string, ctx: Context) {
const module = moduleGraph?.getModuleById(id)
if (module) {
moduleNodeToLoadAddedImports.set(module, ctx._addedImports)
}
}

// we should create a new context for each async hook pipeline so that the
// active plugin in that pipeline can be tracked in a concurrency-safe manner.
// using a class to make creating new contexts more efficient
Expand Down Expand Up @@ -520,9 +532,9 @@ export async function createPluginContainer(
sourcemapChain: NonNullable<SourceDescription['map']>[] = []
combinedMap: SourceMap | { mappings: '' } | null = null

constructor(filename: string, code: string, inMap?: SourceMap | string) {
constructor(id: string, code: string, inMap?: SourceMap | string) {
super()
this.filename = filename
this.filename = id
this.originalCode = code
if (inMap) {
if (debugSourcemapCombine) {
Expand All @@ -531,6 +543,11 @@ export async function createPluginContainer(
}
this.sourcemapChain.push(inMap)
}
// Inherit `_addedImports` from the `load()` hook
const node = moduleGraph?.getModuleById(id)
if (node) {
this._addedImports = moduleNodeToLoadAddedImports.get(node) ?? null
}
}

_getCombinedSourcemap() {
Expand Down Expand Up @@ -719,9 +736,11 @@ export async function createPluginContainer(
if (isObject(result)) {
updateModuleInfo(id, result)
}
updateModuleLoadAddedImports(id, ctx)
return result
}
}
updateModuleLoadAddedImports(id, ctx)
return null
},

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { expect, test } from 'vitest'
import { editFile, page, untilUpdated } from '~utils'

test('should re-run transform when plugin-dep file is edited', async () => {
test('should re-run transform when dependencies are edited', async () => {
expect(await page.textContent('#transform-count')).toBe('1')

await editFile('plugin-dep.js', (str) => str)
editFile('plugin-dep.js', (str) => str)
await untilUpdated(() => page.textContent('#transform-count'), '2')

editFile('plugin-dep-load.js', (str) => str)
await untilUpdated(() => page.textContent('#transform-count'), '3')
})
1 change: 1 addition & 0 deletions playground/transform-plugin/plugin-dep-load.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// Empty file for detecting changes in tests
9 changes: 8 additions & 1 deletion playground/transform-plugin/vite.config.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { resolve } from 'node:path'
import { defineConfig, normalizePath } from 'vite'

const file = normalizePath(resolve(__dirname, 'index.js'))
let transformCount = 1

const transformPlugin = {
name: 'transform',
load(id) {
if (id === file) {
// Ensure `index.js` is reloaded if 'plugin-dep-load.js' is changed
this.addWatchFile('./plugin-dep-load.js')
}
},
transform(code, id) {
if (id === normalizePath(resolve(__dirname, 'index.js'))) {
if (id === file) {
// Ensure `index.js` is reevaluated if 'plugin-dep.js' is changed
this.addWatchFile('./plugin-dep.js')

Expand Down

0 comments on commit b1a456c

Please sign in to comment.