Skip to content

[code-infra] Bring eslint configuration from core and bump to v9 #344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

brijeshb42
Copy link

@brijeshb42 brijeshb42 commented May 30, 2025

This is now exposed as a package that can be imported and assembled with
minimum code on the client repos.

  1. Migrated eslint-plugin-material-ui to its own subpath.
  2. Airbnb config has been assembled in its own subpath.
  3. Common configs used in core repo have been moved here.

The package also exposes the common prettier config.

One of the pending discussions would be what level of abstraction do we want in this new package because a lot of the overrides in the core repo target files/folders that pertain to that repo itself and are not relevant in other repos.

Migration PR on core - mui/material-ui#46258
Base UI - mui/base-ui#2054

@brijeshb42 brijeshb42 requested a review from Janpot May 30, 2025 11:00
@brijeshb42 brijeshb42 added the scope: code-infra Specific to the core-infra product label May 30, 2025
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label May 30, 2025
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label May 30, 2025
@brijeshb42 brijeshb42 changed the title [code-infra] Bring eslint configuration from core [code-infra] Bring eslint configuration from core and bump to v9 May 30, 2025
@brijeshb42 brijeshb42 force-pushed the configs-package branch 3 times, most recently from 7076f75 to d420d80 Compare June 3, 2025 07:09
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Jun 3, 2025
@brijeshb42 brijeshb42 force-pushed the configs-package branch 2 times, most recently from 8c92e97 to da2c6db Compare June 3, 2025 09:16
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Jun 3, 2025
import { includeIgnoreFile } from '@eslint/compat';
import { defineConfig, globalIgnores } from 'eslint/config';
import * as path from 'node:path';
import baseConfig from '@mui/infra/eslint';
Copy link
Member

Choose a reason for hiding this comment

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

Would it make sense for these to be factory functions? So that we can pass configuration such as tsconfig locations:

  {
    name: 'Base config',
    extends: createBaseConfig(),
    rules: {
      'import/prefer-default-export': 'off',
      // No time for this
      'react/prop-types': 'off',
      'jsx-a11y/control-has-associated-label': 'off',
      'jsx-a11y/no-autofocus': 'off',
    },
  },

Copy link
Author

Choose a reason for hiding this comment

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

The only thing that I came across to require factory was conditionally enabling react-compiler plugin based on params.
So far in the process of migration, no other use-case has surfaced.

Copy link
Member

Choose a reason for hiding this comment

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

I can imagine us to cook up some quite extensive factory for things like https://github.com/mui/mui-x/blob/ef29b0c82d874564c2d9a4a59d0164ffb625f9b9/.eslintrc.js#L60

🤔 Maybe it's too much future proofing, but if we make factory functions by default we don't have to make breaking changes to introduce one if needed at some point

Copy link
Author

Choose a reason for hiding this comment

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

Yeah. Makes sense.

import { defineConfig, globalIgnores } from 'eslint/config';
import * as path from 'node:path';
import baseConfig from '@mui/infra/eslint';
import testConfig from '@mui/infra/eslint-test';
Copy link
Member

Choose a reason for hiding this comment

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

Let's keep the amount subpath exports low?

Suggested change
import testConfig from '@mui/infra/eslint-test';
import { testConfig, baseConfig } from '@mui/infra/eslint';

