11cb0ef41Sopenharmony_ci--- 21cb0ef41Sopenharmony_cititle: workspaces 31cb0ef41Sopenharmony_cisection: 7 41cb0ef41Sopenharmony_cidescription: Working with workspaces 51cb0ef41Sopenharmony_ci--- 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci### Description 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ci**Workspaces** is a generic term that refers to the set of features in the 101cb0ef41Sopenharmony_cinpm cli that provides support for managing multiple packages from your local 111cb0ef41Sopenharmony_cifile system from within a singular top-level, root package. 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ciThis set of features makes up for a much more streamlined workflow handling 141cb0ef41Sopenharmony_cilinked packages from the local file system. It automates the linking process 151cb0ef41Sopenharmony_cias part of `npm install` and removes the need to manually use `npm link` in 161cb0ef41Sopenharmony_ciorder to add references to packages that should be symlinked into the current 171cb0ef41Sopenharmony_ci`node_modules` folder. 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ciWe also refer to these packages being auto-symlinked during `npm install` as a 201cb0ef41Sopenharmony_cisingle **workspace**, meaning it's a nested package within the current local 211cb0ef41Sopenharmony_cifile system that is explicitly defined in the [`package.json`](/configuring-npm/package-json#workspaces) 221cb0ef41Sopenharmony_ci`workspaces` configuration. 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ci### Defining workspaces 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ciWorkspaces are usually defined via the `workspaces` property of the 271cb0ef41Sopenharmony_ci[`package.json`](/configuring-npm/package-json#workspaces) file, e.g: 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci```json 301cb0ef41Sopenharmony_ci{ 311cb0ef41Sopenharmony_ci "name": "my-workspaces-powered-project", 321cb0ef41Sopenharmony_ci "workspaces": [ 331cb0ef41Sopenharmony_ci "packages/a" 341cb0ef41Sopenharmony_ci ] 351cb0ef41Sopenharmony_ci} 361cb0ef41Sopenharmony_ci``` 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ciGiven the above `package.json` example living at a current working 391cb0ef41Sopenharmony_cidirectory `.` that contains a folder named `packages/a` that itself contains 401cb0ef41Sopenharmony_cia `package.json` inside it, defining a Node.js package, e.g: 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci``` 431cb0ef41Sopenharmony_ci. 441cb0ef41Sopenharmony_ci+-- package.json 451cb0ef41Sopenharmony_ci`-- packages 461cb0ef41Sopenharmony_ci +-- a 471cb0ef41Sopenharmony_ci | `-- package.json 481cb0ef41Sopenharmony_ci``` 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ciThe expected result once running `npm install` in this current working 511cb0ef41Sopenharmony_cidirectory `.` is that the folder `packages/a` will get symlinked to the 521cb0ef41Sopenharmony_ci`node_modules` folder of the current working dir. 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ciBelow is a post `npm install` example, given that same previous example 551cb0ef41Sopenharmony_cistructure of files and folders: 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci``` 581cb0ef41Sopenharmony_ci. 591cb0ef41Sopenharmony_ci+-- node_modules 601cb0ef41Sopenharmony_ci| `-- a -> ../packages/a 611cb0ef41Sopenharmony_ci+-- package-lock.json 621cb0ef41Sopenharmony_ci+-- package.json 631cb0ef41Sopenharmony_ci`-- packages 641cb0ef41Sopenharmony_ci +-- a 651cb0ef41Sopenharmony_ci | `-- package.json 661cb0ef41Sopenharmony_ci``` 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci### Getting started with workspaces 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ciYou may automate the required steps to define a new workspace using 711cb0ef41Sopenharmony_ci[npm init](/commands/npm-init). For example in a project that already has a 721cb0ef41Sopenharmony_ci`package.json` defined you can run: 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci``` 751cb0ef41Sopenharmony_cinpm init -w ./packages/a 761cb0ef41Sopenharmony_ci``` 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ciThis command will create the missing folders and a new `package.json` 791cb0ef41Sopenharmony_cifile (if needed) while also making sure to properly configure the 801cb0ef41Sopenharmony_ci`"workspaces"` property of your root project `package.json`. 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci### Adding dependencies to a workspace 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ciIt's possible to directly add/remove/update dependencies of your workspaces 851cb0ef41Sopenharmony_ciusing the [`workspace` config](/using-npm/config#workspace). 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ciFor example, assuming the following structure: 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci``` 901cb0ef41Sopenharmony_ci. 911cb0ef41Sopenharmony_ci+-- package.json 921cb0ef41Sopenharmony_ci`-- packages 931cb0ef41Sopenharmony_ci +-- a 941cb0ef41Sopenharmony_ci | `-- package.json 951cb0ef41Sopenharmony_ci `-- b 961cb0ef41Sopenharmony_ci `-- package.json 971cb0ef41Sopenharmony_ci``` 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ciIf you want to add a dependency named `abbrev` from the registry as a 1001cb0ef41Sopenharmony_cidependency of your workspace **a**, you may use the workspace config to tell 1011cb0ef41Sopenharmony_cithe npm installer that package should be added as a dependency of the provided 1021cb0ef41Sopenharmony_ciworkspace: 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci``` 1051cb0ef41Sopenharmony_cinpm install abbrev -w a 1061cb0ef41Sopenharmony_ci``` 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ciNote: other installing commands such as `uninstall`, `ci`, etc will also 1091cb0ef41Sopenharmony_cirespect the provided `workspace` configuration. 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci### Using workspaces 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ciGiven the [specifics 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 1141cb0ef41Sopenharmony_ciby its declared `package.json` `name`. Continuing from the example defined 1151cb0ef41Sopenharmony_ciabove, let's also create a Node.js script that will require the workspace `a` 1161cb0ef41Sopenharmony_ciexample module, e.g: 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ci``` 1191cb0ef41Sopenharmony_ci// ./packages/a/index.js 1201cb0ef41Sopenharmony_cimodule.exports = 'a' 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci// ./lib/index.js 1231cb0ef41Sopenharmony_ciconst moduleA = require('a') 1241cb0ef41Sopenharmony_ciconsole.log(moduleA) // -> a 1251cb0ef41Sopenharmony_ci``` 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ciWhen running it with: 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci`node lib/index.js` 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ciThis demonstrates how the nature of `node_modules` resolution allows for 1321cb0ef41Sopenharmony_ci**workspaces** to enable a portable workflow for requiring each **workspace** 1331cb0ef41Sopenharmony_ciin such a way that is also easy to [publish](/commands/npm-publish) these 1341cb0ef41Sopenharmony_cinested workspaces to be consumed elsewhere. 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ci### Running commands in the context of workspaces 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ciYou can use the `workspace` configuration option to run commands in the context 1391cb0ef41Sopenharmony_ciof a configured workspace. 1401cb0ef41Sopenharmony_ciAdditionally, if your current directory is in a workspace, the `workspace` 1411cb0ef41Sopenharmony_ciconfiguration is implicitly set, and `prefix` is set to the root workspace. 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ciFollowing is a quick example on how to use the `npm run` command in the context 1441cb0ef41Sopenharmony_ciof nested workspaces. For a project containing multiple workspaces, e.g: 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci``` 1471cb0ef41Sopenharmony_ci. 1481cb0ef41Sopenharmony_ci+-- package.json 1491cb0ef41Sopenharmony_ci`-- packages 1501cb0ef41Sopenharmony_ci +-- a 1511cb0ef41Sopenharmony_ci | `-- package.json 1521cb0ef41Sopenharmony_ci `-- b 1531cb0ef41Sopenharmony_ci `-- package.json 1541cb0ef41Sopenharmony_ci``` 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_ciBy running a command using the `workspace` option, it's possible to run the 1571cb0ef41Sopenharmony_cigiven command in the context of that specific workspace. e.g: 1581cb0ef41Sopenharmony_ci 1591cb0ef41Sopenharmony_ci``` 1601cb0ef41Sopenharmony_cinpm run test --workspace=a 1611cb0ef41Sopenharmony_ci``` 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ciYou could also run the command within the workspace. 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ci``` 1661cb0ef41Sopenharmony_cicd packages/a && npm run test 1671cb0ef41Sopenharmony_ci``` 1681cb0ef41Sopenharmony_ci 1691cb0ef41Sopenharmony_ciEither will run the `test` script defined within the 1701cb0ef41Sopenharmony_ci`./packages/a/package.json` file. 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ciPlease note that you can also specify this argument multiple times in the 1731cb0ef41Sopenharmony_cicommand-line in order to target multiple workspaces, e.g: 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci``` 1761cb0ef41Sopenharmony_cinpm run test --workspace=a --workspace=b 1771cb0ef41Sopenharmony_ci``` 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ciOr run the command for each workspace within the 'packages' folder: 1801cb0ef41Sopenharmony_ci``` 1811cb0ef41Sopenharmony_cinpm run test --workspace=packages 1821cb0ef41Sopenharmony_ci``` 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ciIt's also possible to use the `workspaces` (plural) configuration option to 1851cb0ef41Sopenharmony_cienable the same behavior but running that command in the context of **all** 1861cb0ef41Sopenharmony_ciconfigured workspaces. e.g: 1871cb0ef41Sopenharmony_ci 1881cb0ef41Sopenharmony_ci``` 1891cb0ef41Sopenharmony_cinpm run test --workspaces 1901cb0ef41Sopenharmony_ci``` 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_ciWill run the `test` script in both `./packages/a` and `./packages/b`. 1931cb0ef41Sopenharmony_ci 1941cb0ef41Sopenharmony_ciCommands will be run in each workspace in the order they appear in your `package.json` 1951cb0ef41Sopenharmony_ci 1961cb0ef41Sopenharmony_ci``` 1971cb0ef41Sopenharmony_ci{ 1981cb0ef41Sopenharmony_ci "workspaces": [ "packages/a", "packages/b" ] 1991cb0ef41Sopenharmony_ci} 2001cb0ef41Sopenharmony_ci``` 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ciOrder of run is different with: 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_ci``` 2051cb0ef41Sopenharmony_ci{ 2061cb0ef41Sopenharmony_ci "workspaces": [ "packages/b", "packages/a" ] 2071cb0ef41Sopenharmony_ci} 2081cb0ef41Sopenharmony_ci``` 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ci### Ignoring missing scripts 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_ciIt is not required for all of the workspaces to implement scripts run with the `npm run` command. 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ciBy running the command with the `--if-present` flag, npm will ignore workspaces missing target script. 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci``` 2171cb0ef41Sopenharmony_cinpm run test --workspaces --if-present 2181cb0ef41Sopenharmony_ci``` 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_ci### See also 2211cb0ef41Sopenharmony_ci 2221cb0ef41Sopenharmony_ci* [npm install](/commands/npm-install) 2231cb0ef41Sopenharmony_ci* [npm publish](/commands/npm-publish) 2241cb0ef41Sopenharmony_ci* [npm run-script](/commands/npm-run-script) 2251cb0ef41Sopenharmony_ci* [config](/using-npm/config) 2261cb0ef41Sopenharmony_ci 227