Uh oh!
There was an error while loading. Please reload this page.
Upgrade the misc toolchain: Style Dictionary 5, cssnano 8, sass, js-yaml 5, npm-run-all2 9 - #2422
Merged
Conversation
The only call site is `yaml.load` in the svgToTwig gulp task, reading `.svgo.yml`. All 72 generated `.svg.twig` files are byte-identical.
Requires Node ^22.22.2 || ^24.15.0 || >=26, satisfied by the 24.19.0 in `.nvmrc` and CI. All `run-s`/`run-p` globs still expand, including the nested `lint:*:check` pattern.
`dist/standalone.css` and `standalone.min.css` are byte-identical.
Changes `dist/standalone.min.css`. Every difference was accounted for against the unminified stylesheet, which is byte-identical: - Inline SVG data URIs are percent-encoded more thoroughly (spaces, quotes, `=`, `:`, `/`). They decode identically. - 23 of 25 inline SVGs regain the `viewBox` the source SVGs declare. The older bundled SVGO stripped it via `removeViewBox`, which is why that plugin left `preset-default` upstream. - A trailing `Z` is dropped from 9 paths, all fill-only, where it is a no-op. - Path coordinates round slightly: 0 structural changes, largest delta 0.05 user units. - `columns: N` and `border: … solid currentColor` now survive as authored; cssnano 5 rewrote them to `column-count` and dropped `currentColor`. - Custom property values are no longer minified, which is the safer reading of an arbitrary token stream. Rendered old and new in Chromium: 11 of 250,000 pixels differ, max channel delta 6/255, and the new output is closer to the unminified reference than the old one was. Raw size +3.2kB, but only +227 bytes gzipped.
Style Dictionary 4 was a rewrite, so this is a migration rather than a bump.
The package is ESM-only, hence the rename to `.mjs`, matching
`eslint.config.mjs` and `.storybook/main.mjs`.
API moves: `.extend(config)` becomes `new StyleDictionary(config)` with an
awaited `buildAllPlatforms()`; `transformer`/`formatter` become
`transform`/`format`; formats receive `{ dictionary }` and read `allTokens`
and `tokens` rather than `allProperties` and `properties`; and the built-in
`name/cti/kebab` is now `name/kebab`.
Two changes were needed beyond renaming:
- References drop the `.value` suffix, so all 25 of them across seven token
files become e.g. `{color.base.blue}`. Broken references are also an error
rather than a warning now, which is what surfaced these — and is why the
config no longer needs `log: 'warn'`.
- `color/css` no longer applies. Its filter used to match our CTI
`attributes.category`, but now requires an explicit `type: 'color'` that
our tokens do not declare, so colors would have passed through exactly as
authored (`#3d84F5`, `#000`, `rgba(0, 0, 0, 0.60)`). Re-registered as
`custom/value/color/css` with the category filter.
`name/kebab` also switched from lodash to change-case, which does not split
letter/digit boundaries. That is a no-op here: it emits `size-n1` directly
instead of the `size-n-1` that `custom/name/i/kebab-rejoin-n` existed to
repair, and the regex simply finds nothing.
Output: all 15 SCSS files and `tokens.json` are byte-identical apart from the
header, which loses its build timestamp and so is now deterministic. `dist`
is unchanged in full. The two JS token files gain a `key` field on each leaf
token — group nodes are unaffected, so the `Object.keys` in embed's story
still yields only the aspect ratios — and 40 `original.value` entries record
the new reference syntax. No resolved value changed anywhere.Matches the other 63 devDependencies; `npm install` had added carets.
The viewBox restoration is a fidelity fix, not a visible one: measured against the previous bundle it is an antialiasing-level difference.
🦋 Changeset detectedLatest commit: 0205aa6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
✅ Deploy Preview for cloudfour-patterns ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
7 tasks
Uh oh!
There was an error while loading. Please reload this page.
5 tasks
Merged
This was referenced Aug 21, 2026
spaceninja added a commit
that referenced
this pull request
Aug 22, 2026
* Replace gulp with plain Node build scripts
Removes the last of the gulp toolchain: 280 lines across 5 tasks, and 8
packages (gulp, gulp-postcss, gulp-rename, gulp-run, gulp-sass, gulp-svgmin,
through2, tiny-glob), which takes 199 packages out of the tree.
Each task moves to a script in `scripts/`, matching the `.mjs` convention
`.style-dictionary/build.mjs` already set:
- `buildJS` and `buildTypes` were already plain Rollup API, so they only
needed converting to ESM. They share the virtual root entry via
`rollup-root-entry.mjs`.
- `buildSass` calls sass and postcss directly, matching what gulp-sass and
gulp-postcss were doing: compile, run `postcss.config.js`, write
`standalone.css`, then minify that with cssnano.
- `buildTokens` was a 5-line wrapper shelling out to `preprocess:tokens`, so
it is simply gone; the watcher runs the token build directly.
- `watchPreprocess` uses `node:fs.watch` with `recursive: true` rather than
taking on a watcher dependency. It was the only thing in the build needing
one.
`tiny-glob` is replaced by `node:fs.glob`, which finds the same 63 files. The
results are now sorted explicitly: the entry file is built by joining those
paths, so the published bundle and type declarations were quietly depending
on one glob library's traversal order. Sorting reproduces the previous order
exactly.
All of `dist` is byte-identical, as are the generated token files.
The SVG task is the exception. `gulp-svgmin` pins SVGO 2, so taking svgo as a
direct dependency means SVGO 4 -- and SVGO 4 rejects the `.svgo.yml` plugin
format outright rather than warning, so the config fix and the upgrade cannot
be separated. `.svgo.yml` now uses the current format, which has three
consequences:
- `removeXMLNS` finally applies. It has been silently dropped for years,
because it is not a `preset-default` plugin and the old format could only
express preset overrides. These partials are only `{% include %}`d into
HTML, where the namespace is implied.
- `removeViewBox: false` is no longer needed. SVGO 4 dropped that plugin from
`preset-default`, so viewBox is preserved by default -- which is what this
config already asked for, and what #2422 restored in the minified CSS.
- Coordinates round slightly differently. Rendered and compared pixel for
pixel, 55 of the 72 partials are unchanged, and the largest difference in
the rest is 0.53% of pixels at the edges of curves.
Verified with a headless sweep: all 337 entries (249 stories, 82 docs) render
with content and zero page errors.
* Update the project structure in CONTRIBUTING
Beyond replacing gulpfile.js with scripts/, the tree had drifted: Style
Dictionary's files became .mjs in #2422, .storybook/main became .mjs in
#2405, and stories stopped being .stories.mdx in the same PR.
* Add a changeset for the SVG partial changes
This was referenced Aug 22, 2026
Closed
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 freeto 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.
Overview
This is item 5 of #2391 — the last group of ordinary dependency upgrades before removing Gulp. Five packages move:
js-yaml4→5,npm-run-all28→9,sass1.102→1.103,cssnano5→8, andstyle-dictionary3→5. Only the last two are more than a version bump, and both change files we publish, so each commit records what moved in the output and why. They are one commit each so the two interesting ones can be read on their own.Style Dictionary 4 was a rewrite, so that one is a migration: the package is ESM-only, the build hooks were all renamed, and reference syntax dropped its
.valuesuffix. Two of its changes were silent rather than loud, which is the part worth a reviewer's attention. Broken references are now an error instead of a warning, which is what surfaced 25 stale references that had been resolving by luck. More subtly, the built-incolor/csstransform stopped matching our tokens at all — its filter used to key off the CTIattributes.categoryand now requires an explicittype: 'color'that our tokens don't declare — so the build stayed green while colours quietly passed through unnormalised. It is re-registered with the old filter, which is why the generated Sass is byte-identical.cssnano 8 is the only change to published output. It grows
dist/standalone.min.cssby 3.2kB raw, 227 bytes gzipped, almost entirely because the newer SVGO keeps theviewBoxon inlined SVGs where the old one stripped it. That is a fidelity fix rather than a visible one — rendered and compared pixel for pixel, the old and new bundles differ only by antialiasing — but it means the minified bundle is once again a faithful minification of the unminified one. The remaining differences are all in the same direction:columnsandcurrentColornow survive as authored instead of being rewritten.Screenshots
Testing
Most of this is checkable on the deploy preview, but one part is not: Storybook compiles Sass through Vite and never loads
dist/standalone.min.css, which is the only file cssnano changed. The last section covers that separately.Design tokens, on the deploy preview — these exercise the Style Dictionary migration end to end, since the pages read the generated token files:
rgba(…)value beside it — no blanks, noundefined, and nothing rendering as black or transparent that shouldn't.Components that use an inlined SVG background:
The published minified stylesheet, locally — this is the part the preview can't show:
npm run build, then save the snippet below ascheck.htmlin the project root and open it in a browser. The blue and white clouds should be fully drawn and anchored to the bottom-right of the bordered box.dist/standalone.cssand reload. It should look the same. The two bundles agreeing is the point of the cssnano change; they should no longer drift apart.check.htmlwhen you're done — it's a scratch file, not something to commit.