- 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|wscommand/alias - Add new folder
./lib/workspaces/*.js - Add default behavior that sets
prefixto 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:
d@1.0.0
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
+- foo@1.0.1
# 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_commandenvironment 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=coreand 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, wherebaris a workspace nested under thefooworkspace.-wis ambiguous between name and path, use name, and print a warning, because you can always donpm ws i -w core/or-w ./coreto 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:
-warg matches a workspace name, use that workspace by that name.-w=foowill match onlycore/foo(where package is namedfoo)-w=core/*will match./core/fooand./core/bar.-w=./corewill also match./core/fooand./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/barto 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=ainstead ofnpm ws i -w=a, just go through the appropriate code path when--workspacesconfig is set, and reservenpm wsfor 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 aworkspacesconfig, and pass it through without even looking at it, in some cases?