Skip to content

Commit 4c1f16d

Browse files
committed
feat: add init workspaces
Add workspaces support to `npm init` - Fixes `npm exec` respecting `script-shell` option value - Refactored `lib/exec.js` into `libnpmexec` - Updates [email protected] - Added ability to create a new workspace using the -w config PR-URL: #3095 Credit: @ruyadorno Close: #3095 Reviewed-by: @wraithgar
1 parent 2aecec5 commit 4c1f16d

31 files changed

+1405
-446
lines changed

docs/content/commands/npm-exec.md

+1
Original file line numberDiff line numberDiff line change
@@ -291,3 +291,4 @@ project.
291291
* [npm restart](/commands/npm-restart)
292292
* [npm stop](/commands/npm-stop)
293293
* [npm config](/commands/npm-config)
294+
* [npm workspaces](/using-npm/workspaces)

docs/content/commands/npm-init.md

+110-10
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ description: Create a package.json file
88

99
```bash
1010
npm init [--force|-f|--yes|-y|--scope]
11-
npm init <@scope> (same as `npx <@scope>/create`)
12-
npm init [<@scope>/]<name> (same as `npx [<@scope>/]create-<name>`)
11+
npm init <@scope> (same as `npm exec <@scope>/create`)
12+
npm init [<@scope>/]<name> (same as `npm exec [<@scope>/]create-<name>`)
13+
npm init [-w <dir>] [args...]
1314
```
1415

1516
### Description
@@ -18,19 +19,16 @@ npm init [<@scope>/]<name> (same as `npx [<@scope>/]create-<name>`)
1819
package.
1920

