| 62 | } |
| 63 | |
| 64 | export class BundledDev { |
| 65 | private _devEngine!: DevEngine |
| 66 | private initialBuildCompleted = false |
| 67 | private clients = new Clients() |
| 68 | private invalidateCalledModules = new Map< |
| 69 | NormalizedHotChannelClient, |
| 70 | Set<string> |
| 71 | >() |
| 72 | private debouncedFullReload = debounce(20, () => { |
| 73 | this.environment.hot.send({ type: 'full-reload', path: '*' }) |
| 74 | this.environment.logger.info(colors.green(`page reload`), { |
| 75 | timestamp: true, |
| 76 | }) |
| 77 | }) |
| 78 | |
| 79 | private fullReloadPending = false |
| 80 | |
| 81 | private lastBuildError: Error | null = null |
| 82 | |
| 83 | memoryFiles: MemoryFiles = new MemoryFiles() |
| 84 | |
| 85 | constructor(private environment: DevEnvironment) { |
| 86 | if (environment.name !== 'client') { |
| 87 | throw new Error( |
| 88 | 'currently full bundle mode is only available for client environment', |
| 89 | ) |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | private get devEngine(): DevEngine { |
| 94 | if (!this._devEngine) { |
| 95 | throw new Error(`dev engine was not yet initialized`) |
| 96 | } |
| 97 | return this._devEngine |
| 98 | } |
| 99 | |
| 100 | async listen(): Promise<void> { |
| 101 | debug?.('INITIAL: setup bundle options') |
| 102 | const rolldownOptions = await this.getRolldownOptions() |
| 103 | // NOTE: only single outputOptions is supported here |
| 104 | if ( |
| 105 | Array.isArray(rolldownOptions.output) && |
| 106 | rolldownOptions.output.length > 1 |
| 107 | ) { |
| 108 | throw new Error('multiple output options are not supported in dev mode') |
| 109 | } |
| 110 | const outputOptions = ( |
| 111 | Array.isArray(rolldownOptions.output) |
| 112 | ? rolldownOptions.output[0] |
| 113 | : rolldownOptions.output |
| 114 | )! |
| 115 | |
| 116 | this.environment.hot.on('vite:module-loaded', (payload, client) => { |
| 117 | this.clients.setupIfNeeded(client, payload.clientId) |
| 118 | this.devEngine.registerModules(payload.clientId, payload.modules) |
| 119 | }) |
| 120 | this.environment.hot.on('vite:client:connect', (_payload, client) => { |
| 121 | // Replay the cached build error to freshly connected clients. |