Skip to content

Update stylelint to v17, including related packages - #80738

Open
mikeybinns wants to merge 14 commits into
WordPress:trunkfrom
mikeybinns:feature/update-stylelint
Open

Update stylelint to v17, including related packages#80738
mikeybinns wants to merge 14 commits into
WordPress:trunkfrom
mikeybinns:feature/update-stylelint

Conversation

@mikeybinns

Copy link
Copy Markdown
Contributor

What?

Closes: #75047
Closes: #75503

Why?

There was no change or response from the original PR creator on branch #75503 and that branch only updates the stylelint package in one place, it didn't account for updating the package in other places in the repo or updating any breaking changes.

How?

I have:

  • Updated Stylelint and all related packages within the stylelint config.
  • Updated the dev dependency for the theme package, which exports stylelint plugins for the stylelint package.
  • Updated the stylelint-plugin-logical-css package in tools/stylelint and migrated to the new rules.
  • Updated stylelint version used in @wordpress/scripts
  • Run the autofixer to fix any issues found after updating (72 issues found, all to do with a change in indentation in @stylistic/stylelint-plugin v4.0.1)
  • Checked the Stylelint migration guide for v16 > v17 and I don't think there's any work we need to do to specifically migrate to v17 other than doing the package updates. It's largely based around the ESM updates, which seems to have been recently fixed ahead of time in stylelint-config: Convert config to ESM #79755, thanks :) )

Testing Instructions

  1. Clone the repo, check the branch and run repo setup as normal.
  2. Run the npm run lint:css command to run stylelint against the repo using the stylelint config.

Use of AI Tools

I have not used AI in any capacity for this migration.

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: mikeybinns <mikeybinns@git.wordpress.org>
Co-authored-by: manzoorwanijk <manzoorwanijk@git.wordpress.org>
Co-authored-by: aduth <aduth@git.wordpress.org>
Co-authored-by: ciampo <mciampini@git.wordpress.org>
Co-authored-by: marekdedic <marekdedic@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions github-actions Bot added [Package] Components /packages/components [Package] Block library /packages/block-library [Package] Theme /packages/theme [Package] UI /packages/ui labels Jul 27, 2026
@mikeybinns

Copy link
Copy Markdown
Contributor Author

I could use some help with Jest, it's throwing a module error, but the file it's referencing as "not a module" is a .mjs file, which is a module:
image

@aduth

aduth commented Jul 27, 2026

Copy link
Copy Markdown
Member

I haven't looked deeply, but you might try adding stylelint to the set of |-delimited dependencies here:

transformIgnorePatterns: [
'/node_modules/(?!(docker-compose|yaml|preact|@preact|parsel-js|comctx|uuid|marked)/)',
'\\.pnp\\.[^\\/]+$',
],

Jest doesn't actually process ESM, and this pattern is a way to tell Jest to transpile (to CommonJS) some of our dependencies that need it. Since Stylelint went ESM-only in v17, it likely needs it.

@mikeybinns

Copy link
Copy Markdown
Contributor Author

Okay, that seems to have worked, I added stylelint and some packages which stylelint relies on (globby and @sindresorhus/merge-streams), but now I've got another issue.

image

I can see the package in the root node_modules folder alongside stylelint, so it's clearly been moved further up the tree, but I'm not sure how to go about fixing that?

@manzoorwanijk
manzoorwanijk requested a review from ciampo July 28, 2026 04:41

@manzoorwanijk manzoorwanijk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks fine to me. Let us fix the changelog though.

Comment thread packages/stylelint-config/CHANGELOG.md Outdated
Co-authored-by: Manzoor Wani <manzoorwani.jk@gmail.com>
@mikeybinns

Copy link
Copy Markdown
Contributor Author

@manzoorwanijk I've updated the changelog with your suggestion.

Just for avoidance of doubt, I think changelogs for the components and UI packages are unnecessary as the only changes are either indentation or updates to stylelint disables, neither of which have any change on the styling rules at all.

The theme package is slightly different, the only change is the update of a dev dependency, however because there was no change to any other code and the peer dependency remained the same, I don't believe this warrants a changelog entry either.

@manzoorwanijk

Copy link
Copy Markdown
Member

I don't think adding stylelint to ignore patterns in test/unit/jest.config.js will fix this. It needs a deeper fix. The reason is that v17 is ESM-only, and Jest (CJS) can't import it.

stylelint 17 dropped its CommonJS build, so it can no longer be imported
from Jest's CommonJS runtime. Move the lint into a small ESM runner script
spawned as a child process, matching how the stylelint-config tests already
invoke stylelint.

Because a plugin instance can't cross a process boundary, the tests now
reference the plugin under test by path instead of importing it.
@manzoorwanijk

Copy link
Copy Markdown
Member

@aduth @ciampo, should we try the vm-modules option for this?

It's getting messy. I wish we get rid of Jest in favor of Vitest.

@aduth

aduth commented Jul 28, 2026

Copy link
Copy Markdown
Member

@aduth @ciampo, should we try the vm-modules option for this?

If it works, sure. I'd be happy with anything that gets us closer to true ESM. I just assumed it would break a bunch of stuff if we enabled it.

@manzoorwanijk

Copy link
Copy Markdown
Member

I just assumed it would break a bunch of stuff if we enabled it.

Yes, it breaks lot of other tests. Let us stick with this solution for now.

@aduth

aduth commented Jul 29, 2026

Copy link
Copy Markdown
Member

