- RFC TODAY:
npm fund --workspace=a
- RFC TODO CHANGE:
npm ws fund --workspace=a --workspace=b --workspace=group-name
Adding a top-level workspaces|ws
command should abstract enough the implementation to make it flexible enough to accomodate future tweaks in the workspace installing algorithm.
- Add new
workspaces|ws
command/alias - Add new folder
./lib/workspaces/*.js
- Add default behavior that sets
prefix
to top-level commands under./lib/workspaces/default.js
- Add
ws run-script
- Add
ws install
(ie. scoped installs) - Add
ws install <pkg>
- Add
ws ci
- Add
ws update
- Add
ws uninstall
- Add
ws outdated
(ie.cd ./ && npm outdated
, might need tweaking Arborist to only load from a specific tree node) - Add
ws ls
(ie.cd ./ && npm ls
) - Add ``
- Should run commands over multiple workspaces
- (no args) run command across all workspaces
- (
-w=<workspace-name>
named option) filter by only defined names
- Should support
--parallel
(defaults to--serial
) - ref. https://www.npmjs.com/package/npm-run-all
./lib/workspaces.js `npm workspaces|ws`
./lib/workspaces/default.js <- default... tries `prefix` + <command> / warn if we couldn't do anything...
./lib/workspaces/install.js <- some cmds require special logic
./lib/workspaces/publish.js <- would set `prefix` & then include ./lib/publish.js
...
# The default behavior is to run the command setting the prefix to workspace realpath, e.g:
npm ws publish -w name
# Might be effectively the same as:
npm publish --prefix=<workspace-name>
# Assuming `npm publish` is a command that won't need special tweaks/impl
npm ws install -w name
# ^--- "scoped install": *only* reify the packages for the workspace defined, e.g:
root:
dependencies:
[email protected]
workspaces:
a -> foo@^1.0.0 -> c@1
b -> foo@^1.0.1 -> c@2
$ npm ws install -w a
node_modules
+- a -> ../a
+- c@2
+- [email protected]
# NOTE: just be mindful of deduping (ie. you'd get c@2 if all workspaces
# were being installed... you should still get it if you only specify `a`)
# NOTE2: arborist will not place `d` within `node_modules` for
# a "scoped install"
# Adding a new dep to a workspace:
$ npm ws install -w <workspace-name> <pkg> -> ./lib/workspaces/install.js
# ^--- <pkg> will be installed as a
# dep of workspace-name
npm install <pkg>
Arborist
root:
- <pkg> <-- add user request
npm ws install <pkg> -w <workspace-name>
Arborist
root:
- workspace-name:
- <pkg> <-- add user request under workspace-name instead
npm ws <command> -w|--workspace=<pkg-name|group-alias>
A simple way to refer to a set of workspace by using a single name, e.g:
.
+- core
+- foo
+- plugins
+- lorem
+- ipsum
With a root package.json
defining both workspaces packages and groups:
{
"name": "workspace-example",
"version": "1.0.0",
"workspaces": {
"groups": {
"plugins": ["lorem", "ipsum"],
"common": ["foo"]
},
"packages": [
"core/*",
"plugins/*"
]
}
}
Running: npm ws install abbrev -w plugins
effectively means adding abbrev as a dep to both lorem
and ipsum
and reifying the tree.
Arborist needs API for:
{complete:true}
buildIdealTree for everything other than the workspace(s) being reified, so that we can write the package-lock.json fully.This (ie, the CLI) needs at least stub API for:
npm ws list --workspace=a
, which runs npm ls under workspace a)npm ws i -w=core/*
? Should we support the paths/globs as well as the name?npm_command
environment var set to when I runnpm ws test
?"ws"
or"test"
?Idea, for when we do dig into ws groups: maybe the folder is the group, and we just have that be the opinionated convention? Ie, if you have
packages: [ "core/*", "plugins/*" ]
then you can use-w=core
and that'll pick up all the packages undercore/*
.For the future, nested workspaces? Could we ever imagine
npm ws -w foo ws -w bar install
? Would run the install inpackages/foo/packages/bar
, wherebar
is a workspace nested under thefoo
workspace.-w
is ambiguous between name and path, use name, and print a warning, because you can always donpm ws i -w core/
or-w ./core
to make it only match the path.This will never work:
npm ws i -w core/*
, because the shell will expand that tonpm ws i -w core/foo core/bar core/baz
. Butnpm ws i -w=core/*
ornpm i -w "core/*"
would work fine.So, suggestion:
-w
arg matches a workspace name, use that workspace by that name.-w=foo
will match onlycore/foo
(where package is namedfoo
)-w=core/*
will match./core/foo
and./core/bar
.-w=./core
will also match./core/foo
and./core/bar
, because it's a partial path.-w core/*
will not work, and we aren't going to try to reverse engineer from-w core/foo core/bar
to what the user might have actually typed into the shell. (nopt is weird and broken, but at least it's weird and broken in one place.)Action item: @isaacs write RFC for parsing cli options more strictly finally, with warnings in npm v8 for what will break in npm v9.
npm i -w=a
instead ofnpm ws i -w=a
, just go through the appropriate code path when--workspaces
config is set, and reservenpm ws
for management of workspaces config.npm ws add
,npm ws ls
,npm ws rm
, etc. Implementation-wise, that's a little bit trickier though, maybe? Might need Arborist to be able to just take aworkspaces
config, and pass it through without even looking at it, in some cases?