The Why
Linking dependencies straight to a main project might speed up development.
Obviously npm packages are standalone, independent modules hence do not need to be used by a “main” app whilst being developed.
However, there are scenarios when a module needs to be worked on with the main application hooked to it.
Examples:
- end to end testing module
- module breaks down in a scneario that is hard to replicate
The natural way to do it would be updating dependency source then copyying files to node_modules
/module folder in root project. Perhaps copying the whole project there and edit files straight away
A much niftier solution is getting npm link to work for us.
The Goal
Having a node application running whilst working on one of it’s dependency.
Changes in dependency should be reflected straight away in main app, without copyying any files manually.
TL/DR
1cd npm-link-package2npm link3cd npm-link-project4npm link npm-link-package5ls -l node/modules/6lrwxr-xr-x 1 andras staff 79 2 Sep 18:42 npm-link-package -> ../../../../../../.nvm/versions/node/v10.16.3/lib/node_modules/npm-link-package
The How
We’ll create two projects
- npm-link-project
- npm-link-package
The npm-link-project
depends on npm-link-package
. By the end oif this post, you’ll understand how making changes in npm-link-package
project can be reflected immediately in the root project.
Creating projects
Package - dependency - project
This is the package that will serve as dependency.
Create directory and jump in it
1mkdir npm-link-package && cd "$_" && touch index.js
Initializing default node app
1npm init -y23### output ###45{6 "name": "npm-link-package",7 "version": "1.0.0",8 "description": "",9 "main": "index.js",10 "scripts": {11 "test": "echo \"Error: no test specified\" && exit 1"12 },13 "keywords": [],14 "author": "",15 "license": "ISC"16}
Adding code
Open an editor and update index.js
.
1module.exports = function log(message) {2 console.log(`Logger says "${message}"`);3};45/* this is only to kick it off from command line*/6if(require.main == module) {7 module.exports('blah')8}
Main project
This project will use the above as dependency.
Create directory, jump in it then create index.js
.
1mkdir npm-link-project && cd "$_" && touch index.js
Initialize a default node app
1npm init -y23### output ###45{6 "name": "npm-link-project",7 "version": "1.0.0",8 "description": "",9 "main": "index.js",10 "scripts": {11 "test": "echo \"Error: no test specified\" && exit 1"12 },13 "keywords": [],14 "author": "",15 "license": "ISC"16}
Create npm links
Linking dependency project to main project
In order to link dependency to main project’s node_modules
folder, the below two things need to be done
- a global symlink for the dependency. This symlink adds (well, links) the dependency project under npm’s global node_modules
1npm global home2└───node_modules3 └───npm-link-package
Note: run npm list -g | head -n 1
to get global home folder.
- a symlink from the main project pointing to the linked folder above It might be slightly confusing at this point. Don;t worry, it is actually much simpler than it looks so let’s create them.
Create global symlink
Again, this will be a symlink that links dependency project under npm’s global node_modules folder
1cd npm-link-package2npm link3...45/Users/andras/.nvm/versions/node/v10.16.3/lib/node_modules/npm-link-package -> /Users/andras/work/npm-link-package
There is no magic here, could have done the same with a standard symlink
1$ ls -l /Users/andras/.nvm/versions/node/v10.16.3/lib/node_modules2total 03drwxr-xr-x 24 andras staff 768 16 Aug 05:30 npm4lrwxr-xr-x 1 andras staff 62 26 Aug 18:30 npm-link-package -> /Users/andras/work/npm-link-package
Create symlink from main project to global npm_modules/npm-link-package
1cd npm-link-project2npm link npm-link-package3/Users/andras/work/npm-link-project/node_modules/npm-link-package -> /Users/andras/.nvm/versions/node/v10.16.3/lib/node_modules/npm-link-package -> /Users/andras/work/npm-link-package
Let’s try it out
Add index.js to main project
1const log = require('npm-link-package')23log('I can be called from project');
Then run it
1$ node index.js2Logger says "I can be called from project"
For the sake of it, update index.js in package project
1module.exports = function log(message) {2 console.log(`v2 logger says "${message}"`);3};
Then run it
1$ node index.js2v2 logger says "I can be called from project"
Delete npm links
Once work on dependency is done, links may be deleted.
1cd npm-link-project2npm uninstall npm-link-package3cd npm-link-package4npm uninstall
Afrer running the above, all symlinks hould be gone
1# main project2ls -l node_modules/34# npm global for dependency project5ls -l /Users/andras/.nvm/versions/node/v10.16.3/lib/node_modules/
Cover photo by Samarth Shirke on Unsplash