settings: {
'import/resolver': {
typescript: {
project: ['tsconfig.node.json', 'apps/*/tsconfig.json', 'packages/*/tsconfig.json'],
Copy link
Member

Choose a reason for hiding this comment

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

This can probably be the default?

@@ -0,0 +1,3 @@
import baseline from '@mui/infra/prettier';
Copy link
Member

Choose a reason for hiding this comment

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

Let's use named export? Also, would it be beneficial for the future to use factory functions as well?

@brijeshb42 brijeshb42 force-pushed the configs-package branch 2 times, most recently from 5f16f20 to 9d28044 Compare June 3, 2025 12:38
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Jun 3, 2025
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Jun 3, 2025
@brijeshb42 brijeshb42 force-pushed the configs-package branch 3 times, most recently from 31b6174 to 93c0a1d Compare June 4, 2025 05:08
@brijeshb42 brijeshb42 requested a review from a team June 4, 2025 05:32
@brijeshb42 brijeshb42 force-pushed the configs-package branch 4 times, most recently from 858ed71 to 9f53c7e Compare June 4, 2025 06:02
@@ -0,0 +1,74 @@
{
"name": "@mui/infra",
Copy link
Author

Choose a reason for hiding this comment

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

@oliviertassinari What do you recommend the package name to be ?
@mui/internal-infra or @mui-internal/infra or does the current name work?

Copy link
Member

@oliviertassinari oliviertassinari Jun 5, 2025

Choose a reason for hiding this comment

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

What I see in https://github.com/mui/base-ui/pull/2008/files#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519R76 looks correct for the prefixes, it matches with https://www.notion.so/mui-org/engineering-mui-utils-purpose-9a9fc9da3a004864b6c4e1f4d1f24f95?source=copy_link#d1699bb48f0f4ef58ca831d1ee9772ec.

For the actual name of this, I would always be more in favor of having ONE big npm package, than many, per https://www.notion.so/mui-org/Engineering-philosophy-ec1615511f594782a8a2adeec3e25143?source=copy_link#1e7cbfe7b660805eb1f3f2475839085f so we are forced to update everything at once, so we are forced to make small breaking changes and so we don't have to deal with different version inter-compatibility. So something like:

Suggested change
"name": "@mui/infra",
"name": "@mui/internal-code-infra",

sounds amazing, to be the default npm package that hosts code-infra, https://www.notion.so/mui-org/Code-infra-5562c14178aa42af97bc1fa5114000cd. Add prettier, eslint, CSS, markdown config, e2e test utils, visual regression, bundle size checker, etc, the whole thing.


On the choice of the repository, if we go with https://github.com/mui/mui-public, I think we have to have:

  1. Very strong test cases here; otherwise, the DX to make changes will be miserable compared to having the source inside https://github.com/mui/base-ui.
  2. Kind of the same as 1 is the ability to develop changes right inside the different repositories, at the very least, to debug effectively
  3. I think that this only works if each commit here can be propagated, almost instantly, to the other repositories. Nobody wants to context shift by 1 day on 5 repositories to make minor changes. So if we don't have this, so many small crappy stuff won't be fixed, only becaue of the overhead, so we can't offord to have an overhead.

Copy link
Member

@Janpot Janpot Jun 6, 2025

Choose a reason for hiding this comment

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

  1. Agree

  2. This is tricky, it's possible with pnpm linking but it can get messy with transitive dependencies and singletons. Otherwise use file: dependencies. but you'll have to re-install on every change. There is no having your cake and eating it too. Going multi-repo will impose degraded DX on shared infra, always.

  3. Again tricky, everything with trade-offs:

    • github: dependecy: no build step posseble, no workspace: dependencies possible. slow install process. i.e. heavy resrictions on expressiveness, which you wouldn't have in a monorepo.
    • renovatebot with tight schedule +
      • rely on pkg.pr.new: much lower guarantees on stability than npm. If it goes down for a few days, we are in trouble. This is not imaginary, we've had this situation in smaller scale with csbci and Base UI. non-starter for me.
      • publish every master commit to npm: tricky versioning situation, version number in github bisects from version in npm
        • sequential version: great for natural ordering, npm can take two versions and compare them know which one is newer
        • versioning by SHA, rely on npm tag. no ordering at all in version numbers, npm will just install the alphabetically last version, even if it's not the last published one. Only meaningful with npm publish tags. And only one version will be relevant, i.e. the one that is tagged

    best trade-off imo is to automatically publish to npm on every push to master, and use a sequential patch version. I suppose in source we could set the version in package.json to 1.2.x, the publish flow can then determine the patch by looking at latest published version that satisfies 1.2.x and increment. This way we can still control minor and major updates. renovatebot can then just operate on regular semver, which should be quite controllable as well.*

Problem 1. and 3. are solvable. IMO, for 2. a good solution doesn't exist ina multi-repo setup. You need people working on this that understand well what dependency linking does and what it doesn't and even then you'll have installations that will be difficult to simulate. I will work on a automated publishing flow next.

* alternative, a -canary.* version tag with incremental number

Copy link
Author

@brijeshb42 brijeshb42 Jun 6, 2025

Choose a reason for hiding this comment

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

IMO it's fine to not have a build step in this particular package. We can still have type-checking for local usage and any small change required by the package users can be first tested from inside the node_modules itself and then when everyting works, just copy over the changes to create a PR to this repo.

Copy link
Member

@Janpot Janpot Jun 6, 2025

Choose a reason for hiding this comment

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

As it grows, I'm sure we will want a build step, some of the existing code that we will port also requires one. And if for docs infra we need to publish some react components, there is no other way around it unless we manually want to write compiled JSX.

It'll also allow us to use the code infra repo to work on the build tooling itself instead of having to link it in other repositories for testing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
scope: code-infra Specific to the core-infra product
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants