Migrate d3_graph_generator from react-scripts (CRA) to Vite#112
Merged
Conversation
Create React App is officially deprecated upstream (facebook/create-react-app README: "now in long-term stasis... we do not recommend starting production apps based on Create React App") and react-scripts hasn't been released since April 2022. Its frozen webpack/babel/eslint toolchain is the entire reason d3_graph_generator kept accumulating Dependabot alerts on packages several levels deep in the tree (postcss, webpack-dev-server, minimatch, js-yaml, ajv, ...) that Dependabot can't bump directly and that needed hand-maintained yarn `resolutions` overrides to patch. Replacing it with Vite removes that entire dependency subtree outright (node_modules: ~800+ packages -> 59; yarn.lock: ~2000 -> 620 lines) instead of continuing to patch it package-by-package. Changes: - package.json: drop react-scripts and its transitive baggage, plus @observablehq/stdlib, web-vitals, and @testing-library/* (all confirmed unused - no test files exist, no reportWebVitals call, no stdlib import). Add vite + @vitejs/plugin-react. eslintConfig/browserslist blocks removed since they configured react-scripts' bundled tooling specifically. - vite.config.js: new, configures the React plugin, keeps dev server on port 3000 (matching the documented workflow) and build output in `build/` (matching the existing .gitignore entry). - index.html: moved from public/ to the project root per Vite convention. Dropped the stale, insecure `http://d3js.org/d3.v3.min.js` CDN script tag - the app only ever uses the npm-installed d3@7 via ESM imports, so this was dead, unused, mixed-content markup. Replaced %PUBLIC_URL% templating with root-relative paths and added the module entry script tag. - src/index.js -> src/index.jsx: renamed so esbuild's default JSX loader picks it up (it's the only source file with JSX in a .js extension; the other components were already .jsx). No content changes. Verified locally: `yarn install` (zero peer-dependency warnings, versus several with react-scripts), `yarn build`, and both `yarn dev` and `yarn preview` actually serving working HTML/JS/CSS (curled and checked response codes, not just that the build produced files).
This was referenced Jul 24, 2026
dduugg
added a commit
that referenced
this pull request
Jul 25, 2026
* Fix missing-workflow-permissions alerts and integrate zizmor Resolves 6 of the 7 open code scanning alerts (https://github.com/rubyatscale/visualize_packs/security/code-scanning), all actions/missing-workflow-permissions findings on workflows that had no explicit permissions block and so defaulted to the repository's token permissions: - ci.yml: root-level `contents: read` (checkout + bundle exec only, across all three jobs) - cd.yml: `contents: write` on the shared-config caller job - the called reusable workflow pushes a release tag (discourse/publish-rubygems-action) and creates a GitHub release (`gh release create`), both of which need contents:write - stale.yml: `issues: write` + `pull-requests: write` - required by actions/stale to label/close stale issues and PRs - triage.yml: `issues: write` - the called reusable workflow's own `label_issues` job requires this from the caller The 7th alert (js/functionality-from-untrusted-source, the insecure `http://d3js.org/d3.v3.min.js` CDN script tag in d3_graph_generator/public/index.html) is already fixed on the open Vite migration branch (#112) via removing that dead script tag entirely; it isn't duplicated here since that PR deletes the file this alert points at. Also adds .github/workflows/zizmor.yml, copied from shared-config's existing zizmor integration (the org's canonical pattern - this is the first repo to adopt it). Running it locally against this repo's own workflows surfaced additional real findings beyond CodeQL's actions coverage, all fixed here so the new job starts green instead of red: - unpinned `actions/checkout@v4` / `ruby/setup-ruby@v1` in ci.yml - pinned to SHA (matching the convention already used in codeql.yml) - missing `persist-credentials: false` on checkout steps in ci.yml and codeql.yml - stale/incorrect version comments on already-pinned SHAs in ci.yml, codeql.yml, and the copied zizmor.yml - e.g. a SHA commented "# v6" that's actually tagged v7.0.0 today (floating major tags move), and "# v3.37.3" on a SHA that's actually v4.37.3 (a leftover from an earlier find-and-replace pass across the org). Caught by zizmor's ref-version-mismatch audit in online mode (--gh-token), not offline. - three findings suppressed with `# zizmor: ignore[...]` comments for patterns that are deliberate, org-wide conventions rather than bugs: workflow_run-triggered CD (dangerous-triggers), unpinned @main references to shared-config's own reusable workflows (unpinned-uses - pinning these would defeat the point of centralizing them, since shared-config updates wouldn't propagate), and secrets: inherit on the cd.yml caller (secrets-inherit - matches shared-config's own precedent for this exact pattern). Verified with `zizmor .github/workflows/` locally, both offline and with --gh-token (online mode catches the ref-version-mismatch findings that offline mode misses): 0 findings, all ignores/suppressions resolving correctly. * Group GitHub Actions dependabot updates into a single monthly PR Matches the existing bundler grouping in this same file: one PR a month for all github-actions bumps together, instead of a separate PR per action. Especially relevant now that this PR pins several actions to a SHA (actions/checkout, ruby/setup-ruby, github/codeql-action, zizmorcore/zizmor-action) for the first time, which is what makes them trackable by dependabot's github-actions ecosystem in the first place. * Add cooldown to dependabot config, fixing zizmor's new alert The new zizmor.yml added earlier in this PR caught its own dependabot-cooldown finding on the github-actions entry this PR just added (alert #11), and the same check flags the pre-existing bundler entry too - it just never ran against this repo before since zizmor.yml didn't exist until this PR. Fixed both with zizmor --fix=safe, matching shared-config's own dependabot.yml convention (cooldown: default-days: 7).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Create React App is officially deprecated upstream — facebook/create-react-app's README now says "Create React App... is now in long-term stasis... we do not recommend starting production apps based on Create React App" — and
react-scriptshasn't been released since April 2022. Its frozen webpack/babel/eslint toolchain is the entire reasond3_graph_generatorkept accumulating Dependabot alerts on packages several levels deep in the tree (postcss,webpack-dev-server,minimatch,js-yaml,ajv, ...) that Dependabot can't bump directly, and that needed hand-maintainedyarn resolutionsoverrides to patch (see #111).This replaces
react-scriptswith Vite, removing that entire dependency subtree outright instead of continuing to patch it package-by-package.Verified impact (measured against an actual install of the pre-migration commit, not estimated):
node_modules: 848 packages → 59yarn.lock: 9,791 lines → 620yarn audit: 199 vulnerabilities (2 critical / 125 high / 56 moderate / 16 low) → 0Changes
package.json: dropreact-scriptsand its transitive baggage, plus@observablehq/stdlib,web-vitals, and@testing-library/*(all confirmed unused — no test files exist, noreportWebVitalscall, nostdlibimport anywhere insrc/). Addvite+@vitejs/plugin-react. TheeslintConfig/browserslistblocks are removed since they configuredreact-scripts' bundled tooling specifically.vite.config.js(new): configures the React plugin, keeps the dev server on port 3000 (matching the documented workflow) and build output inbuild/(matching the existing.gitignoreentry).index.html: moved frompublic/to the project root per Vite convention. Dropped the stale, insecurehttp://d3js.org/d3.v3.min.jsCDN script tag — the app only ever uses the npm-installedd3@7via ESM imports (import * as d3 from "d3"inbuildGraph.js), so this was dead, unused, mixed-content markup, not a functional dependency. Replaced%PUBLIC_URL%templating with root-relative paths and added the module entry script tag.src/index.js→src/index.jsx: renamed so esbuild's default JSX loader picks it up (it's the only source file with JSX in a.jsextension; the other components were already.jsx). No content changes — confirmed byte-identical aside from the rename.README.md:yarn start→yarn install(first time) +yarn dev.No application source files (
App.jsx,ForceGraph.jsx,NodeDetails.jsx,buildGraph.js,index.css) were touched.d3_graph_generatorhas no coupling to the rest of the Ruby gem or to CI — nothing else in the repo references its build output, filenames, or manifest.Test plan
Verified independently (fresh clones, not just re-running my own working directory):
yarn install— zero errors, zero peer-dependency warnings (the old CRA tree had several)yarn build— succeeds in ~280ms, emitsbuild/index.html+ hashed JS/CSS assets + copiedpublic/assetsyarn preview— servedindex.html, the JS bundle, the CSS bundle, and/manifest.json, all HTTP 200 with real (non-empty, non-error) contentyarn dev— serves on port 3000 as configured/documented,/and/src/index.jsxboth HTTP 200ruby parse_packwerk_integration.rbagainst a real repo, thenyarn dev) — nothing in this migration should change runtime behavior, but I don't have a way to visually confirm the rendered force graph from this environment