Npm link
Npm link
Npm link is a command that allows us to create a symlink between a global package and a local package. This is particularly useful when we are developing a package and want to test it in a real project.
Link a global package to a local package (local node project)
In the local package directory, run npm link
to create a symlink in the global folder.
Say we want to make a local package available globally we can (example: clone @notifii-network/notifi-react-card
to our local machine) run npm link
in the package directory.
Output
Then this local package is linked to the global folder. we can confirm it through npm list -g --depth 0
.
Output
Output
Consume the global package
We can consume the linked package in any node project by running npm link <package-name>
in the project directory.
Here is an example node project in the @notifi-network/notifi-react-card
is consumed. we can just simply run npm link @notifi-network/notifi-react-card
in the project directory. It will override the
@notifi-network/notifi-react-card
package in the node_modules
folder with the symlink if it exists.
Output
To check the symblink packages that we are using in the project, we can run npm ls --link=true
Two possible outputs:
- If this dependency is already defined in the
package.json
file, the error will be thrown.
Conflict case
- We remove the dependency from the
package.json
file, then it shows
Normal case
Then we can make the change locally in the @notifi-network/notifi-react-card
package and test it in the project. The change will be reflected immediately. 🎉🎉🎉🎉🎉🎉🎉
Unlink the global package
If we no longer want to use the local package in the project, we can run npm unlink <package-name>
in the project directory.
Output
To use back the original npm package, we will need to define it back in the package.json
file and run npm install
to install it.
If you're using npm link to link the local package (ex. @notifi-network/notifi-react-card
package ) to your project, you may see a linting error in VS Code that suggests adding the package to your project's dependencies.
To get rid of this error, you can add the following line to your project's .eslintrc file:
Example
To get rid of this error, you can add the following line to your project's .eslintrc.json
file. Replace the "/Your/global/node_modules/node_modules"
with your global node_modules path.
{
"settings": {
"import/resolver": {
"node": {
"paths": ["src"],
"extensions": [".js", ".jsx", ".ts", ".tsx"],
"moduleDirectory": [
"node_modules",
"/Your/global/node_modules/node_modules"
]
}
}
}
}
This configuration tells ESLint to resolve imports using the src directory as the root directory, and to look for modules in both the node_modules and global node_modules directory.
This should allow ESLint to resolve the @notifi-network/notifi-react-card package correctly, even though it's not listed in your project's dependencies.
yarn link
Simiilarily, yarn also has a command called yarn link
that does the same thing as npm link
.
Here we also want to have a small use case to demonstrate how to use yarn link
.
Register a package (A
) to the global folder
Under the A
package directory, run yarn link
to register the package to the global folder.
Output
Then we can see the A
package is registered in the global folder by running
# macOS & Linux
ls ~/.config/yarn/link
Unregister the package (A
)
We can also unregister the package by running yarn unlink
in the A
package directory.
Output
Consume the global package in another project (B
)
Under the B
package directory, run yarn link A
to consume the global package A
.
Output
Then we are able to use local A
package in the B
project without pushing the changes to the npm registry.
Unlink the global package
To unlink the global package, we can run yarn unlink A
in the B
project directory.
❯ yarn unlink A
yarn unlink v1.22.19
success Removed linked package "A".
info You will need to run `yarn install --force` to re-install the package that was linked.
✨ Done in 0.04s.
Then we can run yarn install --force
to install the original package back.
yalc
npm or yarn link is a good way to test the local package in the project. However, the symbolic linking solution might not work in all cases especially we have so many bundler tools like webpack, rollup, etc. in the project.
NPM and Yarn address this issue with a similar approach of symlinked packages (npm/yarn link). Though this may work in many cases, it often brings nasty constraints and problems with dependency resolution, symlink interoperability between file systems, etc. Quoted from yalc doc
yalc
in this case is a good alternative to npm link
or yarn link
.
Working flow of yalc with small example
We will use one of my local packages @notifii-network/notifi-react-card
and vue-dummy-project
as example to showcase how to use yalc
.
@notifii-network/notifi-react-card
is a local package that we want to test in thevue-dummy-project
project.vue-dummy-project
is a vue project that we want to test the@notifii-network/notifi-react-card
package.
Step 1: npx yalc publish
When you run yalc publish
in the package directory, it grabs only files that should be published to NPM and puts them in a special global store (located, for example, in ~/.yalc).
So lets run npx yalc publish
in the @notifii-network/notifi-react-card
package directory.
❯ cd ~/.yalc
❯ ls
installations.json packages
❯ cd packages
❯ ls
@notifi-network
❯ cd @notifi-network
❯ ls
notifi-react-card
~/.y/packages/@notifi-network
Step 2: npx yalc add
When you run yalc add <package>
in your project it pulls package content into .yalc in the current folder and injects a file:/link: dependency into package.json
So we can run npx yalc add @notifi-network/notifi-react-card
in the vue-dummy-project
project directory.
❯ npx yalc add @notifi-network/notifi-react-card
Package @notifi-network/notifi-react-card@0.84.0 added ==> /Users/macbookpro4eric/Projects/notifi/ref/vue-dummy-project/node_modules/@notifi-network/notifi-react-card
Other operation
yalc also have some other operations that might also be useful such as remove
, installation
.
Checkout the yalc doc for more details.
We need to be cautious that the bundler for some reason might not rebuild the updated package. For example .next
(next project) or .vite
(vite project) folder might not be updated. In this case, we need to manually remove the folder and rebuild the project.
It might not be straightforward in the beginning because bundling tools tends to cache the package. So we need to be cautious about this. To make sure all the cache is cleared. Following are the steps to do so:
- For dependency projects
# this example we have 3 packages to publish
# 1. rebuild the dependency projects: in this case the mono repo notifi-sdk-ts
npm run build && \
# 2. remove the all the yalc packages in `~/.yalc/packages/@notifi-network`
rm -rf ~/.yalc/packages/@notifi-network && \
# 3. publish the packages
npx yalc publish ./packages/notifi-react/ && \
npx yalc publish ./packages/notifi-frontend-client/ && \
npx yalc publish ./packages/notifi-graphql/
- For the main project (In this case, we use SvelteKit project powered by Vite)
#1 remove the possible cache folders and files
rm -rf .yalc node_modules yalc.lock && \
#2 Re-add the yalc packages
npx yalc add @notifi-network/notifi-react @notifi-network/notifi-frontend-client @notifi-network/notifi-graphql
#3 Re-install npm packages and start the project in dev
npm install && npm run dev
Then we are ready to go 🔥🔥🔥🔥🔥🔥🔥