mirror of
https://github.com/stablyai/orca.git
synced 2026-10-07 16:02:29 +00:00
Reuse discovered mobile chunks during static traversal (#24774)
Iterate the existing live visited Set in FIFO discovery order instead of maintaining a second shifted queue; both actual callers own untouched esbuild JSON metadata.
This commit is contained in:
@@ -363,15 +363,12 @@ export function mobileWebAppBuildOptions(routes) {
|
||||
*/
|
||||
export function entryStaticClosure(metafile, entryOutputPath) {
|
||||
const reached = new Set([entryOutputPath])
|
||||
const queue = [entryOutputPath]
|
||||
while (queue.length > 0) {
|
||||
const current = queue.shift()
|
||||
for (const current of reached) {
|
||||
for (const imported of metafile.outputs[current]?.imports ?? []) {
|
||||
if (imported.kind !== 'import-statement' || reached.has(imported.path)) {
|
||||
continue
|
||||
}
|
||||
reached.add(imported.path)
|
||||
queue.push(imported.path)
|
||||
}
|
||||
}
|
||||
return reached
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
import { expect, it } from 'vitest'
|
||||
import { entryStaticClosure } from './build-mobile-web-app-bundle.mjs'
|
||||
|
||||
it.each([1, 12, 128, 1000])(
|
||||
'keeps the complete %s-output closure without shifting a second queue',
|
||||
(count) => {
|
||||
const paths = Array.from({ length: count }, (_value, index) => `dist/chunk-${index}.js`)
|
||||
const metafile = {
|
||||
outputs: Object.fromEntries(
|
||||
paths.map((path, index) => [
|
||||
path,
|
||||
{
|
||||
bytes: index + 1,
|
||||
imports:
|
||||
index === 0
|
||||
? paths.slice(1).map((child) => ({ kind: 'import-statement', path: child }))
|
||||
: []
|
||||
}
|
||||
])
|
||||
)
|
||||
}
|
||||
const before = structuredClone(metafile)
|
||||
const originalShift = Array.prototype.shift
|
||||
let reached
|
||||
let shifts = 0
|
||||
Array.prototype.shift = function () {
|
||||
shifts++
|
||||
return originalShift.call(this)
|
||||
}
|
||||
try {
|
||||
reached = entryStaticClosure(metafile, paths[0])
|
||||
} finally {
|
||||
Array.prototype.shift = originalShift
|
||||
}
|
||||
expect([...reached]).toEqual(paths)
|
||||
expect(metafile).toEqual(before)
|
||||
expect([...reached].reduce((total, path) => total + metafile.outputs[path].bytes, 0)).toBe(
|
||||
(count * (count + 1)) / 2
|
||||
)
|
||||
const fresh = entryStaticClosure(metafile, paths[0])
|
||||
expect(fresh).not.toBe(reached)
|
||||
reached.add('mutated-result')
|
||||
expect([...fresh]).toEqual(paths)
|
||||
expect(shifts).toBe(0)
|
||||
}
|
||||
)
|
||||
|
||||
it('keeps breadth-first order, duplicates, cycles, missing chunks and dynamic boundaries', () => {
|
||||
const metafile = {
|
||||
outputs: {
|
||||
entry: {
|
||||
imports: [
|
||||
{ kind: 'import-statement', path: 'one' },
|
||||
{ kind: 'dynamic-import', path: 'deferred' },
|
||||
{ kind: 'import-statement', path: 'two' },
|
||||
{ kind: 'import-statement', path: 'one' }
|
||||
]
|
||||
},
|
||||
one: { imports: [{ kind: 'import-statement', path: 'three' }] },
|
||||
two: {
|
||||
imports: [
|
||||
{ kind: 'import-statement', path: 'entry' },
|
||||
{ kind: 'import-statement', path: 'three' },
|
||||
{ kind: 'import-statement', path: 'missing' }
|
||||
]
|
||||
},
|
||||
three: { imports: [] },
|
||||
deferred: { imports: [{ kind: 'import-statement', path: 'deferred-child' }] }
|
||||
}
|
||||
}
|
||||
expect([...entryStaticClosure(metafile, 'entry')]).toEqual([
|
||||
'entry',
|
||||
'one',
|
||||
'two',
|
||||
'three',
|
||||
'missing'
|
||||
])
|
||||
metafile.outputs.one.imports.push({ kind: 'import-statement', path: 'fresh-😀' })
|
||||
expect([...entryStaticClosure(metafile, 'entry')]).toEqual([
|
||||
'entry',
|
||||
'one',
|
||||
'two',
|
||||
'three',
|
||||
'fresh-😀',
|
||||
'missing'
|
||||
])
|
||||
expect([...entryStaticClosure({ outputs: {} }, 'unknown')]).toEqual(['unknown'])
|
||||
})
|
||||
|
||||
it('keeps a later output error after earlier discoveries in the same order', () => {
|
||||
const error = new Error('later-output')
|
||||
const reads = []
|
||||
const outputs = {
|
||||
get entry() {
|
||||
reads.push('entry')
|
||||
return {
|
||||
imports: [
|
||||
{ kind: 'import-statement', path: 'one' },
|
||||
{ kind: 'import-statement', path: 'two' }
|
||||
]
|
||||
}
|
||||
},
|
||||
get one() {
|
||||
reads.push('one')
|
||||
return { imports: [{ kind: 'import-statement', path: 'three' }] }
|
||||
},
|
||||
get two() {
|
||||
reads.push('two')
|
||||
throw error
|
||||
}
|
||||
}
|
||||
let caught
|
||||
try {
|
||||
entryStaticClosure({ outputs }, 'entry')
|
||||
} catch (failure) {
|
||||
caught = failure
|
||||
}
|
||||
expect(caught).toBe(error)
|
||||
expect(reads).toEqual(['entry', 'one', 'two'])
|
||||
})
|
||||
Reference in New Issue
Block a user