2021
`initializer` in this case is an npm package named `create-<initializer>`,
21-
which will be installed by [`npx`](https://npm.im/npx), and then have its
22+
which will be installed by [`npm-exec`](/commands/npm-exec), and then have its
2223
main bin executed -- presumably creating or updating `package.json` and
2324
running any other initialization-related operations.
2425

25-
The init command is transformed to a corresponding `npx` operation as
26+
The init command is transformed to a corresponding `npm exec` operation as
2627
follows:
2728

28-
* `npm init foo` -> `npx create-foo`
29-
* `npm init @usr/foo` -> `npx @usr/create-foo`
30-
* `npm init @usr` -> `npx @usr/create`
31-
32-
Any additional options will be passed directly to the command, so `npm init
33-
foo -- --hello` will map to `npx create-foo --hello`.
29+
* `npm init foo` -> `npm exec create-foo`
30+
* `npm init @usr/foo` -> `npm exec @usr/create-foo`
31+
* `npm init @usr` -> `npm exec @usr/create`
3432

3533
If the initializer is omitted (by just calling `npm init`), init will fall
3634
back to legacy init behavior. It will ask you a bunch of questions, and
@@ -40,6 +38,18 @@ strictly additive, so it will keep any fields and values that were already
4038
set. You can also use `-y`/`--yes` to skip the questionnaire altogether. If
4139
you pass `--scope`, it will create a scoped package.
4240

41+
#### Forwarding additional options
42+
43+
Any additional options will be passed directly to the command, so `npm init
44+
foo -- --hello` will map to `npm exec -- create-foo --hello`.
45+
46+
To better illustrate how options are forwarded, here's a more evolved
47+
example showing options passed to both the **npm cli** and a create package,
48+
both following commands are equivalent:
49+
50+
- `npm init foo -y --registry=<url> -- --hello -a`
51+
- `npm exec -y --registry=<url> -- create-foo --hello -a`
52+
4353
### Examples
4454

4555
Create a new React-based project using
@@ -71,6 +81,68 @@ Generate it without having it ask any questions:
7181
$ npm init -y
7282
```
7383

84+
### Workspaces support
85+
86+
It's possible to create a new workspace within your project by using the
87+
`workspace` config option. When using `npm init -w <dir>` the cli will
88+
create the folders and boilerplate expected while also adding a reference
89+
to your project `package.json` `"workspaces": []` property in order to make
90+
sure that new generated **workspace** is properly set up as such.
91+
92+
Given a project with no workspaces, e.g:
93+
94+
```
95+
.
96+
+-- package.json
97+
```
98+
99+
You may generate a new workspace using the legacy init:
100+
101+
```bash
102+
$ npm init -w packages/a
103+
```
104+
105+
That will generate a new folder and `package.json` file, while also updating
106+
your top-level `package.json` to add the reference to this new workspace:
107+
108+
```
109+
.
110+
+-- package.json
111+
`-- packages
112+
`-- a
113+
`-- package.json
114+
```
115+
116+
The workspaces init also supports the `npm init <initializer> -w <dir>`
117+
syntax, following the same set of rules explained earlier in the initial
118+
**Description** section of this page. Similar to the previous example of
119+
creating a new React-based project using
120+
[`create-react-app`](https://npm.im/create-react-app), the following syntax
121+
will make sure to create the new react app as a nested **workspace** within your
122+
project and configure your `package.json` to recognize it as such:
123+
124+
```bash
125+
npm init -w packages/my-react-app react-app .
126+
```
127+
128+
This will make sure to generate your react app as expected, one important
129+
consideration to have in mind is that `npm exec` is going to be run in the
130+
context of the newly created folder for that workspace, and that's the reason
131+
why in this example the initializer uses the initializer name followed with a
132+
dot to represent the current directory in that context, e.g: `react-app .`:
133+
134+
```
135+
.
136+
+-- package.json
137+
`-- packages
138+
+-- a
139+
| `-- package.json
140+
`-- my-react-app
141+
+-- README
142+
+-- package.json
143+
`-- ...
144+
```
145+
74146
### A note on caching
75147

76148
The npm cli utilizes its internal package cache when using the package
@@ -93,10 +165,38 @@ requested from the server. To force full offline mode, use `offline`.
93165
Forces full offline mode. Any packages not locally cached will result in
94166
an error.
95167

168+
#### workspace
169+
170+
* Alias: `-w`
171+
* Type: Array
172+
* Default: `[]`
173+
174+
Enable running `npm init` in the context of workspaces, creating any missing
175+
folders, generating files and adding/updating the `"workspaces"` property of
176+
the project `package.json`.
177+
178+
the provided names or paths provided.
179+
180+
Valid values for the `workspace` config are either:
181+
- Workspace names
182+
- Path to a workspace directory
183+
- Path to a parent workspace directory (will result to selecting all of the
184+
children workspaces)
185+
186+
#### workspaces
187+
188+
* Alias: `-ws`
189+
* Type: Boolean
190+
* Default: `false`
191+
192+
Run `npm init` in the context of all configured workspaces for the
193+
current project.
194+
96195
### See Also
97196

98197
* [init-package-json module](http://npm.im/init-package-json)
99198
* [package.json](/configuring-npm/package-json)
100199
* [npm version](/commands/npm-version)
101200
* [npm scope](/using-npm/scope)
102201
* [npm exec](/commands/npm-exec)
202+
* [npm workspaces](/using-npm/workspaces)

docs/content/commands/npm-run-script.md

+1
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,4 @@ project.
204204
* [npm restart](/commands/npm-restart)
205205
* [npm stop](/commands/npm-stop)
206206
* [npm config](/commands/npm-config)
207+
* [npm workspaces](/using-npm/workspaces)

docs/content/using-npm/config.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1087,7 +1087,8 @@ installation of packages specified according to the pattern
10871087
* Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows
10881088
* Type: null or String
10891089

1090-
The shell to use for scripts run with the `npm run` command.
1090+
The shell to use for scripts run with the `npm exec`, `npm run` and
1091+
`npm init <pkg>` commands.
10911092

10921093
#### `searchexclude`
10931094

0 commit comments

Comments
 (0)