Skip to content

Commit

Permalink
feat: use Rolldown's watch API
Browse files Browse the repository at this point in the history
  • Loading branch information
sapphi-red committed Nov 18, 2024
1 parent f646104 commit 82412fc
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 60 deletions.
97 changes: 50 additions & 47 deletions packages/vite/src/node/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type {
RollupLog,
RollupOptions,
RollupOutput,
// RollupWatcher,
watch as rolldownWatch,
// WatcherOptions,
} from 'rolldown'
import {
Expand Down Expand Up @@ -65,7 +65,7 @@ import { findNearestPackageData } from './packages'
import type { PackageCache } from './packages'
import {
getResolvedOutDirs,
// resolveChokidarOptions,
resolveChokidarOptions,
resolveEmptyOutDir,
} from './watch'
import { completeSystemWrapPlugin } from './plugins/completeSystemWrap'
Expand All @@ -79,6 +79,9 @@ import {
import type { MinimalPluginContext, Plugin, PluginContext } from './plugin'
import type { RollupPluginHooks } from './typeUtils'

export type RollupWatcher = Awaited<ReturnType<typeof rolldownWatch>>
type WatcherOptions = { _: never }

export interface BuildEnvironmentOptions {
/**
* Compatibility transform target. The transform is performed with esbuild
Expand Down Expand Up @@ -272,7 +275,7 @@ export interface BuildEnvironmentOptions {
* https://rollupjs.org/configuration-options/#watch
* @default null
*/
// watch?: WatcherOptions | null
watch?: WatcherOptions | null
/**
* create the Build Environment instance
*/
Expand Down Expand Up @@ -536,7 +539,7 @@ export async function resolveBuildPlugins(config: ResolvedConfig): Promise<{
*/
export async function build(
inlineConfig: InlineConfig = {},
): Promise<RollupOutput | RollupOutput[] /* | RollupWatcher */> {
): Promise<RollupOutput | RollupOutput[] | RollupWatcher> {
const builder = await createBuilder(inlineConfig, true)
const environment = Object.values(builder.environments)[0]
if (!environment) throw new Error('No environment found')
Expand Down Expand Up @@ -564,7 +567,7 @@ function resolveConfigToBuild(
**/
async function buildEnvironment(
environment: BuildEnvironment,
): Promise<RollupOutput | RollupOutput[] /* | RollupWatcher */> {
): Promise<RollupOutput | RollupOutput[] | RollupWatcher> {
const { root, packageCache } = environment.config
const options = environment.config.build
const libOptions = options.lib
Expand Down Expand Up @@ -699,11 +702,11 @@ async function buildEnvironment(
}
}

// const outputBuildError = (e: RollupError) => {
// enhanceRollupError(e)
// clearLine()
// logger.error(e.message, { error: e })
// }
const outputBuildError = (e: RollupError) => {
enhanceRollupError(e)
clearLine()
logger.error(e.message, { error: e })
}

let bundle: RollupBuild | undefined
let startTime: number | undefined
Expand Down Expand Up @@ -806,42 +809,42 @@ async function buildEnvironment(
)

// watch file changes with rollup
// if (options.watch) {
// logger.info(colors.cyan(`\nwatching for file changes...`))

// const resolvedChokidarOptions = resolveChokidarOptions(
// options.watch.chokidar,
// resolvedOutDirs,
// emptyOutDir,
// environment.config.cacheDir,
// )

// const { watch } = await import('rolldown')
// const watcher = watch({
// ...rollupOptions,
// output: normalizedOutputs,
// watch: {
// ...options.watch,
// chokidar: resolvedChokidarOptions,
// },
// })

// watcher.on('event', (event) => {
// if (event.code === 'BUNDLE_START') {
// logger.info(colors.cyan(`\nbuild started...`))
// if (options.write) {
// prepareOutDir(resolvedOutDirs, emptyOutDir, environment)
// }
// } else if (event.code === 'BUNDLE_END') {
// event.result.close()
// logger.info(colors.cyan(`built in ${event.duration}ms.`))
// } else if (event.code === 'ERROR') {
// outputBuildError(event.error)
// }
// })

// return watcher
// }
if (options.watch) {
logger.info(colors.cyan(`\nwatching for file changes...`))

const resolvedChokidarOptions = resolveChokidarOptions(
{}, // options.watch.chokidar,
resolvedOutDirs,
emptyOutDir,
environment.config.cacheDir,
)

const { watch } = await import('rolldown')
const watcher = await watch({
...rollupOptions,
output: normalizedOutputs[0], // normalizedOutputs,
watch: {
...options.watch,
chokidar: resolvedChokidarOptions,
},
})

watcher.on('event', (event) => {
if (event.code === 'BUNDLE_START') {
logger.info(colors.cyan(`\nbuild started...`))
if (options.write) {
prepareOutDir(resolvedOutDirs, emptyOutDir, environment)
}
} else if (event.code === 'BUNDLE_END') {
// event.result.close()
logger.info(colors.cyan(`built in ${event.duration}ms.`))
} else if (event.code === 'ERROR') {
outputBuildError(event.error)
}
})

return watcher
}

// write or generate files with rollup
const { rolldown } = await import('rolldown')
Expand Down Expand Up @@ -1502,7 +1505,7 @@ export interface ViteBuilder {
buildApp(): Promise<void>
build(
environment: BuildEnvironment,
): Promise<RollupOutput | RollupOutput[] /* | RollupWatcher */>
): Promise<RollupOutput | RollupOutput[] | RollupWatcher>
}

export interface BuilderOptions {
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export { perEnvironmentPlugin } from './plugin'
export { perEnvironmentState } from './environment'
export { createServer } from './server'
export { preview } from './preview'
export { build, createBuilder } from './build'
export { build, createBuilder, type RollupWatcher } from './build'

export { optimizeDeps } from './optimizer'
export { createIdResolver } from './idResolver'
Expand Down
3 changes: 1 addition & 2 deletions playground/assets/__tests__/assets.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -550,8 +550,7 @@ test.runIf(isBuild)('manifest', async () => {
}
})

// TODO: rolldown does not support rebuild
describe.runIf(isBuild).skip('css and assets in css in build watch', () => {
describe.runIf(isBuild)('css and assets in css in build watch', () => {
test('css will not be lost and css does not contain undefined', async () => {
editFile('index.html', (code) => code.replace('Assets', 'assets'), true)
await notifyRebuildComplete(watcher)
Expand Down
25 changes: 15 additions & 10 deletions playground/vitestSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
Logger,
PluginOption,
ResolvedConfig,
RollupWatcher,
UserConfig,
ViteDevServer,
} from 'vite'
Expand All @@ -20,7 +21,7 @@ import {
preview,
} from 'vite'
import type { Browser, Page } from 'playwright-chromium'
import type { RollupError, RollupWatcher, RollupWatcherEvent } from 'rollup'
import type { RollupError, RollupWatcherEvent } from 'rollup'
import type { RunnerTestFile } from 'vitest'
import { beforeAll, inject } from 'vitest'

Expand Down Expand Up @@ -72,7 +73,7 @@ export let resolvedConfig: ResolvedConfig = undefined!
export let page: Page = undefined!
export let browser: Browser = undefined!
export let viteTestUrl: string = ''
export const watcher: RollupWatcher | undefined = undefined
export let watcher: RollupWatcher | undefined = undefined

export function setViteUrl(url: string): void {
viteTestUrl = url
Expand Down Expand Up @@ -273,13 +274,14 @@ export async function startDefaultServe(): Promise<void> {
const builder = await createBuilder(buildConfig)
await builder.buildApp()
} else {
/* const rollupOutput = */ await build(buildConfig)
// const isWatch = !!resolvedConfig!.build.watch
// // in build watch,call startStaticServer after the build is complete
// if (isWatch) {
// watcher = rollupOutput as RollupWatcher
// await notifyRebuildComplete(watcher)
// }
const rollupOutput = await build(buildConfig)
const isWatch = !!resolvedConfig!.build.watch
// in build watch,call startStaticServer after the build is complete
if (isWatch) {
watcher = rollupOutput as RollupWatcher
await notifyRebuildComplete(watcher)
await new Promise<void>((resolve) => setTimeout(resolve, 1000))
}
if (buildConfig.__test__) {
buildConfig.__test__()
}
Expand Down Expand Up @@ -315,7 +317,10 @@ export async function notifyRebuildComplete(
await new Promise<void>((resolve) => {
resolveFn = resolve
})
return watcher.off('event', callback)
// During tests we edit the files too fast and sometimes chokidar
// misses change events, so wait 100ms for consistency
await new Promise<void>((resolve) => setTimeout(resolve, 100))
return watcher // watcher.off('event', callback)
}

export function createInMemoryLogger(logs: string[]): Logger {
Expand Down

0 comments on commit 82412fc

Please sign in to comment.