({ outputDir }: { outputDir: string })
| 83 | } |
| 84 | |
| 85 | async function prerenderPages({ outputDir }: { outputDir: string }) { |
| 86 | const seen = new Set<string>() |
| 87 | const prerendered = new Set<string>() |
| 88 | const retriesByPath = new Map<string, number>() |
| 89 | const concurrency = startConfig.prerender?.concurrency ?? os.cpus().length |
| 90 | logger.info(`Concurrency: ${concurrency}`) |
| 91 | const queue = new Queue({ concurrency }) |
| 92 | const routerBasePath = joinURL('/', startConfig.router.basepath ?? '') |
| 93 | const routerBaseUrl = new URL(routerBasePath, 'http://localhost') |
| 94 | |
| 95 | startConfig.pages = validateAndNormalizePrerenderPages( |
| 96 | startConfig.pages, |
| 97 | routerBaseUrl, |
| 98 | ) |
| 99 | |
| 100 | startConfig.pages.forEach((page) => addCrawlPageTask(page)) |
| 101 | |
| 102 | if (queue.isSettled()) { |
| 103 | logger.info('No pages matched prerender filter; skipping.') |
| 104 | return Array.from(prerendered) |
| 105 | } |
| 106 | |
| 107 | await queue.start() |
| 108 | |
| 109 | return Array.from(prerendered) |
| 110 | |
| 111 | function addCrawlPageTask(page: Page) { |
| 112 | if (seen.has(page.path)) return |
| 113 | |
| 114 | seen.add(page.path) |
| 115 | |
| 116 | if (page.fromCrawl) { |
| 117 | startConfig.pages.push(page) |
| 118 | } |
| 119 | |
| 120 | if (!(page.prerender?.enabled ?? true)) return |
| 121 | |
| 122 | if ( |
| 123 | startConfig.prerender?.filter && |
| 124 | !startConfig.prerender.filter(page) |
| 125 | ) { |
| 126 | return |
| 127 | } |
| 128 | |
| 129 | const prerenderOptions = { |
| 130 | ...startConfig.prerender, |
| 131 | ...page.prerender, |
| 132 | } |
| 133 | |
| 134 | queue.add(async () => { |
| 135 | logger.info(`Crawling: ${page.path}`) |
| 136 | const retries = retriesByPath.get(page.path) || 0 |
| 137 | |
| 138 | try { |
| 139 | const res = await requestWithRedirects( |
| 140 | withTrailingSlash(withBase(page.path, routerBasePath)), |
| 141 | { |
| 142 | headers: { |
no test coverage detected