[PR #120] [CLOSED] fix(routing): pass exclude as function to node:fs/promises.glob #327

Closed
opened 2026-05-06 12:39:13 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/120
Author: @harrisrobin
Created: 2/26/2026
Status: Closed

Base: mainHead: fix/glob-exclude-function


📝 Commits (3)

  • dd656fe chore: add .worktrees/ to .gitignore
  • bf3a90e fix(deploy): detect bun.lock text format and walk up to monorepo root
  • aceb83c fix(routing): pass exclude as function to node:fs/promises.glob

📊 Changes

5 files changed (+118 additions, -12 deletions)

View changed files

📝 .gitignore (+3 -0)
📝 packages/vinext/src/routing/app-router.ts (+7 -3)
📝 packages/vinext/src/routing/pages-router.ts (+7 -1)
📝 packages/vinext/src/utils/project.ts (+42 -8)
📝 tests/deploy.test.ts (+59 -0)

📄 Description

Problem

PR #52 migrated app-router.ts and pages-router.ts from the glob npm package to the Node.js built-in node:fs/promises.glob, but left array literals in the exclude option:

// app-router.ts
glob("**/page.{tsx,ts,jsx,js}", { cwd: appDir, exclude: ["**/@*"] })

// pages-router.ts
glob("**/*.{tsx,ts,jsx,js}", { cwd: pagesDir, exclude: ["api", "**/_*"] })

The Node.js glob API has always required exclude to be a function. Passing an array throws on Node.js v23:

TypeError: The "options.exclude" property must be of type function. Received an instance of Array
    at new Glob (node:internal/fs/glob:204:7)
    at appRouter (dist/routing/app-router.js:36:22)
    at Object.load (dist/index.js:1993:42)

This breaks vinext build and vinext deploy entirely for any project on Node.js v23.

Fix

Convert both array literals to equivalent predicate functions:

// app-router.ts — exclude parallel slot dirs (@slot)
const excludeSlots = (f: string) => path.basename(f).startsWith("@");

// pages-router.ts — exclude api/ dir and _-prefixed private files  
const excludePagesGlob = (f: string) => {
  const base = path.basename(f);
  return base === "api" || base.startsWith("_");
};

Behaviour is identical — @slot directories and _app/_document/etc. are still excluded from route scanning.

Verification

  • tests/app-router.test.ts — previously failing with the TypeError, now passes
  • tests/pages-router.test.ts — 269 tests passing
  • pnpm run typecheck and pnpm run lint clean

/bonk


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/120 **Author:** [@harrisrobin](https://github.com/harrisrobin) **Created:** 2/26/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/glob-exclude-function` --- ### 📝 Commits (3) - [`dd656fe`](https://github.com/cloudflare/vinext/commit/dd656fee5b07e59eb887614a43dd9069fae227f3) chore: add .worktrees/ to .gitignore - [`bf3a90e`](https://github.com/cloudflare/vinext/commit/bf3a90e2a9fcc488f00008c1a7943113172bb9df) fix(deploy): detect bun.lock text format and walk up to monorepo root - [`aceb83c`](https://github.com/cloudflare/vinext/commit/aceb83cb9822f976e7b9479bf9079919dd1d3e1f) fix(routing): pass exclude as function to node:fs/promises.glob ### 📊 Changes **5 files changed** (+118 additions, -12 deletions) <details> <summary>View changed files</summary> 📝 `.gitignore` (+3 -0) 📝 `packages/vinext/src/routing/app-router.ts` (+7 -3) 📝 `packages/vinext/src/routing/pages-router.ts` (+7 -1) 📝 `packages/vinext/src/utils/project.ts` (+42 -8) 📝 `tests/deploy.test.ts` (+59 -0) </details> ### 📄 Description ## Problem PR #52 migrated `app-router.ts` and `pages-router.ts` from the `glob` npm package to the Node.js built-in `node:fs/promises.glob`, but left array literals in the `exclude` option: ```ts // app-router.ts glob("**/page.{tsx,ts,jsx,js}", { cwd: appDir, exclude: ["**/@*"] }) // pages-router.ts glob("**/*.{tsx,ts,jsx,js}", { cwd: pagesDir, exclude: ["api", "**/_*"] }) ``` The Node.js `glob` API has always required `exclude` to be a **function**. Passing an array throws on Node.js v23: ``` TypeError: The "options.exclude" property must be of type function. Received an instance of Array at new Glob (node:internal/fs/glob:204:7) at appRouter (dist/routing/app-router.js:36:22) at Object.load (dist/index.js:1993:42) ``` This breaks `vinext build` and `vinext deploy` entirely for any project on Node.js v23. ## Fix Convert both array literals to equivalent predicate functions: ```ts // app-router.ts — exclude parallel slot dirs (@slot) const excludeSlots = (f: string) => path.basename(f).startsWith("@"); // pages-router.ts — exclude api/ dir and _-prefixed private files const excludePagesGlob = (f: string) => { const base = path.basename(f); return base === "api" || base.startsWith("_"); }; ``` Behaviour is identical — `@slot` directories and `_app`/`_document`/etc. are still excluded from route scanning. ## Verification - `tests/app-router.test.ts` — previously failing with the `TypeError`, now passes - `tests/pages-router.test.ts` — 269 tests passing - `pnpm run typecheck` and `pnpm run lint` clean /bonk --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 12:39:13 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#327
No description provided.