linklocal
is a development tool that the reduces overheads of breaking your application into small packages. It gives you more expressive power than simple files and folders, yet requires far less overhead than versioning and publishing packages to a local private registry.
Requires npm 2.0.0 and above in order for npm to recogise local paths as dependencies.
npm install -g linklocal
linklocal --help
Usage: linklocal [options] <dir>
Options:
-h, --help output usage information
-f, --format [format] output format
-l, --link Link local dependencies [default]
-r, --recursive Link recursively
-q, --unique Only unique lines of output
-u, --unlink Unlink local dependencies
--absolute Format output paths as absolute paths
--files Output only symlink targets (--format="%h") [default]
--links Output only symlinks (--format="%s")
--list Only list local dependencies. Does not link.
--long Output the symlink to hardlink mapping (--format="%s -> %h")
--no-summary Exclude summary i.e. "Listed 22 dependencies"
-V, --version output the version number
Examples
$ linklocal # link local deps in current dir
$ linklocal link # link local deps in current dir
$ linklocal -r # link local deps recursively
$ linklocal unlink # unlink only in current dir
$ linklocal unlink -r # unlink recursively
$ linklocal list # list all local deps, ignores link status
$ linklocal list -r # list all local deps recursively, ignoring link status
$ linklocal -- mydir # link local deps in mydir
$ linklocal unlink -- mydir # unlink local deps in mydir
Formats
%s: relative path to symlink
%S: absolute path to symlink
%h: relative real path to symlink target
%H: absolute real path to symlink target
relative paths are relative to cwd
npm 2.0.0 supports specifying local dependencies in your package.json:
> npm install --save ../apple
> cat package.json
{
"name": "bowl",
"version": "1.0.0",
"dependencies": {
"apple": "file:../apple"
}
}
npm install
will copy (and npm install
) the package into the target's node_module's hierarchy.
This is not an ideal workflow during development: any time you modify your local dependency, you must reinstall it in every location that depends on it. If you do not update all copies, you will have different versions of the same code, probably under the same version number.
Global npm link
dependencies are also not ideal as packages clobber each other across projects.
By symlinking local dependencies while in development, changes can be instantly consumed by dependees, effects are limited to the current package and you can be more certain local dependees are using the latest changes.
linklocal
symlinks both development and production dependencies.
linklocal
creates symlinks to any local dependencies it finds in your package.json.
e.g. test/banana/package.json.
{
"name": "banana",
"version": "1.0.0",
"private": true,
"dependencies": {
"apple": "file:../apple"
}
}
Note file:
dependencies are standard syntax in npm 2.x, just that npm will copy the dependency into place, rather than symlink it. That's what linklocal
is for:
# from test/banana
# find local dependencies and symlink them
> linklocal
node_modules/apple -> ../apple
Linked 1 dependency
> # proof:
> ls -l node_modules
total 8
lrwxr-xr-x 1 timoxley staff 11 20 Sep 01:39 apple -> ../../apple
You can unlink all local links using linklocal --unlink
.
# from test/banana
> linklocal --unlink
node_modules/apple -> ../apple
Unlinked 1 dependency
> ls -l node_modules
>
If your local dependencies themselves might have local dependencies, you can use
linklocal -r
to recursively link all local dependencies:
bowl
depends on banana
banana
depends on apple
apple
gets linked into banana
node_modules/apple -> ../apple
node_modules/banana -> ../banana
../banana/node_modules/apple -> ../apple
node_modules/@nuts/almond -> ../almond
Linked 4 dependencies
apple
does not get linked into banana
# from test/bowl
> linklocal
node_modules/apple -> ../apple
node_modules/banana -> ../banana
node_modules/@nuts/almond -> ../almond
Linked 3 dependencies
linklocal
does not install dependencies of linked dependencies. To have dependencies installed, use timoxley/bulk or xargs
in a script like:
{
"name": "my-app",
"scripts": {
"dev": "linklocal link -r && linklocal list -r | bulk -c 'npm install --production'",
"prepublish": "if [[ $NODE_ENV != 'production' ]]; then npm run dev; fi"
}
}
linklocal
does not install dependencies of linked dependencies, as such you typically end up installing dependencies of linked dependencies twice: once during npm install, then again after linklocal
MIT