mirror of
https://github.com/pestphp/pest.git
synced 2026-06-05 02:52:12 +02:00
wip
This commit is contained in:
@ -10,6 +10,7 @@ const PAGE_EXTENSIONS = new Set(['.vue', '.tsx', '.jsx', '.svelte'])
|
|||||||
const PROJECT_ROOT = resolve(process.argv[2] ?? process.cwd())
|
const PROJECT_ROOT = resolve(process.argv[2] ?? process.cwd())
|
||||||
const PAGES_REL = (process.env.TIA_VITE_PAGES_DIR ?? 'resources/js/Pages').replace(/\\/g, '/')
|
const PAGES_REL = (process.env.TIA_VITE_PAGES_DIR ?? 'resources/js/Pages').replace(/\\/g, '/')
|
||||||
const TIMEOUT_MS = Number.parseInt(process.env.TIA_VITE_TIMEOUT_MS ?? '20000', 10)
|
const TIMEOUT_MS = Number.parseInt(process.env.TIA_VITE_TIMEOUT_MS ?? '20000', 10)
|
||||||
|
const CONCURRENCY = Math.max(1, Number.parseInt(process.env.TIA_VITE_CONCURRENCY ?? '16', 10))
|
||||||
|
|
||||||
async function loadVite() {
|
async function loadVite() {
|
||||||
const projectRequire = createRequire(join(PROJECT_ROOT, 'package.json'))
|
const projectRequire = createRequire(join(PROJECT_ROOT, 'package.json'))
|
||||||
@ -77,42 +78,70 @@ async function main() {
|
|||||||
pageComponentCache.set(page, componentNameFor(page, pagesDir))
|
pageComponentCache.set(page, componentNameFor(page, pagesDir))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const projectRootPosix = PROJECT_ROOT.split(sep).join('/')
|
||||||
|
const pageEntries = pages.map((pagePath) => ({
|
||||||
|
pagePath,
|
||||||
|
pageComponent: pageComponentCache.get(pagePath),
|
||||||
|
pageUrl: '/' + posix.relative(projectRootPosix, pagePath.split(sep).join('/')),
|
||||||
|
}))
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (const pagePath of pages) {
|
let cursor = 0
|
||||||
const pageComponent = pageComponentCache.get(pagePath)
|
const workers = Array.from({ length: Math.min(CONCURRENCY, pageEntries.length) }, async () => {
|
||||||
const pageUrl = '/' + posix.relative(
|
while (true) {
|
||||||
PROJECT_ROOT.split(sep).join('/'),
|
const i = cursor++
|
||||||
pagePath.split(sep).join('/'),
|
if (i >= pageEntries.length) return
|
||||||
)
|
const { pageUrl } = pageEntries[i]
|
||||||
|
try {
|
||||||
try {
|
await server.transformRequest(pageUrl, { ssr: false })
|
||||||
await server.transformRequest(pageUrl, { ssr: false })
|
} catch {
|
||||||
} catch {
|
// ignore, handled below when we look up the module
|
||||||
continue
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
await Promise.all(workers)
|
||||||
|
|
||||||
|
const transitiveCache = new Map()
|
||||||
|
const computeTransitive = (mod, stack) => {
|
||||||
|
const key = mod.file ?? mod.id
|
||||||
|
if (!key) return null
|
||||||
|
const cached = transitiveCache.get(key)
|
||||||
|
if (cached) return cached
|
||||||
|
if (stack.has(key)) return null // cycle: let the originating frame fold us in
|
||||||
|
|
||||||
|
stack.add(key)
|
||||||
|
const acc = new Set()
|
||||||
|
for (const imported of mod.importedModules) {
|
||||||
|
const id = imported.file ?? imported.id
|
||||||
|
if (!id) continue
|
||||||
|
if (id.startsWith('\0')) continue
|
||||||
|
|
||||||
|
if (id.startsWith(PROJECT_ROOT)) {
|
||||||
|
const rel = relative(PROJECT_ROOT, id).split(sep).join('/')
|
||||||
|
acc.add(rel)
|
||||||
|
}
|
||||||
|
|
||||||
|
const childKey = id
|
||||||
|
if (stack.has(childKey)) continue
|
||||||
|
const child = computeTransitive(imported, stack)
|
||||||
|
if (child) for (const r of child) acc.add(r)
|
||||||
|
}
|
||||||
|
stack.delete(key)
|
||||||
|
transitiveCache.set(key, acc)
|
||||||
|
return acc
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const { pageComponent, pageUrl } of pageEntries) {
|
||||||
const pageModule = await server.moduleGraph.getModuleByUrl(pageUrl, false)
|
const pageModule = await server.moduleGraph.getModuleByUrl(pageUrl, false)
|
||||||
if (!pageModule) continue
|
if (!pageModule) continue
|
||||||
|
|
||||||
const visited = new Set()
|
const reachable = computeTransitive(pageModule, new Set())
|
||||||
const queue = [pageModule]
|
if (!reachable) continue
|
||||||
while (queue.length) {
|
|
||||||
const mod = queue.shift()
|
|
||||||
for (const imported of mod.importedModules) {
|
|
||||||
const id = imported.file ?? imported.id
|
|
||||||
if (!id || visited.has(id)) continue
|
|
||||||
visited.add(id)
|
|
||||||
|
|
||||||
if (id.startsWith('\0')) continue
|
for (const rel of reachable) {
|
||||||
if (!id.startsWith(PROJECT_ROOT)) continue
|
const bucket = reverse.get(rel) ?? new Set()
|
||||||
|
bucket.add(pageComponent)
|
||||||
const rel = relative(PROJECT_ROOT, id).split(sep).join('/')
|
reverse.set(rel, bucket)
|
||||||
const bucket = reverse.get(rel) ?? new Set()
|
|
||||||
bucket.add(pageComponent)
|
|
||||||
reverse.set(rel, bucket)
|
|
||||||
|
|
||||||
queue.push(imported)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
"php": "^8.3.0",
|
"php": "^8.3.0",
|
||||||
"brianium/paratest": "^7.20.0",
|
"brianium/paratest": "^7.20.0",
|
||||||
"composer/xdebug-handler": "^3.0.5",
|
"composer/xdebug-handler": "^3.0.5",
|
||||||
|
"fidry/cpu-core-counter": "^1.3",
|
||||||
"nunomaduro/collision": "^8.9.4",
|
"nunomaduro/collision": "^8.9.4",
|
||||||
"nunomaduro/termwind": "^2.4.0",
|
"nunomaduro/termwind": "^2.4.0",
|
||||||
"pestphp/pest-plugin": "^4.0.0",
|
"pestphp/pest-plugin": "^4.0.0",
|
||||||
|
|||||||
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Pest\Plugins\Tia;
|
namespace Pest\Plugins\Tia;
|
||||||
|
|
||||||
|
use Pest\Support\Cpu;
|
||||||
use Symfony\Component\Process\ExecutableFinder;
|
use Symfony\Component\Process\ExecutableFinder;
|
||||||
use Symfony\Component\Process\Process;
|
use Symfony\Component\Process\Process;
|
||||||
|
|
||||||
@ -166,7 +167,7 @@ final class JsModuleGraph
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$env = [];
|
$env = ['TIA_VITE_CONCURRENCY' => (string) max(4, min(32, Cpu::cores() * 2))];
|
||||||
foreach (['resources/js/Pages', 'resources/js/pages'] as $candidate) {
|
foreach (['resources/js/Pages', 'resources/js/pages'] as $candidate) {
|
||||||
if (is_dir($projectRoot.DIRECTORY_SEPARATOR.$candidate)) {
|
if (is_dir($projectRoot.DIRECTORY_SEPARATOR.$candidate)) {
|
||||||
$env['TIA_VITE_PAGES_DIR'] = $candidate;
|
$env['TIA_VITE_PAGES_DIR'] = $candidate;
|
||||||
|
|||||||
18
src/Support/Cpu.php
Normal file
18
src/Support/Cpu.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\Support;
|
||||||
|
|
||||||
|
use Fidry\CpuCoreCounter\CpuCoreCounter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class Cpu
|
||||||
|
{
|
||||||
|
public static function cores(int $fallback = 4): int
|
||||||
|
{
|
||||||
|
return (new CpuCoreCounter)->getCountWithFallback($fallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user