Skip to content

Adopt Vite+ - #4028

Merged
nstepien merged 47 commits into
mainfrom
viteplus
Oct 5, 2026
Merged

nstepien merged 47 commits into
mainfrom
viteplus

Conversation

@nstepien

@nstepien nstepien commented Apr 2, 2026

Copy link
Copy Markdown
Collaborator

@nstepien nstepien self-assigned this Apr 2, 2026
@codecov-commenter

codecov-commenter commented Oct 3, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.30%. Comparing base (b786d20) to head (9ed48e7).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4028   +/-   ##
=======================================
  Coverage   98.30%   98.30%           
=======================================
  Files          45       45           
  Lines        1943     1944    +1     
  Branches      732      733    +1     
=======================================
+ Hits         1910     1911    +1     
  Misses         33       33           

see 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@nstepien
nstepien marked this pull request as ready for review October 4, 2026 23:40
@nstepien
nstepien requested a review from amanmahajan7 as a code owner October 4, 2026 23:40
@nstepien
nstepien merged commit 5c89257 into main Oct 5, 2026
5 checks passed
@nstepien
nstepien deleted the viteplus branch October 5, 2026 00:12

@amanmahajan7 amanmahajan7 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great. Anything noteworthy?

Comment thread .github/dependabot.yml
Comment on lines +15 to +16
- dependency-name: 'vitest'
- dependency-name: '@vitest/*'

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still install these packages separately?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vite-plus manages these dependencies via vp migrate, as vite-plus expects specific package versions.
I hope they'll make it simpler in the future, or hope they'll release an updater action.

Comment thread .vscode/settings.json
Comment on lines +26 to +27
"oxc.disableNestedConfig": true,
"oxc.fmt.disableNestedConfig": true

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need these?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was added by vp migrate
vp does not support nested configs

