deprecate-totp-2fa
@reggi/path-to-regexp
dependabot/npm_and_yarn/main/copy-to-clipboard-4.0.2
dependabot/npm_and_yarn/main/eslint-10.4.0
dependabot/npm_and_yarn/main/npmcli/eslint-config-7.0.0
dependabot/npm_and_yarn/main/proc-log-7.0.0
dependabot/npm_and_yarn/npm_and_yarn-826852524d
dependabot/npm_and_yarn/npm_and_yarn-ab9a7f4bc2
deprecate-totp-2fa
dhei/classic-tokens
gat-bypass-2fa-docs
jpg619/fix-accessibility-content-flow
jpg619/version-bump-tar-2
kartykp/gat-bypass-2fa-docs
kartykp/upgrade-path-to-regex
main
maitxn/version-bump-tar
patch-1
reggi/cache-based-on-version
reggi/dev-engines
reggi/fix-transform-prettier
reggi/overrides
update-search-sensitivity
| 1 | --- |
| 2 | title: workspaces |
| 3 | section: 7 |
| 4 | description: Working with workspaces |
| 5 | github_repo: npm/cli |
| 6 | github_branch: release/v9 |
| 7 | github_path: docs/lib/content/using-npm/workspaces.md |
| 8 | redirect_from: |
| 9 | - /cli-documentation/v9/misc/workspaces |
| 10 | - /cli-documentation/v9/using-npm/workspaces |
| 11 | - /cli/v9/misc/workspaces |
| 12 | --- |
| 13 | |
| 14 | ### Description |
| 15 | |
| 16 | **Workspaces** is a generic term that refers to the set of features in the npm cli that provides support to managing multiple packages from your local file system from within a singular top-level, root package. |
| 17 | |
| 18 | This set of features makes up for a much more streamlined workflow handling linked packages from the local file system. Automating the linking process as part of `npm install` and avoiding manually having to use `npm link` in order to add references to packages that should be symlinked into the current `node_modules` folder. |
| 19 | |
| 20 | We also refer to these packages being auto-symlinked during `npm install` as a single **workspace**, meaning it's a nested package within the current local file system that is explicitly defined in the [`package.json`](/cli/v9/configuring-npm/package-json#workspaces) `workspaces` configuration. |
| 21 | |
| 22 | ### Defining workspaces |
| 23 | |
| 24 | Workspaces are usually defined via the `workspaces` property of the [`package.json`](/cli/v9/configuring-npm/package-json#workspaces) file, e.g: |
| 25 | |
| 26 | ```json |
| 27 | { |
| 28 | "name": "my-workspaces-powered-project", |
| 29 | "workspaces": ["packages/a"] |
| 30 | } |
| 31 | ``` |
| 32 | |
| 33 | Given the above `package.json` example living at a current working directory `.` that contains a folder named `packages/a` that itself contains a `package.json` inside it, defining a Node.js package, e.g: |
| 34 | |
| 35 | ``` |
| 36 | . |
| 37 | +-- package.json |
| 38 | `-- packages |
| 39 | +-- a |
| 40 | | `-- package.json |
| 41 | ``` |
| 42 | |
| 43 | The expected result once running `npm install` in this current working directory `.` is that the folder `packages/a` will get symlinked to the `node_modules` folder of the current working dir. |
| 44 | |
| 45 | Below is a post `npm install` example, given that same previous example structure of files and folders: |
| 46 | |
| 47 | ``` |
| 48 | . |
| 49 | +-- node_modules |
| 50 | | `-- a -> ../packages/a |
| 51 | +-- package-lock.json |
| 52 | +-- package.json |
| 53 | `-- packages |
| 54 | +-- a |
| 55 | | `-- package.json |
| 56 | ``` |
| 57 | |
| 58 | ### Getting started with workspaces |
| 59 | |
| 60 | You may automate the required steps to define a new workspace using [npm init](/cli/v9/commands/npm-init). For example in a project that already has a `package.json` defined you can run: |
| 61 | |
| 62 | ``` |
| 63 | npm init -w ./packages/a |
| 64 | ``` |
| 65 | |
| 66 | This command will create the missing folders and a new `package.json` file (if needed) while also making sure to properly configure the `"workspaces"` property of your root project `package.json`. |
| 67 | |
| 68 | ### Adding dependencies to a workspace |
| 69 | |
| 70 | It's possible to directly add/remove/update dependencies of your workspaces using the [`workspace` config](/cli/v9/using-npm/config#workspace). |
| 71 | |
| 72 | For example, assuming the following structure: |
| 73 | |
| 74 | ``` |
| 75 | . |
| 76 | +-- package.json |
| 77 | `-- packages |
| 78 | +-- a |
| 79 | | `-- package.json |
| 80 | `-- b |
| 81 | `-- package.json |
| 82 | ``` |
| 83 | |
| 84 | If you want to add a dependency named `abbrev` from the registry as a dependency of your workspace **a**, you may use the workspace config to tell the npm installer that package should be added as a dependency of the provided workspace: |
| 85 | |
| 86 | ``` |
| 87 | npm install abbrev -w packages/a |
| 88 | ``` |
| 89 | |
| 90 | Note: other installing commands such as `uninstall`, `ci`, etc will also respect the provided `workspace` configuration. |
| 91 | |
| 92 | ### Using workspaces |
| 93 | |
| 94 | Given the [specifities of how Node.js handles module resolution](https://nodejs.org/dist/latest-v14.x/docs/api/modules.html#modules_all_together) it's possible to consume any defined workspace by its declared `package.json` `name`. Continuing from the example defined above, let's also create a Node.js script that will require the workspace `a` example module, e.g: |
| 95 | |
| 96 | ``` |
| 97 | // ./packages/a/index.js |
| 98 | module.exports = 'a' |
| 99 | |
| 100 | // ./lib/index.js |
| 101 | const moduleA = require('a') |
| 102 | console.log(moduleA) // -> a |
| 103 | ``` |
| 104 | |
| 105 | When running it with: |
| 106 | |
| 107 | `node lib/index.js` |
| 108 | |
| 109 | This demonstrates how the nature of `node_modules` resolution allows for **workspaces** to enable a portable workflow for requiring each **workspace** in such a way that is also easy to [publish](/cli/v9/commands/npm-publish) these nested workspaces to be consumed elsewhere. |
| 110 | |
| 111 | ### Running commands in the context of workspaces |
| 112 | |
| 113 | You can use the `workspace` configuration option to run commands in the context of a configured workspace. Additionally, if your current directory is in a workspace, the `workspace` configuration is implicitly set, and `prefix` is set to the root workspace. |
| 114 | |
| 115 | Following is a quick example on how to use the `npm run` command in the context of nested workspaces. For a project containing multiple workspaces, e.g: |
| 116 | |
| 117 | ``` |
| 118 | . |
| 119 | +-- package.json |
| 120 | `-- packages |
| 121 | +-- a |
| 122 | | `-- package.json |
| 123 | `-- b |
| 124 | `-- package.json |
| 125 | ``` |
| 126 | |
| 127 | By running a command using the `workspace` option, it's possible to run the given command in the context of that specific workspace. e.g: |
| 128 | |
| 129 | ``` |
| 130 | npm run test --workspace=a |
| 131 | ``` |
| 132 | |
| 133 | You could also run the command within the workspace. |
| 134 | |
| 135 | ``` |
| 136 | cd packages/a && npm run test |
| 137 | ``` |
| 138 | |
| 139 | Either will run the `test` script defined within the `./packages/a/package.json` file. |
| 140 | |
| 141 | Please note that you can also specify this argument multiple times in the command-line in order to target multiple workspaces, e.g: |
| 142 | |
| 143 | ``` |
| 144 | npm run test --workspace=a --workspace=b |
| 145 | ``` |
| 146 | |
| 147 | Or run the command for each workspace within the 'packages' folder: |
| 148 | |
| 149 | ``` |
| 150 | npm run test --workspace=packages |
| 151 | ``` |
| 152 | |
| 153 | It's also possible to use the `workspaces` (plural) configuration option to enable the same behavior but running that command in the context of **all** configured workspaces. e.g: |
| 154 | |
| 155 | ``` |
| 156 | npm run test --workspaces |
| 157 | ``` |
| 158 | |
| 159 | Will run the `test` script in both `./packages/a` and `./packages/b`. |
| 160 | |
| 161 | Commands will be run in each workspace in the order they appear in your `package.json` |
| 162 | |
| 163 | ``` |
| 164 | { |
| 165 | "workspaces": [ "packages/a", "packages/b" ] |
| 166 | } |
| 167 | ``` |
| 168 | |
| 169 | Order of run is different with: |
| 170 | |
| 171 | ``` |
| 172 | { |
| 173 | "workspaces": [ "packages/b", "packages/a" ] |
| 174 | } |
| 175 | ``` |
| 176 | |
| 177 | ### Ignoring missing scripts |
| 178 | |
| 179 | It is not required for all of the workspaces to implement scripts run with the `npm run` command. |
| 180 | |
| 181 | By running the command with the `--if-present` flag, npm will ignore workspaces missing target script. |
| 182 | |
| 183 | ``` |
| 184 | npm run test --workspaces --if-present |
| 185 | ``` |
| 186 | |
| 187 | ### See also |
| 188 | |
| 189 | - [npm install](/cli/v9/commands/npm-install) |
| 190 | - [npm publish](/cli/v9/commands/npm-publish) |
| 191 | - [npm run-script](/cli/v9/commands/npm-run-script) |
| 192 | - [config](/cli/v9/using-npm/config) |