@manzoorwanijk Do you think this pull request needs anything else? For your comment at #80738 (comment), my understanding is that the ignore list is what allows Jest to be able to import it by transpiling to CommonJS. The regular expression with lookaheads is confusing, but my read of it is: "transpile everything to CommonJS, but not node_modules as they should be loaded as-is, with the exception of these packages that should also be transpiled to CommonJS".

We should probably rebase/merge the latest trunk though to bring in #80767, since I'd want some confidence this still works in Jest 30.

@ciampo

ciampo commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

It's getting messy. I wish we get rid of Jest in favor of Vitest.

Let's make it happen! I spent some time researching and coming up with a plan:

@manzoorwanijk

Copy link
Copy Markdown
Member

Do you think this pull request needs anything else?

No, it's ready, but TBH, I am not happy with the mess this ESM/CJS fight creates here.

my understanding is that the ignore list is what allows Jest to be able to import it by transpiling to CommonJS.

The reason is that merely adding stylint there won't help as it dies on some transitive deps like globby to @sindresorhus/merge-streams (import {on, once} from 'node:events'). So the fix is to enumerate the full transitive ESM closure - 118 packages in stylelint 17's tree (as per Claude). So, maintaining that hard list is not something we want to do.

@manzoorwanijk

Copy link
Copy Markdown
Member

I'm not getting any errors in lint:css, even after pulling down your latest changes?

Now you can see the CSS errors in CI after trunk merge.

@mikeybinns

Copy link
Copy Markdown
Contributor Author

Ah yeah, that's annoying, I specifically made sure trunk was up to date when I started to avoid this.

Shall we add these to the suppressions for now so it isn't a blocker for this PR?

@manzoorwanijk

Copy link
Copy Markdown
Member

Shall we add these to the suppressions for now so it isn't a blocker for this PR?

I don't think suppressions is a good idea, and yes, I do think it's a blocker for this PR. Let us create a preparatory PR that fixes those lints in trunk and then we can update this PR.

@mikeybinns

Copy link
Copy Markdown
Contributor Author

@manzoorwanijk I've synced the latest version of trunk to my fork, run npm install and then npm run lint:css. I'm not getting any errors against trunk.

Do you think this is accurate? Do we just have to make the changes even though they're not flagging yet?

@manzoorwanijk

Copy link
Copy Markdown
Member

@manzoorwanijk I've synced the latest version of trunk to my fork, run npm install and then npm run lint:css. I'm not getting any errors against trunk.

That is expected because those lints are due to the version upgrade here.

Do you think this is accurate? Do we just have to make the changes even though they're not flagging yet?

It's fine. Let us fix those lints here in this PR.

@mikeybinns

Copy link
Copy Markdown
Contributor Author

Okay, I have done the work to fix those linting issues. All the changes should be transparent in normal cases, however, it's possible these changes may have an impact on sites which have overridden those styles, especially on the blocks front end styling.

Note I have not done any testing or changelogs for these changes, and the safer method in this case may be to revert my commit and add "stylelint-disable-next-line" for all the violations instead, as this won't change styling but will still apply rules to the new code being added.

I have run out of time on my end for this week, but I may be able to look at these issues next weekend and do some more in-depth testing if no-one else can do this in my absence.

@github-actions github-actions Bot added [Package] Editor /packages/editor [Package] Block editor /packages/block-editor [Package] DataViews /packages/dataviews [Package] Fields /packages/fields labels Jul 31, 2026
@manzoorwanijk manzoorwanijk added the [Type] Task Issues or PRs that have been broken down into an individual action to take label Jul 31, 2026
@manzoorwanijk

Copy link
Copy Markdown
Member

Thanks, I will defer the review of CSS-related changes to @ciampo @aduth and @mirka

@manzoorwanijk
manzoorwanijk requested review from aduth and mirka July 31, 2026 12:27
@aduth

aduth commented Jul 31, 2026

Copy link
Copy Markdown
Member

Thanks for the work here @mikeybinns ! At a first glance a lot of these look like valid improvements for legacy CSS properties, for example. I'll take a closer look to understand the backwards-compatibility ramifications. You raise an interesting point about the potential downstream impact, though (a) I don't know that it's reasonable to expect that we can't ever make CSS changes to a block (i.e. not a public API contract) and (b) many of these being legacy CSS properties with equivalent overrides, the updated property would be the preferable extension point. I'd be curious what might happen if a theme overrides grid-gap and we now assign it as gap, for example.

display: inline-block;
text-align: center;
word-break: break-word; // overflow-wrap doesn't work well if a link is wrapped in the div, so use word-break here.
overflow-wrap: break-word;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Some of these specifically call out issues in the alternative that we switch to. And if still valid, then we may want to keep it and disable the rule for the instance instead.

That might also extend to all of the places we're removing word-break and overflow-wrap if it's not functionally equivalent. To your comment in #80738 (comment), we may want to exempt all of these instances, or even consider disabling the rule altogether.

At the very least it wouldn't be the same value. MDN's documentation for word-break: break-word specifically mentions as having 'the same effect as overflow-wrap: anywhere combined with word-break: normal" so I don't think overflow-wrap: break-word; is the equivalent.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I did try out in a codepen whether a div > a structure with overflow-wrap: break-word and word-wrap: break-word and I couldn't see a difference, but yeah, more testing should be done to confirm this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Block editor /packages/block-editor [Package] Block library /packages/block-library [Package] Components /packages/components [Package] DataViews /packages/dataviews [Package] Editor /packages/editor [Package] Fields /packages/fields [Package] Theme /packages/theme [Package] UI /packages/ui [Type] Task Issues or PRs that have been broken down into an individual action to take

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update @wordpress/stylelint-config to support stylelint 17

4 participants