Skip to content

Commit afca02e

Browse files
authored
feat: always-fresh production tarballs + Nuxt DevTools production playground (#511)
1 parent 6c99273 commit afca02e

14 files changed

Lines changed: 335 additions & 82 deletions

File tree

eslint.config.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ export default antfu({
99
'plans',
1010
'e2e/fixtures/**/dist',
1111
'e2e/fixtures/**/.vite-devtools',
12-
// The production playground is a standalone workspace (its own
13-
// `pnpm-workspace.yaml`) that mirrors a real user install, so it uses plain
14-
// dependency specifiers rather than the repo catalog and stays out of the
15-
// repo-wide ESLint run.
12+
// The production playgrounds are standalone workspaces (their own
13+
// `pnpm-workspace.yaml`) that mirror a real user install, so they use
14+
// plain dependency specifiers rather than the repo catalog and stay out
15+
// of the repo-wide ESLint run.
1616
'playgrounds/production',
17+
'playgrounds/production-nuxt',
1718
// `packages/oxc` is DevTools for the Oxc toolchain and dogfoods its own
1819
// oxlint/oxfmt on itself, whose formatting (e.g. `arrowParens: "avoid"`)
1920
// conflicts with this shared antfu config, so it is linted by its own
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules
2+
dist
3+
.output
4+
.nuxt
5+
.tarballs
6+
pnpm-lock.yaml
7+
*.local
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Production Nuxt Playground
2+
3+
A **standalone pnpm workspace** running a **Nuxt 5** app with **Nuxt DevTools
4+
4**, whose internal Vite DevTools dependency is overridden to the **local
5+
built dist** — so you can test how Vite DevTools behaves when it's running as
6+
Nuxt DevTools' own engine, rather than mounted directly as a Vite plugin.
7+
8+
The playground at `playgrounds/production` installs `@vitejs/devtools`
9+
straight into a plain Vite app. This one exercises the other real-world
10+
integration path: Nuxt DevTools v4 (`@nuxt/devtools@^4.0.0-alpha.9`) depends
11+
directly on `@vitejs/devtools` and `@vitejs/devtools-kit`, so a Nuxt app with
12+
`devtools: { enabled: true }` gets Vite DevTools for free, through Nuxt
13+
DevTools.
14+
15+
Nuxt 5 isn't published to the `nuxt` package's stable dist-tags yet, so
16+
`package.json` pulls it from Nuxt's [nightly release
17+
channel](https://nuxt.com/docs/guide/going-further/nightly-release-channel)
18+
via the `npm:nuxt-nightly@5x` alias — the same channel Nuxt itself documents
19+
for trying the next major early. Nuxt DevTools 4 (`@nuxt/devtools@^4.0.0-alpha.9`)
20+
is already on its regular dist-tags as a pre-release, so it's installed
21+
directly with no alias needed.
22+
23+
## How it works
24+
25+
`scripts/pack-local.mjs` builds the monorepo and packs the six published
26+
Vite DevTools packages into `.tarballs/`, exactly like `playgrounds/production`
27+
(it shares the same `scripts/pack-devtools-tarballs.mjs` implementation).
28+
Every run wipes and repacks under stable, version-agnostic names, then
29+
installs with `--force`, so the install always reflects the tarballs that
30+
were just packed, never a stale previous build.
31+
32+
`pnpm-workspace.yaml` overrides `@vitejs/devtools`, `@vitejs/devtools-kit`,
33+
and every sibling package to those tarballs. Because `@nuxt/devtools` pulls
34+
those same two packages in as regular (non-`workspace:`) npm dependencies,
35+
the override reaches into Nuxt DevTools' own dependency tree and forces it to
36+
run on the exact Vite DevTools build under test here — not whatever version
37+
`@nuxt/devtools` has pinned on npm. Everything else (`nuxt`, `vue`,
38+
`@nuxt/devtools` itself, ...) resolves from the public registry, just like a
39+
real install.
40+
41+
Its own `pnpm-workspace.yaml` keeps it isolated from the monorepo above, so a
42+
`pnpm install` here builds an independent dependency tree with its own lockfile.
43+
44+
## Usage
45+
46+
From this directory:
47+
48+
```sh
49+
# Build the monorepo, pack the packages, and install them
50+
pnpm run setup
51+
52+
# Start the Nuxt dev server (Nuxt DevTools panel)
53+
pnpm dev
54+
55+
# Or produce a production build
56+
pnpm build
57+
```
58+
59+
To re-pack after changing package source without rebuilding untouched packages,
60+
`pnpm run setup` re-runs the turbo build (cached), repacks, and reinstalls. If
61+
you already have fresh `dist` output and only want to re-pack + reinstall:
62+
63+
```sh
64+
pnpm run setup:no-build
65+
```
66+
67+
## Layout
68+
69+
- `scripts/pack-local.mjs` — build + pack the published packages into `.tarballs/`, then install
70+
- `nuxt.config.ts` — a plain user config with `devtools: { enabled: true }`
71+
- `app/app.vue` — a minimal Nuxt app so the panels have real build/module data
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script setup lang="ts">
2+
import { ref } from 'vue'
3+
4+
const count = ref(0)
5+
</script>
6+
7+
<template>
8+
<main>
9+
<h1>Vite DevTools — Production Nuxt Playground</h1>
10+
<p>
11+
This app installs Nuxt with Nuxt DevTools from npm, inside a standalone
12+
pnpm workspace, with Nuxt DevTools' internal <code>@vitejs/devtools</code>
13+
and <code>@vitejs/devtools-kit</code> dependencies overridden to the
14+
local built dist — testing Vite DevTools the way it actually ships,
15+
running as Nuxt DevTools' own engine.
16+
</p>
17+
<button type="button" @click="count++">
18+
count is {{ count }}
19+
</button>
20+
</main>
21+
</template>
22+
23+
<style scoped>
24+
main {
25+
max-width: 42rem;
26+
margin: 4rem auto;
27+
padding: 0 1rem;
28+
font-family: system-ui, sans-serif;
29+
line-height: 1.6;
30+
}
31+
button {
32+
padding: 0.5rem 1rem;
33+
border-radius: 0.5rem;
34+
border: 1px solid currentColor;
35+
cursor: pointer;
36+
}
37+
</style>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { defineNuxtConfig } from 'nuxt/config'
2+
3+
// This config is intentionally written the way a real user would write it:
4+
// enabling Nuxt DevTools is the only integration point needed. Nuxt DevTools
5+
// v4 (`@nuxt/devtools`, overridden here to resolve its internal Vite DevTools
6+
// dependency from the local built dist — see `pnpm-workspace.yaml`) embeds
7+
// Vite DevTools as its own engine, so there's no separate `@vitejs/devtools`
8+
// Vite plugin to add by hand.
9+
export default defineNuxtConfig({
10+
compatibilityDate: '2024-11-01',
11+
devtools: { enabled: true },
12+
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "playground-production-nuxt",
3+
"type": "module",
4+
"version": "0.4.11",
5+
"private": true,
6+
"description": "Standalone workspace that installs a Nuxt 5 app with Nuxt DevTools 4 from npm, overriding its internal Vite DevTools dependency to the local built dist, to test the real Nuxt-DevTools-embeds-Vite-DevTools install path.",
7+
"scripts": {
8+
"setup": "node scripts/pack-local.mjs",
9+
"setup:no-build": "node scripts/pack-local.mjs --no-build",
10+
"dev": "nuxt dev --host 0.0.0.0",
11+
"build": "nuxt build",
12+
"preview": "nuxt preview"
13+
},
14+
"dependencies": {
15+
"nuxt": "npm:nuxt-nightly@5x",
16+
"vue": "^3.5.39"
17+
},
18+
"devDependencies": {
19+
"@nuxt/devtools": "^4.0.0-alpha.9"
20+
}
21+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Standalone workspace root.
2+
#
3+
# This file exists so pnpm treats `playgrounds/production-nuxt` as its own,
4+
# self-contained project instead of a member of the monorepo above it.
5+
#
6+
# Nuxt DevTools v4 (`@nuxt/devtools@^4.0.0-alpha.9`) embeds Vite DevTools: it
7+
# depends directly on `@vitejs/devtools` and `@vitejs/devtools-kit` as its own
8+
# engine. These overrides redirect that internal dependency — and every other
9+
# Vite DevTools package — to the local built dist tarballs produced by
10+
# `scripts/pack-local.mjs`, so Nuxt DevTools always runs on the exact Vite
11+
# DevTools build under test here rather than whatever version `@nuxt/devtools`
12+
# has pinned on npm. Everything else (nuxt, vue, ...) resolves from the public
13+
# registry — exactly what a real user gets.
14+
packages: []
15+
16+
overrides:
17+
'@vitejs/devtools': 'file:.tarballs/vitejs-devtools.tgz'
18+
'@vitejs/devtools-kit': 'file:.tarballs/vitejs-devtools-kit.tgz'
19+
'@vitejs/devtools-rolldown': 'file:.tarballs/vitejs-devtools-rolldown.tgz'
20+
'@vitejs/devtools-vite': 'file:.tarballs/vitejs-devtools-vite.tgz'
21+
'@vitejs/devtools-vitest': 'file:.tarballs/vitejs-devtools-vitest.tgz'
22+
'@vitejs/devtools-oxc': 'file:.tarballs/vitejs-devtools-oxc.tgz'
23+
24+
verifyDepsBeforeRun: false
25+
allowBuilds:
26+
esbuild: true
27+
rolldown: true
28+
unrs-resolver: true
29+
minimumReleaseAge: 0
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// @ts-check
2+
/**
3+
* Build the Vite DevTools packages, pack them into local tarballs, and
4+
* install this playground from them — the same artifacts that would be
5+
* published to npm. Nuxt DevTools v4 (`@nuxt/devtools`) depends directly on
6+
* `@vitejs/devtools` and `@vitejs/devtools-kit`; `pnpm-workspace.yaml`
7+
* overrides those (and every other Vite DevTools package) to these tarballs,
8+
* so Nuxt DevTools runs on the build under test here.
9+
*
10+
* Every run wipes `.tarballs/` and repacks from scratch, then reinstalls with
11+
* `--force` so pnpm never mistakes a freshly rebuilt tarball (same stable
12+
* filename, new content) for the previous stale install.
13+
*
14+
* Usage:
15+
* node scripts/pack-local.mjs # build the monorepo, pack, install
16+
* node scripts/pack-local.mjs --no-build # skip the build, just (re)pack + install
17+
*/
18+
import { dirname, join, resolve } from 'node:path'
19+
import process from 'node:process'
20+
import { fileURLToPath } from 'node:url'
21+
import { packDevToolsTarballs, run } from '../../../scripts/pack-devtools-tarballs.mjs'
22+
23+
const scriptDir = dirname(fileURLToPath(import.meta.url))
24+
const playgroundDir = resolve(scriptDir, '..')
25+
const repoRoot = resolve(playgroundDir, '../..')
26+
const tarballDir = join(playgroundDir, '.tarballs')
27+
28+
const skipBuild = process.argv.includes('--no-build')
29+
30+
packDevToolsTarballs({ repoRoot, tarballDir, skipBuild })
31+
32+
// `--force` bypasses pnpm's content-addressable store cache, guaranteeing the
33+
// install always reflects the tarballs that were just packed above.
34+
run('pnpm install --no-frozen-lockfile --force', playgroundDir)
35+
36+
console.log('\nDone. Run `pnpm dev` to start the playground.')
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "./.nuxt/tsconfig.json"
3+
}

playgrounds/production/README.md

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ and the `dist` output.
1212

1313
## How it works
1414

15-
`scripts/pack-local.mjs` builds the monorepo and runs `pnpm pack` on the five
15+
`scripts/pack-local.mjs` builds the monorepo and runs `pnpm pack` on the six
1616
published packages (`@vitejs/devtools`, `-kit`, `-rolldown`, `-vite`,
17-
`-vitest`). `pnpm pack` rewrites each package's `workspace:*` and `catalog:*`
18-
protocols into concrete versions, producing the exact tarballs npm would serve.
19-
The tarballs land in `.tarballs/` under stable names; `pnpm-workspace.yaml`
20-
points `@vitejs/devtools` and every inter-package dependency at them through
21-
`overrides`. Everything else (devframe, `@devframes/*`, vite, vue) resolves
22-
from the public registry — just like a real install.
17+
`-vitest`, `-oxc`). `pnpm pack` rewrites each package's `workspace:*` and
18+
`catalog:*` protocols into concrete versions, producing the exact tarballs npm
19+
would serve. Every run wipes `.tarballs/` and repacks from scratch under
20+
stable, version-agnostic names, then installs the playground with `--force`
21+
so the install always reflects the tarballs that were just packed, never a
22+
stale previous build. `pnpm-workspace.yaml` points `@vitejs/devtools` and
23+
every inter-package dependency at those tarballs through `overrides`.
24+
Everything else (devframe, `@devframes/*`, vite, vue) resolves from the public
25+
registry — just like a real install.
2326

2427
Its own `pnpm-workspace.yaml` keeps it isolated from the monorepo above, so a
2528
`pnpm install` here builds an independent dependency tree with its own lockfile.
@@ -40,21 +43,15 @@ pnpm build
4043
```
4144

4245
To re-pack after changing package source without rebuilding untouched packages,
43-
`pnpm run setup` re-runs the turbo build (cached) and re-packs. If you already
44-
have fresh `dist` output and only want to re-pack + reinstall:
46+
`pnpm run setup` re-runs the turbo build (cached), repacks, and reinstalls. If
47+
you already have fresh `dist` output and only want to re-pack + reinstall:
4548

4649
```sh
4750
pnpm run setup:no-build
4851
```
4952

50-
If pnpm doesn't pick up freshly re-packed tarballs, force it:
51-
52-
```sh
53-
pnpm install --no-frozen-lockfile --force
54-
```
55-
5653
## Layout
5754

58-
- `scripts/pack-local.mjs` — build + pack the published packages into `.tarballs/`
55+
- `scripts/pack-local.mjs` — build + pack the published packages into `.tarballs/`, then install
5956
- `vite.config.ts` — a plain user config importing `DevTools` from `@vitejs/devtools`
6057
- `src/` — a minimal Vue app so the panels have real build/module data

0 commit comments

Comments
 (0)