|
| 1 | +- Start Date: 2018-02-12 |
| 2 | +- RFC PR: (leave this empty) |
| 3 | +- Yarn Issue: (leave this empty) |
| 4 | + |
| 5 | +# Summary |
| 6 | + |
| 7 | +Working on a workspace in isolation should be as easy as working on all workspaces together. Running a yarn command in |
| 8 | +a workspace should behave the same whether it is part of a larger project or whether it is its own separate repo. There |
| 9 | +should be a option on relevant commands, `--isolated` to have a command affect a single workspace instead of all workspaces. |
| 10 | + |
| 11 | +# Motivation |
| 12 | + |
| 13 | +Currently, yarn workspaces are optimized for people making changes across multiple projects in the |
| 14 | +monorepo, but they can make things more difficult if you want to work on a single workspace in isolation. While |
| 15 | +the automatic linking and auto-installation of dependencies for all workspaces can be convenient if you are actually working |
| 16 | +on all workspaces, having to build and install everything locally for multiple projects when you only work on one |
| 17 | +at a time can be time consuming compared to just pulling those packages down from a registry. |
| 18 | + |
| 19 | +If you could work on a single workspace in isolation as easily as if it were its own repo, the transition to a monorepo |
| 20 | +from separate repos would be seamless for people who focus on a single workspace/repo at a time, and one of the |
| 21 | +biggest reasons not to use workspaces would be removed. |
| 22 | + |
| 23 | +# Detailed design |
| 24 | + |
| 25 | +Terminology used for this doc: |
| 26 | +- rootDir: the root directory of a workspaces project. the one with the package.json with workspaces in it |
| 27 | +- workspaceDir: Directory for an individual workspace/package |
| 28 | +- isolated flag: `yarn foo --isolated` |
| 29 | + |
| 30 | +In order to be able to interact with a single workspace in both isolation and in the context of the project as a whole, |
| 31 | +relevant yarn commands should be able to be run with an `--isolated` flag. |
| 32 | + |
| 33 | +Relevant commands (based on current functionality) include |
| 34 | +- install |
| 35 | +- upgrade |
| 36 | +- upgrade-interactive |
| 37 | +- outdated |
| 38 | +- check |
| 39 | +- list |
| 40 | +- test (more relevant to [run commands RFC](https://github.com/yarnpkg/rfcs/blob/master/accepted/0000-workspace-run-commands.md). see below) |
| 41 | +- run (more relevant to [run commands RFC](https://github.com/yarnpkg/rfcs/blob/master/accepted/0000-workspace-run-commands.md). see below) |
| 42 | + |
| 43 | +This list may grow in the future (for example if yarn adds the ability to publish all workspaces at once). |
| 44 | + |
| 45 | +If you run a command with the isolated flag and are in a workspaceDir, it will run that command as if the workspaceDir you were currently in existed in isolation (with few exceptions detailed below). |
| 46 | + |
| 47 | +If you run a command with the isolated flag but you are at the rootDir (or any other directory not underneath a workspaceDir), it will give an error saying that the isolated flag can only be used inside an individual workspace. |
| 48 | + |
| 49 | +## Command behavior |
| 50 | +### install |
| 51 | +#### With isolated flag |
| 52 | +Install only that package's dependencies, and do not hoist them to the rootDir. Install dependencies on other |
| 53 | +workspaces from registry instead of using the local version. |
| 54 | + |
| 55 | +It should still use the rootDir's lockfile since adding lockfiles for each workspace will cause conflicts |
| 56 | +across workspaces. Since other workspaces will not be in the lockfile, it should determine their versions as if it was |
| 57 | +installing without a lockfile (by taking the newest version that matches their semver). |
| 58 | + |
| 59 | +#### Changes to current (non-isolated) behavior |
| 60 | +If a dependency was previously installed in a workspaceDir (from an isolated installation) and will be hoisted, delete it from the workspaceDir. This should not be a breaking change since the end result would be the same as if the isolated flag did not exist or if you were installing from scratch. |
| 61 | + |
| 62 | +### upgrade |
| 63 | +#### With isolated flag |
| 64 | +Upgrade all dependencies of the workspace in the root yarn.lock, respecting semvers of the current workspace and also |
| 65 | +every other workspaces. Install all dependencies for the current workspace in its node_modules, not hoisting anything |
| 66 | +to the root. Take the latest matching versions from the registry for all dependencies on other workspaces. |
| 67 | + |
| 68 | +#### Changes to current behavior. |
| 69 | +Deleting modules installed at an individual workspaceDir if they are going to be hoisted (similar to changes for `install`). |
| 70 | + |
| 71 | +### upgrade-interactive |
| 72 | +#### With isolated flag |
| 73 | +Interactive version of an isolated upgrade. Bring up the interactive prompt, only showing the workspace's dependencies. |
| 74 | +Record upgrades in the root yarn.lock. Install all dependencies for the current workspace in its node_modules, not hoisting anything |
| 75 | +to the root. Take the latest matching versions from the registry for all dependencies on other workspaces. |
| 76 | + |
| 77 | +#### Changes to current behavior. |
| 78 | +None except the changes to `upgrade`. Still just an interactive version of `upgrade`. |
| 79 | + |
| 80 | +### outdated |
| 81 | +#### With isolated flag |
| 82 | +Should show the list of packages that upgrade-interactive would show with isolated flag. |
| 83 | + |
| 84 | +#### Changes to current behavior. |
| 85 | +None. |
| 86 | + |
| 87 | +### check |
| 88 | +#### With isolated flag |
| 89 | +Verify the workspace's package.json against the root yarn.lock file. Use the workspace node_modules (not hoisted) when looking |
| 90 | +at actual package contents. |
| 91 | + |
| 92 | +#### Changes to current behavior. |
| 93 | +None. |
| 94 | + |
| 95 | +### list |
| 96 | +#### With isolated flag |
| 97 | +List only dependencies needed by the current workspace. |
| 98 | + |
| 99 | +#### Changes to current behavior. |
| 100 | +None. |
| 101 | + |
| 102 | +# How We Teach This |
| 103 | + |
| 104 | +*What names and terminology work best for these concepts and why?* |
| 105 | +No new terminology is needed. The `--isolated` flag is just a new flag that certain commands recognize. The documentation should be able to give a good explanation of the behavior. |
| 106 | + |
| 107 | +*How is this idea best presented?* |
| 108 | +As a way of enabling isolated development in a single workspace without removing the ability to manage the whole |
| 109 | +workspace from a subfolder. |
| 110 | + |
| 111 | +*How should this feature be introduced and taught to existing Yarn users?* |
| 112 | +Add a new section for the isolated flag for the relevant CLI commands in the documentation, explaining how it behaves differently when run with the flag. |
| 113 | + |
| 114 | +A blog post would be a good way to announce the feature as well. |
| 115 | + |
| 116 | +*Would the acceptance of this proposal mean the Yarn documentation must be |
| 117 | +re-organized or altered? Does it change how Yarn is taught to new users |
| 118 | +at any level?* |
| 119 | +Just adding new documetation for the new flag (see above). |
| 120 | + |
| 121 | +# Drawbacks |
| 122 | + |
| 123 | +For projects where working in isolation is the common case, it's still a bit awkward to have to specify the isolated flag every time you run a relevant command. This can be mitigated by using yarnrc to default the flag to true for each workspace. |
| 124 | + |
| 125 | +The logic for affected commands could get complicated as they would need to support 3 different ways of being run |
| 126 | +- current behavior in workspaces |
| 127 | +- isolation in a single workspace (where yarn.lock is at the root) |
| 128 | +- current isolated behavior in non-workspace project (where yarn.lock is at the same level as package.json) |
| 129 | + |
| 130 | +# Alternatives |
| 131 | + |
| 132 | +Rather than installing dependencies in the local node_modules of a specific workspace when running a command with the isolated flag, they could be hoisted (where possible) like the default commands and then only locally install |
| 133 | +dependencies on other workspaces (since the hoisted links can't be used). This was not chosen because while it would |
| 134 | +generally be faster (since most packages are already hoisted), it would be a worse simulation of isolated development |
| 135 | +since the dependencies would not be in the workspaces's node_modules folder. Adding symlinks to node_modules for |
| 136 | +all hoisted packages would be a middle-ground approach that came close simulating isolated development while still |
| 137 | +keeping dependencies in a consistent place where possible. |
| 138 | + |
| 139 | +An alternative that would require no work would be to just encourage people to disable the workspaces feature |
| 140 | +when they want to work in isolation. This is a poor user experience though, and the feature flag for workspaces |
| 141 | +will likely be deleted at some point. |
| 142 | + |
| 143 | +# Unresolved questions |
| 144 | + |
| 145 | +Should we eventually make the commands that can be run in isolation context-aware and have them default to isolation if run in a single workspace? This would be a breaking change that would need to wait until yarn 2.0 and get feedback from the community before deciding. It can be decided separately from the rest of the proposal after it has been used in the real world. |
| 146 | + |
| 147 | +Should using the isolated flag at the root directory just run with the default non-isolated behavior instead of erroring out (like described above). |
0 commit comments