A command line utility to ease the link
-ing of local npm modules,
especially when link
-ing modules with peerDependencies
.
In short, if you use npm link
a lot.
Alternatively, if:
- When developing, you put all your npm modules in a directory, aka workspace, and you expect they will link together magically.
- You have a number of private npm and you use
npm link
to link them together. - You have local working copies fo your public npm modules, but you prefer to
link
them when developing. - You also have peerDependencies, and
npm link
doesn't exactly work well with that. - You ended up writing a shell script to handle any of the above, but you are not satisfied with the results.
npm install -g npm-workspace
myNodeJsWorkspace
├── prj1
│ ├── lib
│ └── package.json
├── prj2
│ ├── src
│ └── package.json
├── prj3
│ ├── index.js
│ └── package.json
└── workspace.json
With:
{
"name": "prj1",
"version": "0.0.1",
"private": "true",
"dependencies": {
"request": "~2.26.0", <- A "normal" dependency
"prj2": "0.0.1" <- A local dependency, want to npm link that
}
}
{
"name": "prj2",
"version": "0.0.1",
"peerDependencies": {
"underscore": "~1.5.1", <- Normal peer dependency, this WILL NOT be installed
in your parent module, if you 'npm link'
this package (prj2)
"prj3": "0.0.1" <- Local peer dependency, this WILL NOT be installed
in your parent module, if you 'npm link'
this package (prj2)
}
}
{
"name": "prj3",
"version": "0.0.1",
"peerDependencies": {
"optimist": "~0.6.0", <- This becomes a nested peerDependencies
if you consider that prj1->prj2->prj3
}
}
Now instead of doing this
cd myNodeJsWorkspace
cd prj3
npm link
cd ../prj2
npm link
cd ../prj1
npm link prj2
npm link prj3
npm install underscore
npm install optimist
npm install
you can just...
Create a workspace.json
in your workspace dir, and create mappings module name -> module dir
{
"links": {
"prj2": "prj2",
"prj3": "prj3"
}
}
Then
cd myNodeJsWorkspace
npm-workspace install
cd myNodeJsWorkspace/prj1
npm-workspace install
cd myNodeJsWorkspace
npm-workspace clean
When you are ready to deploy your app, you can package all your modules for production, including all your private/local only modules. Just use these 3 options:
-c
: Copy the packages intonode_modules
instead of linking them-g
: Remove.git
directories from dependencies while copying. This is so you can package your production app under a new repo (e.g. for use in a PaaS)-p
: Installs only production dependencies (ignoresdevDependencies
)
Example
cd myNodeJsWorkspace/yourapp
npm-workspace install -cgp
Your app is now ready for deployment.
If you have a few dependencies that come from custom registries, you can add a repos
map to workspace.json
:
{
"links": { ... },
"repos": {
"name-of-module": "http://location.of.registry"
}
}
This allows mixed registry sources until @scope
s are fixed.
Sometimes it will be convenient to execute a script in your modules only during the installation of your workspace.
To do this, add a script named npm-workspace:install
to the module's package.json
:
{
"scripts": {
"npm-workspace:install": "..."
}
}
When you execute npm-workspace install
the script will run after the module has been installed (in the same way that
install
or postinstall
scripts are.
- It finds and parse the links from the nearest
workspace.json
up in the current directory tree. - For each module:
- If a link was specified in
workspace.json
: creates a local symbolic link (as opposed tonpm link
that creates a global link) for each matching module independencies
anddevDependencies
- Otherwise,
npm install
all the remaining modules
- If a link was specified in
- For each module linked, install or link its
peerDependencies
(recursively)
npm-workspace
should work with npm
1, 2 and 3. To support this npm-workspace
takes a conservative approach, with each dependency being added independently.
The installation of Peer Dependencies depends partly on the npm
version used, but linked peer dependencies should be correctly fulfilled.
The following npm
issues currently have direct work-arounds in npm-workspace
:
- The ultimate solution to your Node.js development workflow/private modules/deployment/etc/etc/etc/