Comment thread package.json
Comment on lines +85 to +86
"allowScripts": {
"core-js": false

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this do?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disables core-js's install script (a donation plea), otherwise npm logs this:

npm warn install-scripts 1 package had install scripts blocked because they are not covered by allowScripts:
npm warn install-scripts   core-js@3.50.0 (postinstall: node -e "try{require('./postinstall')}catch(e){}")
npm warn install-scripts
npm warn install-scripts Run `npm install-scripts ls` to review, or `npm install-scripts approve <pkg>` to allow.

https://github.blog/changelog/2026-06-09-upcoming-breaking-changes-for-npm-v12/

Comment thread vite.config.ts
Comment on lines +65 to +68
staged: {
'*': 'vp fmt --no-error-on-unmatched-pattern',
'*.md': 'vp run eslint'
},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how do you like the pre commit hooks?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works great, essentially invisible since vp fmt is fast, and we rarely touch .md files.

Might have some conflicts if you have staged/unstaged blocks in the same file, but it stashes these unstaged changes while running the hooks.
Though it can lead to git conflicts, and fail to commit, but that's rare.

We could also use *': vp check --fixinstead ofvp fmt`, but that might be a bit too much?

I wonder if we should add more hooks.

Comment thread package.json
"lint:md": "eslint --max-warnings 0",
"lint:fix": "oxlint --fix && eslint --fix",
"typecheck": "tsc --build"
"prepare": "vp config"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only one command needed? nice!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well they're moved to tasks in vite.config.ts, so we can benefit from caching.
prepare runs after you run npm install/vp install.
I've added vp run ci (or vpr ci) so you can all the checks locally, just like in CI.

@nstepien

nstepien commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator Author

Anything noteworthy?

  • vp manages which node.js/npm version is used, so you don't have to worry about switching to an older branch or a different repository that expect different versions
    • this is controlled by devEngines in package.json in this repo
    • see vp env, vp env pin --help, vp env current, vp env doctor
    • vp will download the necessary node.js/npm version transparently when you use it
    • you'll need to configure your shell environment, vp should guide with that
  • vp should also work in repos that don't use vp
  • npm run */node --run * -> vp run * === vpr *
    • it handles both "tasks" in the vite config, and "scripts" in package.json
    • it handles arguments better, so npm run typecheck -- --watch -> vpr typecheck --watch, no need for the extra --
    • vp run args are passed before the task/script, like this: vp run --no-cache eslint/vpr --no-cache eslint, no confusion
    • tasks can have multiple commands
      • in that case, passing an arg is passed to the last command
      • so with the following, vpr mytask --arg will run a then b --arg.
        run: {
          tasks: {
            mytask: {
              command: ['a', 'b']
            },
          },
        },
      • tasks can have dependency tasks via dependsOn, which runs the dependencies in parallel
  • npx -> vpx
  • npm start -> vp dev
  • lazyPlugins avoids loading/initializing vite plugins in unrelated commands like vp fmt or vp check, but it does not work with pack's plugins, hope they fix it
  • I've merged the visual tests into the browser project to keep things simple
  • for actions

I'm sure there's even more stuff, but that's a good start 🙂

nstepien added a commit that referenced this pull request Oct 19, 2026
…ish on version tags, and harden workflows (#4211)

The Publish workflow ran `npm version` itself but could only push the
tag, as the default branch ruleset blocks its push to `main`, so the
`7.0.0-beta.61` version commit never landed on `main`. Now `npm version`
runs locally, and pushing the version commit and its tag runs the
workflow.

## How to release

```sh
vp run version <prerelease|patch|minor|major|x.y.z>
git push --atomic --no-follow-tags origin main "v$(npm pkg get version)"
```

- **The `version` task** in `vite.config.ts` runs `git switch main`,
`git fetch --prune --prune-tags origin`, which also deletes local tags
that aren't on GitHub, and `git reset --keep origin/main`, which moves
`main` to GitHub's and keeps uncommitted changes, which `npm version`
then refuses to run with. It stops at the first failure.
- **Versioning**: `vp run` appends the arguments to the task's last
command, `npm version`, which commits the new version and creates an
annotated `v<version>` tag. During the beta, use `prerelease` to go from
`7.0.0-beta.61` to `7.0.0-beta.62`, as `patch`, `minor`, and `major` all
produce `7.0.0`.
- **Pushing**: the push stays a separate command, as Vite Task doesn't
run commands through a shell on Windows, so `$(...)` doesn't work in a
task. Naming the tag makes the push fail if the tag is missing, and
`--no-follow-tags` leaves other local tags out, even with
`push.followTags` set. `--atomic` pushes `main` and the tag together, or
neither. With `--follow-tags`, a missing tag only pushes `main`, so
nothing is published.
- **A missing tag**: until it's pushed, any fetch that prunes tags
deletes the new tag, for example an editor's auto-fetch with
`fetch.pruneTags` enabled. If the push can't find the tag, recreate it,
then push again:
  ```sh
git tag --annotate "v$(npm pkg get version)" --message "$(npm pkg get
version)"
  ```

Only `nstepien` and `amanmahajan7` can push to `main` without a pull
request and create tags, so only they can release (see [Repository
settings](#repository-settings)). The same steps are in the header of
`publish.yml`. `vpr version` is short for `vp run version`, and the
commands work in both Bash and PowerShell.

## Changes

- **Publish runs on `v*` tags** instead of `workflow_dispatch`. Before
installing anything, it checks that the tagged commit is on `main` and
that the tag matches the version from `npm pkg get version`. Tags can't
be pushed twice, and `npm publish` rejects a version that already
exists.
- **Publish is split into three jobs.** In a job with `id-token: write`,
every step can request an OIDC token, so any dev dependency that `vp
install` or `vp run ci` ran could have published to npm as
react-data-grid.
- The read-only `build` job runs the checks and CI, and uploads `lib/`.
- The `publish` job (`id-token: write`) downloads `lib/` and publishes
it without installing the project's dependencies. It still sets up
Vite+, so `npm` is the version that `devEngines` asks for, and
`setup-vp` downloads the Vite+ install script when it runs. `npm publish
--ignore-scripts` skips the `prepare` script (`vp config`), so no
project code runs either.
- The `release` job (`contents: write`) creates the GitHub release with
`gh release create --verify-tag`, which fails instead of creating a tag
if the tag is missing. As a separate job, the job that can publish to
npm has no write token, and a failed release can be re-run on its own
once the version is already on npm.
  - Checkouts no longer persist credentials, as nothing is pushed.
- **Update Screenshots is split into three jobs**, for the same reason:
- `remove-label` (`pull-requests: write`) only runs gh, without checking
out the repository.
- `screenshots` (read-only) installs the dependencies, regenerates the
screenshots, and uploads them if they changed.
- `push` (`contents: write`) checks out the commit the screenshots were
taken on, swaps in the new ones, commits, and pushes. The push fails if
the branch moved since, as before. When nothing changed, this job is
skipped, so no job with write access runs.
- Only PNGs under `test/**/screenshots/`, at any depth, are handed from
`screenshots` to `push`, so the job that pushes can only commit images.
- **publint**: `vp pack` now lints the tarball that `npm pack
--ignore-scripts` produces, in strict mode, so warnings fail the build
like errors do. It reports no issues.
- **Breaking: `main`, `module`, `browser`, and `types` are removed**
from `package.json`, as `exports` covers every entry point. publint
suggested replacing `browser` with an `exports` condition. Tools that
ignore `exports` no longer resolve the package, like TypeScript's
`node10` module resolution (removed in TypeScript 7), webpack 4, and
Jest before 28.
- **`package.json` metadata**: `repository` uses the
`github:Comcast/react-data-grid` shorthand, and `homepage` and `bugs`
are removed, as npm derives all three when publishing.
`publishConfig.provenance` is enabled, which trusted publishing already
does, so publishing from outside CI fails by default (`npm publish
--no-provenance` overrides it). `npm publish` logs that it converted the
`repository` string to an object, which is expected.
- **`skipLibCheck`** is removed from `tsconfig.vite.json` and
`tsconfig.website.json`.
- **AGENTS.md** documents the workflow conventions, publint, and where
to find the release steps.

The Publish workflow's file name is unchanged, so npm's trusted
publisher config still matches.

## Repository settings

These changed in the repository settings alongside this PR, so they're
not in the diff.

- **Actions**: the default `GITHUB_TOKEN` is now read-only, and Actions
can no longer create or approve pull requests. Every workflow sets its
own `permissions`, so this doesn't affect them, only a workflow that
would omit them. "Require actions to be pinned to a full-length commit
SHA" was already on.
- **Rulesets**:
- **Default branch** requires a pull request with a code owner approval,
and the `test` and `CodeQL` checks. Only `nstepien` and `amanmahajan7`
can bypass it, to push the version commit to `main`. The Admin role's
bypass for pull requests is removed, so other admins need an approval
and passing checks to merge.
- **Default branch history** is new, with no bypass: nobody can delete
`main`, force-push it, or add merge commits. These rules moved out of
"Default branch", whose bypass would otherwise cover them.
- **Tag creation** is new: only `nstepien` and `amanmahajan7` can create
tags, so only they can start a release.
- **Tags** no longer has a bypass: nobody can delete, move, or
force-push a tag.
- **gh-pages** is unchanged, and the branch is kept as an archive, as
Pages deploys from the CI workflow since #4028.

## Verification

- `vp run ci` passes, and `vp run typecheck` passes without the cache.
- With a local bare remote, `npm version` created an annotated tag and
`git push --atomic --no-follow-tags origin main "v$(npm pkg get
version)"` pushed both, without another local tag on `main`, which
`--follow-tags` would have pushed too. With `push.followTags` set, the
same push without `--no-follow-tags` sent that other tag as well. After
a fetch with `fetch.pruneTags` deleted the new tag, the push failed and
pushed nothing, while `--follow-tags` pushed `main` alone. The recreated
tag matched the one `npm version` creates. The checks passed for the new
tag, and failed for a tag that doesn't match `package.json` and a tag
off `main`. With npm 12, `npm pkg get version` prints the bare version.
- In a scratch repository with a stand-in remote, `vp run version
prerelease` switched to `main`, deleted a local-only tag, reset `main`,
and created the `7.0.0-beta.62` commit and tag, which the push then
sent. The task stopped before `npm version` when `git reset --keep`
refused to overwrite a local change to a file that GitHub's `main` had
changed, and `npm version` refused to run with an uncommitted change. A
pre-commit hook running a cached `vp run` task worked inside the task.
- In npm 12's `@npmcli/package-json`, which `npm publish` uses to read
`package.json`, the `repository` shorthand is normalized to
`git+https://github.com/Comcast/react-data-grid.git`, the URL that
provenance is verified against, and `homepage` and `bugs` are derived
from it.
- In a fresh clone with only `lib/` and no `node_modules`, `npm publish
--dry-run --ignore-scripts` packed the 4 `lib/` files plus `LICENSE`,
`README.md`, and `package.json`. Without `--ignore-scripts`, it ran
`prepare`.
- With a local bare remote, the steps of the `push` job committed a
modified, a deleted, and an added screenshot, including in a directory
two levels below `test/`, and the push was rejected as non-fast-forward
when the PR branch had moved after the screenshots were taken. `gh auth
setup-git` hands `GH_TOKEN` to git. With the `*.png` pattern, a planted
`test/browser/screenshots/x.test.tsx/evil.test.tsx` was neither detected
as a change nor staged, while a new PNG in a new directory was.
- In gh 2.102.0's source, `gh release create --repo` skips its local git
lookups, and `--verify-tag` checks the tag through the API, so the
`release` job doesn't need a checkout.
- With planted `package.json` problems, a missing file (an error) and an
invalid `repository` (a warning) each fail `vp pack`, including in a
local run outside CI.
- A one-off zizmor run, not added to the repository, only reports
Dependabot's cooldown.

The next release will be Publish's first run. Update Screenshots runs a
PR's own workflow file, and its `remove-label` and `screenshots` jobs
passed on this PR. `push` was skipped, as no screenshot changed, so its
first run will be the next label that changes screenshots.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants