Skip to content

Commit fd8b2cc

Browse files
authored
feat: add @netlify/vite-plugin-tanstack-start (#455)
* feat: add `@netlify/vite-plugin-tanstack-start` This adds a framework-agnostic Vite build plugin that prepares a Vite app for deployment to Netlify. It expects that the Vite app has an `ssr` environment (and no other server environments to deploy) that has exactly one bundle entry and that this entry is a server request entry point, a module with a default export containing a Web Fetch handler under the `fetch` property. TanStack Start meets all these conditions. This build plugin can be opted into via the intentionally private, undocumented `build.enabled` option, passed into `@netlify/vite-plugin`. This also adds a new `@netlify/vite-plugin-tanstack-start` which just wraps `@netlify/vite-plugin` with this enabled. At the moment, this only supports TanStack Start `alpha`, but this will be released imminently (presumably v.1.132 or so). As such, it inherits its requirements: - Vite 7+ - Node.js 22.12.0+ * chore: try a longer hook timeout * refactor: remove unnecessary internal dep * fix(docs): fix incorrect options in readme * fix(types): add clearer private callout * chore: fix potential e2e deploy helper issue * ci: try even higher timeout for Windows * chore: try npm for e2e fixture install pnpm seems to be problematic on Windows CI... * fix: revert vite plugin type fix for now We'll do this in a separate PR to be safe. * chore: actually use npm correctly in deploy helper. follow-up to d117f25 You can't use `overrides` for a direct dependency unless the values are identical... * fix: handle duplicate instances of our plugin Because we now have framework-specific plugins that load our generic plugin, we should make sure nothing bad happens if a user also includes our generic plugin directly. I went down a few different paths here and this ended up seeming like the best approach: just warn when we detect multiple instances in dev. Build is tricky because by design our plugin will be instantiated once per environment (e.g. client + ssr). And it ends up generally not being a problem if it's duplicated in build anyway, just dev. * chore: better error logging for failed e2e deploy * chore: fix e2e deploy bug * chore: actually bump e2e timeout math is hard * chore: improve e2e deploy logging * chore: try even higher Windows e2e timeout * test: skip tanstack plugin Windows tests for now also fix technically incorrect node version check
1 parent 967f6ec commit fd8b2cc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+2240
-40
lines changed

.github/workflows/release-please.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,17 @@ jobs:
209209
fi
210210
env:
211211
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
212+
- if:
213+
${{ steps.release.outputs['packages/vite-plugin-tanstack-start--release_created'] || github.event_name ==
214+
'workflow_dispatch' }}
215+
run: |
216+
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
217+
npm publish packages/vite-plugin-tanstack-start/ --provenance --access=public || true
218+
else
219+
npm publish packages/vite-plugin-tanstack-start/ --provenance --access=public
220+
fi
221+
env:
222+
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
212223
- if: ${{ steps.release.outputs['packages/otel--release_created'] || github.event_name == 'workflow_dispatch' }}
213224
run: |
214225
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then

.github/workflows/test.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ jobs:
5757
run: npm run build --workspaces=true
5858
- name: Tests
5959
run: npm run test --workspaces=true
60+
env:
61+
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
6062
test-node18:
6163
name: Test Node.js 18 for specific packages
6264
runs-on: ${{ matrix.os }}

.prettierignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.circleci
22
dist
33
coverage
4-
CHANGELOG.md
4+
CHANGELOG.md
5+
**/fixtures/*

.release-please-manifest.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@
1515
"packages/runtime-utils": "2.1.0",
1616
"packages/static": "3.0.10",
1717
"packages/types": "2.0.3",
18-
"packages/vite-plugin": "2.5.10"
18+
"packages/vite-plugin": "2.5.10",
19+
"packages/vite-plugin-tanstack-start": "0.0.0"
1920
}

README.md

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,22 @@ npm run dev
2727

2828
## Packages
2929

30-
| Name | Description | Version |
31-
| --------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
32-
| 🤖 [@netlify/ai](packages/ai) | TypeScript utilities for interacting with Netlify AI features | [![npm version](https://img.shields.io/npm/v/@netlify/ai.svg)](https://www.npmjs.com/package/@netlify/ai) |
33-
| 🗄️ [@netlify/blobs](packages/blobs) | TypeScript client for Netlify Blobs | [![npm version](https://img.shields.io/npm/v/@netlify/blobs.svg)](https://www.npmjs.com/package/@netlify/blobs) |
34-
| 💾 [@netlify/cache](packages/cache) | TypeScript utilities for interacting with the Netlify cache | [![npm version](https://img.shields.io/npm/v/@netlify/cache.svg)](https://www.npmjs.com/package/@netlify/cache) |
35-
| 🛠️ [@netlify/dev](packages/dev) | Emulation of the Netlify environment for local development | [![npm version](https://img.shields.io/npm/v/@netlify/dev.svg)](https://www.npmjs.com/package/@netlify/dev) |
36-
| 🔧 [@netlify/dev-utils](packages/dev-utils) | TypeScript utilities for the local emulation of the Netlify environment | [![npm version](https://img.shields.io/npm/v/@netlify/dev-utils.svg)](https://www.npmjs.com/package/@netlify/dev-utils) |
37-
|[@netlify/functions](packages/functions) | TypeScript utilities for interacting with Netlify Functions | [![npm version](https://img.shields.io/npm/v/@netlify/functions.svg)](https://www.npmjs.com/package/@netlify/functions) |
38-
| 📋 [@netlify/headers](packages/headers) | TypeScript implementation of Netlify's headers engine | [![npm version](https://img.shields.io/npm/v/@netlify/headers.svg)](https://www.npmjs.com/package/@netlify/headers) |
39-
| 🖼️ [@netlify/images](packages/images) | TypeScript utilities for interacting with Netlify Image CDN | [![npm version](https://img.shields.io/npm/v/@netlify/images.svg)](https://www.npmjs.com/package/@netlify/images) |
40-
| 🚀 [@netlify/nuxt](packages/nuxt-module) | Nuxt module with a local emulation of the Netlify environment | [![npm version](https://img.shields.io/npm/v/@netlify/nuxt.svg)](https://www.npmjs.com/package/@netlify/nuxt) |
41-
| 🔍 [@netlify/otel](packages/otel) | TypeScript utilities to interact with Netlify's OpenTelemetry | [![npm version](https://img.shields.io/npm/v/@netlify/otel.svg)](https://www.npmjs.com/package/@netlify/otel) |
42-
| 🔄 [@netlify/redirects](packages/redirects) | TypeScript implementation of Netlify's rewrites and redirects engine | [![npm version](https://img.shields.io/npm/v/@netlify/redirects.svg)](https://www.npmjs.com/package/@netlify/redirects) |
43-
| 🏛️ [@netlify/runtime](packages/runtime) | Netlify compute runtime | [![npm version](https://img.shields.io/npm/v/@netlify/runtime.svg)](https://www.npmjs.com/package/@netlify/runtime) |
44-
| 🔨 [@netlify/runtime-utils](packages/runtime-utils) | Cross-environment utilities for the Netlify runtime | [![npm version](https://img.shields.io/npm/v/@netlify/runtime-utils.svg)](https://www.npmjs.com/package/@netlify/runtime-utils) |
45-
| 📁 [@netlify/static](packages/static) | TypeScript implementation of Netlify's static file serving logic | [![npm version](https://img.shields.io/npm/v/@netlify/static.svg)](https://www.npmjs.com/package/@netlify/static) |
46-
| 🔢 [@netlify/types](packages/types) | TypeScript types for Netlify platform primitives | [![npm version](https://img.shields.io/npm/v/@netlify/types.svg)](https://www.npmjs.com/package/@netlify/types) |
47-
| 🔌 [@netlify/vite-plugin](packages/vite-plugin) | Vite plugin with a local emulation of the Netlify environment | [![npm version](https://img.shields.io/npm/v/@netlify/vite-plugin.svg)](https://www.npmjs.com/package/@netlify/vite-plugin) |
30+
| Name | Description | Version |
31+
| ----------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
32+
| 🤖 [@netlify/ai](packages/ai) | TypeScript utilities for interacting with Netlify AI features | [![npm version](https://img.shields.io/npm/v/@netlify/ai.svg)](https://www.npmjs.com/package/@netlify/ai) |
33+
| 🗄️ [@netlify/blobs](packages/blobs) | TypeScript client for Netlify Blobs | [![npm version](https://img.shields.io/npm/v/@netlify/blobs.svg)](https://www.npmjs.com/package/@netlify/blobs) |
34+
| 💾 [@netlify/cache](packages/cache) | TypeScript utilities for interacting with the Netlify cache | [![npm version](https://img.shields.io/npm/v/@netlify/cache.svg)](https://www.npmjs.com/package/@netlify/cache) |
35+
| 🛠️ [@netlify/dev](packages/dev) | Emulation of the Netlify environment for local development | [![npm version](https://img.shields.io/npm/v/@netlify/dev.svg)](https://www.npmjs.com/package/@netlify/dev) |
36+
| 🔧 [@netlify/dev-utils](packages/dev-utils) | TypeScript utilities for the local emulation of the Netlify environment | [![npm version](https://img.shields.io/npm/v/@netlify/dev-utils.svg)](https://www.npmjs.com/package/@netlify/dev-utils) |
37+
|[@netlify/functions](packages/functions) | TypeScript utilities for interacting with Netlify Functions | [![npm version](https://img.shields.io/npm/v/@netlify/functions.svg)](https://www.npmjs.com/package/@netlify/functions) |
38+
| 📋 [@netlify/headers](packages/headers) | TypeScript implementation of Netlify's headers engine | [![npm version](https://img.shields.io/npm/v/@netlify/headers.svg)](https://www.npmjs.com/package/@netlify/headers) |
39+
| 🖼️ [@netlify/images](packages/images) | TypeScript utilities for interacting with Netlify Image CDN | [![npm version](https://img.shields.io/npm/v/@netlify/images.svg)](https://www.npmjs.com/package/@netlify/images) |
40+
| 🚀 [@netlify/nuxt](packages/nuxt-module) | Nuxt module with a local emulation of the Netlify environment | [![npm version](https://img.shields.io/npm/v/@netlify/nuxt.svg)](https://www.npmjs.com/package/@netlify/nuxt) |
41+
| 🔍 [@netlify/otel](packages/otel) | TypeScript utilities to interact with Netlify's OpenTelemetry | [![npm version](https://img.shields.io/npm/v/@netlify/otel.svg)](https://www.npmjs.com/package/@netlify/otel) |
42+
| 🔄 [@netlify/redirects](packages/redirects) | TypeScript implementation of Netlify's rewrites and redirects engine | [![npm version](https://img.shields.io/npm/v/@netlify/redirects.svg)](https://www.npmjs.com/package/@netlify/redirects) |
43+
| 🏛️ [@netlify/runtime](packages/runtime) | Netlify compute runtime | [![npm version](https://img.shields.io/npm/v/@netlify/runtime.svg)](https://www.npmjs.com/package/@netlify/runtime) |
44+
| 🔨 [@netlify/runtime-utils](packages/runtime-utils) | Cross-environment utilities for the Netlify runtime | [![npm version](https://img.shields.io/npm/v/@netlify/runtime-utils.svg)](https://www.npmjs.com/package/@netlify/runtime-utils) |
45+
| 📁 [@netlify/static](packages/static) | TypeScript implementation of Netlify's static file serving logic | [![npm version](https://img.shields.io/npm/v/@netlify/static.svg)](https://www.npmjs.com/package/@netlify/static) |
46+
| 🔢 [@netlify/types](packages/types) | TypeScript types for Netlify platform primitives | [![npm version](https://img.shields.io/npm/v/@netlify/types.svg)](https://www.npmjs.com/package/@netlify/types) |
47+
| 🔌 [@netlify/vite-plugin](packages/vite-plugin) | Vite plugin with a local emulation of the Netlify environment | [![npm version](https://img.shields.io/npm/v/@netlify/vite-plugin.svg)](https://www.npmjs.com/package/@netlify/vite-plugin) |
48+
| 🔌 [@netlify/vite-plugin-tanstack-start](packages/vite-plugin-tanstack-start) | Vite plugin for TanStack Start on Netlify | [![npm version](https://img.shields.io/npm/v/@netlify/vite-plugin.svg)](https://www.npmjs.com/package/@netlify/vite-plugin-tanstack-start) |

eslint.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ export default tseslint.config(
2222
// Global rules and configuration
2323
includeIgnoreFile(path.resolve(__dirname, '.gitignore')),
2424
...packageIgnores,
25+
{
26+
ignores: ['**/fixtures/*'],
27+
},
2528
{
2629
// Uses its own eslint setup
2730
ignores: ['packages/nuxt-module/'],

package-lock.json

Lines changed: 114 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"packages/ai",
2020
"packages/nuxt-module",
2121
"packages/vite-plugin",
22+
"packages/vite-plugin-tanstack-start",
2223
"packages/otel"
2324
],
2425
"version": "0.0.0",

packages/dev-utils/src/lib/logger.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ export const netlifyCommand = ansis.cyanBright
1313
export const netlifyCyan = ansis.rgb(40, 180, 170)
1414

1515
export const netlifyBanner = netlifyCyan('⬥ Netlify')
16+
17+
export const warning = (message: string): string => ansis.yellow(`⚠ Warning: ${message}`)

packages/dev-utils/src/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export { headers, toMultiValueHeaders } from './lib/headers.js'
88
export { getGlobalConfigStore, GlobalConfigStore, resetConfigCache } from './lib/global-config.js'
99
export { Handler } from './lib/handler.js'
1010
export { LocalState } from './lib/local-state.js'
11-
export { type Logger, netlifyCommand, netlifyCyan, netlifyBanner } from './lib/logger.js'
11+
export { type Logger, netlifyCommand, netlifyCyan, netlifyBanner, warning } from './lib/logger.js'
1212
export { memoize, MemoizeCache } from './lib/memoize.js'
1313
export { killProcess, type ProcessRef } from './lib/process.js'
1414
export { HTTPServer } from './server/http_server.js'

0 commit comments

Comments
 (0)