Skip to content

Commit 31f8b51

Browse files
authoredApr 17, 2023
refactor: simplify crawlEndFinder (#12868)
1 parent 1510996 commit 31f8b51

File tree

3 files changed

+39
-59
lines changed

3 files changed

+39
-59
lines changed
 

‎packages/vite/src/node/optimizer/optimizer.ts

+30-59
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ async function createDepsOptimizer(
711711
}
712712
}
713713

714-
const runOptimizerIfIdleAfterMs = 50
714+
const callCrawlEndIfIdleAfterMs = 50
715715

716716
interface CrawlEndFinder {
717717
ensureFirstRun: () => void
@@ -721,18 +721,17 @@ interface CrawlEndFinder {
721721
}
722722

723723
function setupOnCrawlEnd(onCrawlEnd: () => void): CrawlEndFinder {
724-
let registeredIds: { id: string; done: () => Promise<any> }[] = []
724+
const registeredIds = new Set<string>()
725725
const seenIds = new Set<string>()
726726
const workersSources = new Set<string>()
727-
const waitingOn = new Map<string, () => void>()
728-
let firstRunEnsured = false
729-
let crawlEndCalled = false
727+
let timeoutHandle: NodeJS.Timeout | undefined
730728

731729
let cancelled = false
732730
function cancel() {
733731
cancelled = true
734732
}
735733

734+
let crawlEndCalled = false
736735
function callOnCrawlEnd() {
737736
if (!cancelled && !crawlEndCalled) {
738737
crawlEndCalled = true
@@ -743,84 +742,56 @@ function setupOnCrawlEnd(onCrawlEnd: () => void): CrawlEndFinder {
743742
// If all the inputs are dependencies, we aren't going to get any
744743
// delayDepsOptimizerUntil(id) calls. We need to guard against this
745744
// by forcing a rerun if no deps have been registered
745+
let firstRunEnsured = false
746746
function ensureFirstRun() {
747747
if (!firstRunEnsured && seenIds.size === 0) {
748748
setTimeout(() => {
749749
if (seenIds.size === 0) {
750750
callOnCrawlEnd()
751751
}
752-
}, runOptimizerIfIdleAfterMs)
752+
}, 200)
753753
}
754754
firstRunEnsured = true
755755
}
756756

757757
function registerWorkersSource(id: string): void {
758758
workersSources.add(id)
759+
759760
// Avoid waiting for this id, as it may be blocked by the rollup
760761
// bundling process of the worker that also depends on the optimizer
761-
registeredIds = registeredIds.filter((registered) => registered.id !== id)
762+
registeredIds.delete(id)
762763

763-
const resolve = waitingOn.get(id)
764-
// Forced resolve to avoid waiting for the bundling of the worker to finish
765-
resolve?.()
764+
checkIfCrawlEndAfterTimeout()
766765
}
767766

768767
function delayDepsOptimizerUntil(id: string, done: () => Promise<any>): void {
769768
if (!seenIds.has(id)) {
770769
seenIds.add(id)
771-
registeredIds.push({ id, done })
772-
callOnCrawlEndWhenIdle()
770+
if (!workersSources.has(id)) {
771+
registeredIds.add(id)
772+
done()
773+
.catch(() => {})
774+
.finally(() => markIdAsDone(id))
775+
}
773776
}
774777
}
778+
function markIdAsDone(id: string): void {
779+
registeredIds.delete(id)
780+
checkIfCrawlEndAfterTimeout()
781+
}
775782

776-
async function callOnCrawlEndWhenIdle() {
777-
if (cancelled || waitingOn.size > 0) return
778-
779-
const processingRegisteredIds = registeredIds
780-
registeredIds = []
781-
782-
const donePromises = processingRegisteredIds.map(async (registeredId) => {
783-
// During build, we need to cancel workers
784-
let resolve: () => void
785-
const waitUntilDone = new Promise<void>((_resolve) => {
786-
resolve = _resolve
787-
registeredId
788-
.done()
789-
.catch(() => {
790-
// Ignore errors
791-
})
792-
.finally(() => resolve())
793-
})
794-
waitingOn.set(registeredId.id, () => resolve())
795-
796-
await waitUntilDone
797-
waitingOn.delete(registeredId.id)
798-
})
799-
800-
const afterLoad = () => {
801-
if (cancelled) return
802-
if (
803-
registeredIds.length > 0 &&
804-
registeredIds.every((registeredId) =>
805-
workersSources.has(registeredId.id),
806-
)
807-
) {
808-
return
809-
}
810-
811-
if (registeredIds.length > 0) {
812-
callOnCrawlEndWhenIdle()
813-
} else {
814-
callOnCrawlEnd()
815-
}
816-
}
783+
function checkIfCrawlEndAfterTimeout() {
784+
if (cancelled || registeredIds.size > 0) return
817785

818-
await Promise.allSettled(donePromises)
819-
if (registeredIds.length > 0) {
820-
afterLoad()
821-
} else {
822-
setTimeout(afterLoad, runOptimizerIfIdleAfterMs)
823-
}
786+
if (timeoutHandle) clearTimeout(timeoutHandle)
787+
timeoutHandle = setTimeout(
788+
callOnCrawlEndWhenIdle,
789+
callCrawlEndIfIdleAfterMs,
790+
)
791+
}
792+
async function callOnCrawlEndWhenIdle() {
793+
if (cancelled || registeredIds.size > 0) return
794+
callOnCrawlEnd()
824795
}
825796

826797
return {

‎packages/vite/src/node/plugins/optimizedDeps.ts

+1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ export function optimizedDepsBuildPlugin(config: ResolvedConfig): Plugin {
110110
depsOptimizer.delayDepsOptimizerUntil(resolved.id, async () => {
111111
await this.load(resolved)
112112
})
113+
return resolved
113114
}
114115
}
115116
},

‎playground/optimize-deps/__tests__/optimize-deps.spec.ts

+8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
isBuild,
77
isServe,
88
page,
9+
serverLogs,
910
viteTestUrl,
1011
} from '~utils'
1112

@@ -214,3 +215,10 @@ test('pre bundle css require', async () => {
214215

215216
expect(await getColor('.css-require')).toBe('red')
216217
})
218+
219+
test.runIf(isBuild)('no missing deps during build', async () => {
220+
serverLogs.forEach((log) => {
221+
// no warning from esbuild css minifier
222+
expect(log).not.toMatch('Missing dependency found after crawling ended')
223+
})
224+
})

0 commit comments

Comments
 (0)
Please sign in to comment.