|
| 1 | +# Yarn |
| 2 | + |
| 3 | +This page is dedicated to explaing how Yarn has been configured to work in this repository. |
| 4 | + |
| 5 | +## Workspaces |
| 6 | +Yarn, this repository's package manager, supports a feature called [workspaces](https://yarnpkg.com/features/workspaces#global-scripts), which are a way for packages to refer to one another within the same repository. |
| 7 | + |
| 8 | +This has several benefits: |
| 9 | +- **Reduced install size.** Yarn workspaces support focused installs, which means that a single team working on a single bundle or tab won't have to install the entire repository's worth of packages that won't be relevant to them |
| 10 | +- **Dependency Management.** If tabs (or other bundles) rely on a specific bundle, Yarn's dependency resolution automatically determines what needs to be rebuilt and in what order. |
| 11 | +- **Automatic Worktree Detection.** If so desired, Yarn automatically detects which bundles/tabs have changed with respect to the main git branch and won't rebuild those that haven't. |
| 12 | +- **More Configurability:** Each bundle/tab can maintain its own set of dependencies now, separate from other bundles. This allows us to have patches local to a specific bundle (like the `@jscad/modeling` patch for `csg`). Also each bundle/tab can customize its own `tsconfig` etc.. |
| 13 | + |
| 14 | +At the root repository, this is defined using the `workspaces` field in `package.json`. |
| 15 | + |
| 16 | +## Yarn Constraints |
| 17 | +Yarn also supports a feature known as [constraints](https://yarnpkg.com/features/workspaces#constraints) for workspaces. As of this moment, the feature can be used to ensure that all workspaces within a repository have fields in their `package.json`s set to specific values. We use this feature to ensure that: |
| 18 | + |
| 19 | +### 1. All workspaces have `"type": "module"`. |
| 20 | +As part of ensuring consistency, everything in this repository has been designed to use ESM first and to move away from legacy reliance on CommonJS modules. |
| 21 | + |
| 22 | +### 2. Dependencies, if shared, have the correct versions. |
| 23 | +Tabs, for example, should all be using the same versions of `react` and `react-dom`: the one in use by the frontend. If a dependency is specified in the root `package.json`, then the constraints file |
| 24 | +requires that all child workspaces use the version of that dependency. |
| 25 | + |
| 26 | +For example, the root package specifies `react@^18.3.1` as a depdendency, so all workspaces that require React must also use that version spec. |
| 27 | + |
| 28 | +This validation is not carried out across child workspaces, however. Two different bundles could use two different versions of the same package. This should not cause an issue **unless** the bundles are somehow dependendent on each other. |
| 29 | + |
| 30 | +## Parallel Execution of Scripts |
| 31 | +Using the various options of the `yarn workspaces foreach` command, you can execute multiple tasks in parallel, which is how many of the commands in the root repository have been set up. |
| 32 | + |
| 33 | +The `-t` option runs the scripts in topological order, which means you don't have to manually figure out which packages have to be built before others; Yarn figures it out for you. |
| 34 | + |
| 35 | +::: details ESLint out of memory? |
| 36 | +For some reason when I migrated this repository over to Yarn workspaces, I kept finding that linting all the bundles at once in parallel |
| 37 | +would cause NodeJS to exceed its default memory limit of 4906MB. I guess if you wanted to run linting for all bundles in parallel you could |
| 38 | +just run NodeJS with `--max-old-space-size`, but I just found that limiting the number of jobs running in parallel using `-j` to 5 was |
| 39 | +sufficient to get around this issue. |
| 40 | +::: |
0 commit comments