mirror of
https://github.com/pestphp/pest.git
synced 2026-06-05 02:52:12 +02:00
wip
This commit is contained in:
@ -1,32 +1,5 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
/**
|
|
||||||
* TIA Vite dependency resolver.
|
|
||||||
*
|
|
||||||
* Spins up a throwaway headless Vite dev server using the project's
|
|
||||||
* `vite.config.*`, walks every `resources/js/Pages/**` entry to warm
|
|
||||||
* up the module graph, then serializes the graph as a reverse map:
|
|
||||||
*
|
|
||||||
* { "<abs source path>": ["<page component name>", ...], ... }
|
|
||||||
*
|
|
||||||
* The resulting JSON is written to stdout. Stderr is silent on
|
|
||||||
* success so Pest can parse stdout without stripping.
|
|
||||||
*
|
|
||||||
* Why this exists: at TIA record time we need to know which Inertia
|
|
||||||
* page components depend on each shared source file (Button.vue,
|
|
||||||
* Layouts/*.vue, etc.) so a later edit to one of those files can
|
|
||||||
* invalidate only the tests that rendered an affected page. Vite
|
|
||||||
* already knows this via its module graph — we borrow it.
|
|
||||||
*
|
|
||||||
* Called from `Pest\Plugins\Tia\JsModuleGraph::build()` as:
|
|
||||||
*
|
|
||||||
* node bin/pest-tia-vite-deps.mjs <absoluteProjectRoot>
|
|
||||||
*
|
|
||||||
* Environment:
|
|
||||||
* TIA_VITE_PAGES_DIR override the `resources/js/Pages` default.
|
|
||||||
* TIA_VITE_TIMEOUT_MS override the 20s internal watchdog.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { readdir } from 'node:fs/promises'
|
import { readdir } from 'node:fs/promises'
|
||||||
import { existsSync } from 'node:fs'
|
import { existsSync } from 'node:fs'
|
||||||
import { createRequire } from 'node:module'
|
import { createRequire } from 'node:module'
|
||||||
@ -38,11 +11,6 @@ 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)
|
||||||
|
|
||||||
// Resolve Vite from the project's own `node_modules`, not from this
|
|
||||||
// helper's location (which lives under `vendor/pestphp/pest/bin/` and
|
|
||||||
// has no `node_modules`). `createRequire` anchored at the project
|
|
||||||
// root walks up from there, matching the resolution behaviour any
|
|
||||||
// project-local script would see.
|
|
||||||
async function loadVite() {
|
async function loadVite() {
|
||||||
const projectRequire = createRequire(join(PROJECT_ROOT, 'package.json'))
|
const projectRequire = createRequire(join(PROJECT_ROOT, 'package.json'))
|
||||||
const vitePath = projectRequire.resolve('vite')
|
const vitePath = projectRequire.resolve('vite')
|
||||||
@ -84,9 +52,6 @@ async function main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Boot Vite in middleware mode (no port binding, no HMR server).
|
|
||||||
// We only need the module graph; transformRequest per page warms
|
|
||||||
// it without running a bundle.
|
|
||||||
const server = await createServer({
|
const server = await createServer({
|
||||||
configFile: undefined, // auto-detect vite.config.*
|
configFile: undefined, // auto-detect vite.config.*
|
||||||
root: PROJECT_ROOT,
|
root: PROJECT_ROOT,
|
||||||
@ -101,12 +66,10 @@ async function main() {
|
|||||||
optimizeDeps: { disabled: true },
|
optimizeDeps: { disabled: true },
|
||||||
})
|
})
|
||||||
|
|
||||||
// Watchdog — don't let a pathological config hang the record run.
|
|
||||||
const killer = setTimeout(() => {
|
const killer = setTimeout(() => {
|
||||||
server.close().catch(() => {}).finally(() => process.exit(2))
|
server.close().catch(() => {}).finally(() => process.exit(2))
|
||||||
}, TIMEOUT_MS)
|
}, TIMEOUT_MS)
|
||||||
|
|
||||||
// Reverse map: depSourcePath → Set<component name>.
|
|
||||||
const reverse = new Map()
|
const reverse = new Map()
|
||||||
|
|
||||||
const pageComponentCache = new Map()
|
const pageComponentCache = new Map()
|
||||||
@ -125,15 +88,12 @@ async function main() {
|
|||||||
try {
|
try {
|
||||||
await server.transformRequest(pageUrl, { ssr: false })
|
await server.transformRequest(pageUrl, { ssr: false })
|
||||||
} catch {
|
} catch {
|
||||||
// Transform errors (missing deps, syntax issues) shouldn't
|
|
||||||
// poison the whole graph — skip this page and continue.
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const pageModule = await server.moduleGraph.getModuleByUrl(pageUrl, false)
|
const pageModule = await server.moduleGraph.getModuleByUrl(pageUrl, false)
|
||||||
if (!pageModule) continue
|
if (!pageModule) continue
|
||||||
|
|
||||||
// BFS over importedModules, scoped to files inside the project.
|
|
||||||
const visited = new Set()
|
const visited = new Set()
|
||||||
const queue = [pageModule]
|
const queue = [pageModule]
|
||||||
while (queue.length) {
|
while (queue.length) {
|
||||||
@ -143,8 +103,6 @@ async function main() {
|
|||||||
if (!id || visited.has(id)) continue
|
if (!id || visited.has(id)) continue
|
||||||
visited.add(id)
|
visited.add(id)
|
||||||
|
|
||||||
// Skip files outside the project root (node_modules, etc.)
|
|
||||||
// and virtual modules (`\0`-prefixed ids from plugins).
|
|
||||||
if (id.startsWith('\0')) continue
|
if (id.startsWith('\0')) continue
|
||||||
if (!id.startsWith(PROJECT_ROOT)) continue
|
if (!id.startsWith(PROJECT_ROOT)) continue
|
||||||
|
|
||||||
@ -172,8 +130,7 @@ async function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Node 20 dynamic-import path — some environments are pickier than others.
|
void pathToFileURL
|
||||||
void pathToFileURL // retained to silence tree-shakers referencing the import
|
|
||||||
await main()
|
await main()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
process.stderr.write(String(err?.stack ?? err ?? 'unknown error'))
|
process.stderr.write(String(err?.stack ?? err ?? 'unknown error'))
|
||||||
|
|||||||
Reference in New Issue
Block a user