-
-
Notifications
You must be signed in to change notification settings - Fork 499
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
📎 Monorepo support #2228
Comments
wouldn't it be easier to run biome in each package and run it in parallel with like a pnpm (or whatever your'e using for workspaces) script? That affords a lot of flexibility considering in a monorepo you may not have all packages linted with the same config or even the same tools, eg you have an older package that is using eslint+prettier still that package can have an npm script To double down on this; unix philosophy says do one thing and one thing well. Biome is amazing at fixing style issues and smells in ur code. It's not a workspaces tool; theres already a bunch of tools that are specialized in that, eg lerna, pnpm workspaces, yarn workspaces, rush... biome should work with these tools not against them. |
@NyanHelsing I think you make a convincing argument, but there’s a few practical issues we keep running into with the current approach (which aligns with your suggestion):
So while I agree with your argument in principle, I’m afraid there’s too many practical downsides for Biome to keep it limited to a per-package scope. |
@ematipico When you mention the |
I also share your vision, and I wouldn't have created this issue if it wasn't for @arendjr's points in #2228 (comment). The web ecosystem has matured in the last few years, although we have yet to make a standard on managing these big monorepos, which means that users have different flavours. For example, some projects out there would expect a top-level CLI command called I would suggest the same as you did: tell the users to use a package manager to create multiple scripts, one in each monorepo. I just wish there was a better way to do this, maybe by pushing for a proper use of workspaces. Yeah |
i'm confident theis can ameliorated with a top-level section in the documentation: (demonstrated here with pnpm) Biome and WorkspacesBiome works great with workspaces; install it in each of the packages:
Biome can now be run in each package.
if this is the desire it isn't obvious that is should be dependent on workspaces, this is just about putting multiple biome.json in any folder structure and expecting them to work?
it still sounds like this is saying it isn't needed for linting or formatting. In the lint/format space, biome files a decidedly lint/formatting-shaped hole. Theres jslint/jshint which nobody should use because they're old and slow and dont work on modern code, and there's prettier/eslint which are more modern but still slow. Biome is needed here. Since there are already lots of tools that do bundling we'd expect lots of users to continue to use one of the many bundlers (rollup, rspack, webpack, swcpack, turbopack, even grunt) that are all very good (except maybe grunt which is old, webpack which is slow. A biome bundler (AFAIK) doesn't exist yet; assuming it already exists and there is some space it fills that isn't already occupied by one of the previous bundlers; I could imagine users being a little upset at the prospect of having many bundlers installed in their project that might not even be used. It's strongly encouraged to make a bundler a part of a dedicated and separate install (or better, provide tight integration with the existing bundlerts) rather than bloating the tool that creates a hygenic environment for us.
|
I'm sorry, but the solution you offered has nothing to do with the problem I highlighted. The problem is that when users open a repository in their IDE, the extension currently only supports using the top-level
Please look again at the tagline for Biome: One toolchain for your web project It is the project's explicit goal to create a single unified tool that can cover several needs. |
This sounds like a problem with the ide plugins then? not with biome per se; the plugin just needs to have the command to be configurable; then document it at a top level so it's easily seen by folks.
A tool chain contains multiple tools. |
It's not a matter of documentation or configuring the extension. Extensions would need the ability to switch between configurations on the fly, depending on which file is currently opened. Please see this comment for why we don't want to implement such logic purely within the extension: #1573 (comment)
Sorry, but I don't see this discussion heading in a productive direction. Feel free to disagree, but Biome has been clear in its approach: It provides multiple tools within a single command/binary/toolchain. |
" in the future Biome will also transform/compile users's code, so it requires awareness of the manifest file and the dependency graph" Is there any details on these compilation plans? For context, right now I'm using Biome in a monorepo, entirely for its prettier-compliant formatter. |
@anthony-hayes It’s briefly mentioned in the roadmap: https://biomejs.dev/blog/roadmap-2024/#transformations There’s also already a |
I wouldn't strictly call "Central file" common denominator. There's a monorepo tool called Rush, and it basically does things in a way opposite to more popular tools. And while it has less downloads than turbo or nx, it is used for large-scale monorepos at companies like TikTok, Microsoft, HBO. Rush's way is basically to isolate package from each other for portability. There's no root config files, each dependency is explicitly listed in each package.json, common configs are distributed as packages themselves. |
@Faithfinder Maybe I'm missing the crux here. Whilst Rush doesn't have a central package.json file or equivalent, it does have mono-repo level configuration that can alter the behaviour of commands ran within individual projects. |
Well, my main point was that a lot of tools don't work on Rush because they expect a root level And I do believe Rush gets many things right. Just trying to put other approaches on Biome's radar before they make a design decision that's hard to back out of |
@Faithfinder thank you for providing a different example. My assumption was based on my working experience and the projects that I've seen around. I know Rush, and I wanted to use it; however, when I was evaluating the project, I understood that it still needed a package manager under the hoods. Of course, I might be wrong. |
Oh, it uses a package manager under the hood, but it wraps it and imposes additional restrictions on top. At this point it would be easier for you to try it. Their own repo is a moderately sized Rush repo, works well as a study https://github.com/microsoft/rushstack |
Hoping to throw in my two cents! I couldn't find anywhere where design was being discussed and this issue appears to be doing so. (Proposal is at the bottom if you'd like to jump straight there. This is fairly long-winded as I'd like to share how I'm arriving at this proposal.) Some background:
There are various designs that I've seen used around the ecosystem for handling Workspaces and I think the community has learned a lot on how to handle configurations: ESLint 👎ESLint has learned that cascading configuration by default is problematic. It hurts performance as configuration discovery takes too much time and figuring out which configuration applies to the file you're in can be difficult. This has led to their Flat Configurations. Before Flat Configs, users could create ESLint configuration in any arbitrary place within the repo and ESLint would merge everything it can find from the file's location to the location where the ESLint CLI was executed from. This was bad for performance, and made it difficult to know which configuration was being applied in which files. Flat Config was meant to make configuring ESlint easier - but it's still unclear what users are meant to do and ESLint doesn't know what they recommend for Workspaces either. For what it's worth, it's clear to me after working with Flat Configs in multiple repos that each package should get its own configuration file, with a separate configuration in the root specifically, for the Workspace root, if desired. ESLint is then run in each package individually and in the root separately. This brings ESLint closer to TypeScripts more favorable monorepo modeling. TypeScript 👍Typescript allows users to define configuration in the Workspace root and in packages. A package in a workspace uses either the root configuration, or the one defined in the package, but cannot use both - unless the user explicitly uses the This strategy has some significant advantages:
Turborepo Package Configurations 👍Turborepo's Package Configurations follow the same general model as TypeScript, using values from the root configuration and merging in keys found in the Package Configuration. The consistencies between the two approaches have proven to be a strength for users of these tools, in my experience, both when used together and separately. This configuration has a key difference when compared to TypeScript's extending. Turborepo (currently) only allows for extending from the root configuration using a There are, of course, many more tools I could add to this list, but things seem to be converging around TypeScript's monorepo-ing model, which seems to work well. Perceived shortcomings in today's Biome
Proposal
Open questions/uncertainties
Whew! That's a lot of info. Feel free to ask any questions you may have. The biggest thing I'd like to express is that the ecosystem has been closing in on standards around how Workspaces are meant to work, and the above proposal would fall into line with those expectations. The more we can do to have the best tools in the ecosystem work together, the better! |
I'm looking forward to this feature being implemented as I am constantly working with monorepos. While I do value having some freedom between the different packages within my monorepos, I don't consider the ability to install different lint tools to be particularly valuable. I've had multiple monorepos where we chose to allow each package within the monorepo to set up eslint on their own. The result was:
None of the above bullet points made for a pleasant development experience at all. I understand that Biome doesn't have plugins yet, but based on the roadmap I think it eventually will. I would much prefer to install Biome (and any future plugins) in a central location of the monorepo and only do it once. I only want to have one "lint" script that can either lint the entire repo or target specific folders using git diff in CI. |
"One lint script" quickly falls apart the moment you have codebases with different global scopes (think nodejs API backend, browser frontend and browser extension) and have to have separate configs anyway. I'd say the biggest hurdle for biome adoption is it's hard to cram into a subpackage in a project (with IDE support), and therefore "preview" its functionality in an actual production setup. Instead it requires a full commitment from get go, which isn't something people would do when they have working ESLint + Prettier setup already. |
@GabenGar, can you describe further how global scopes of your applications affect a singular lint script being used? From what you've mentioned, it sounds like you have globals that apply to specific packages in your Workspace, given their different contexts. Today, one could use Notably, this is the similar to what some folks are doing now with ESLint's Flat Config. One configuration at the root of the Workspace, one CLI invocation from the root, but the Flat Config has many global contexts it takes care of. Hopefully both of these examples demonstrate my larger point: From the Workspace's perspective, application globals are not global at all, since they only apply within that package's context. Accordingly, a single, root CLI invocation can be designed with the cleverness to only use the right globals at the right times in the right places. |
For clarity, "one lint script" doesn't mean "one lint config file". I can still put different config files in different folders and sub folders. The script picks them up and always applies the most local config. |
We reached the pledged amount. I will start working on this feature starting next year :) |
Description
This task is related to #1573 , but it has slightly different requirements and use cases, although we could potentially solve both with the same solution.
Background
Monorepo (package manager workspaces) are very common in the web ecosystem, and they come in different flavours and expectations.
However, the common denominator is the following: a root configuration file, and each package in the monorepo extends the root configuration.
Flavours:
pnpm run --filter
,turborepo
, etc. This is very common for building tools such as bundlers, compilers, and doc generation.The Biome case
Biome is a particular case here, because, even though it is a linter/formatter, in the future Biome will also transform/compile users's code, so it requires awareness of the manifest file and the dependency graph. Which means, while it makes sense to run
biome check
at the root of the monorepo, what about a - future -biome compile
command?We will have to untangle this. I am also happy to force users to set up Biome in one way in their monorepo.
CLI vs LSP =
Workspace
The solution should lie in the Workspace. The
Workspace
is what LSP and CLI both share, meaning that both of them hold an instance of it, and they use it to pull data when they need.CLI
The CLI usually works from up to bottom, it scans and handles the files that are closest to the working directorey, and eventually handles the farthest files from the working directory. Although, this isn't always true, because for each directory AND file, we always span a thread, which means that eventually all jobs go their own way.
We would need to change the strategy of our CLI here, in way where we would need to read and resolve possible
biome.json
files in each folder.This could be potentially solved with a new
workspace
configuration, that would allow Biome to resolve the packages before hand.LSP
The LSP has a different problem to solve. Biome must apply the correct configuration for the opened file when jumping from one file to another.
Workspace
The reason why I think the solution lies in the
Workspace
, is because both CLI and LSP have to do a very similar job: when handling a file, we should apply the configuration that belongs to that file. The BiomeWorkspace
would potentially store all those configurations, and then the CLI and LSP could:Workspace
to use the correct configuration, e.g.Workspace::swap_config
Workpace
could that by checking the path of the file/folder, and resolving automatically the configuration to useUpvote & Fund
The text was updated successfully, but these errors were encountered: