How to interactively test the executable of an NPM Node.js package during development without constantly reinstalling the package? - node.js

Consider a simple sample module like this one.
The package exposes a dummy function something like:
index.js
const uniq = require('uniq');
function myfunc() {
return uniq([1, 2, 2, 3]).join(' ');
}
exports.myfunc = myfunc;
Then, an executable uses the function:
browserify-hello-world
#!/usr/bin/env node
const browserify_hello_world = require('browserify-hello-world');
console.log(browserify_hello_world.myfunc());
The package publishes both the index.js and the executable with:
package.json
"bin": {
"browserify-hello-world": "browserify-hello-world"
},
"dependencies": {
"uniq": "^1.0.1"
},
My question is, how to test the browserify-hello-world executable interactively during development?
If I just clone the repository and do:
npm install
./browserify-hello-world
then it fails with:
Error: Cannot find module 'browserify-hello-world'
because as documented at https://docs.npmjs.com/cli/install install does not install the current package itself under node_modules.
I got it close to working perfectly with:
npm link
npm link browserify-hello-world
./browserify-hello-world
which runs correctly because:
npm link:
creates a symlink from the global package install: ~/.nvm/versions/node/v10.15.1/lib/node_modules/broserify-hello-world to the source directory
runs npm install on the source directory, which creates node_modules with all dependencies
npm link browserify-hello-world creates a symlink from node_modules/browserify-hello-world to the global directory ~/.nvm/versions/node/v10.15.1/lib/node_modules/broserify-hello-world
which works well because everything is done with symlinks, so that updates to the local package are immediately visible to the executable.
The only downside of this method, besides the inconvenience of typing all those commands after install, is that afterwards during development, if I need to install a new dependency into the project, e.g. with:
npm install vaca
then that breaks by symlinks for some reason: node_modules/broserify-hello-world is gone, and I am forced once again to do:
npm link
npm link browserify-hello-world
Note that doind just npm link browserify-hello-world above does not work and fails with:
Error: Cannot find module 'uniq'
because the dependency of our package, uniq, was also removed by npm install vaca.
Is there a way to avoid redoing the link process after every new install?
The npm-safe-install module might exist to address this problem: https://github.com/UD-UD/npm-safe-install but when I tried it with:
npm install -g npm-safe-install
npm-safe-install vaca
although it did keep my node_modules/borwserify-hello-world symlink, it still removed the dependency uniq. I asked about that at: https://github.com/UD-UD/npm-safe-install/issues/4
Related threads:
https://github.com/npm/cli/issues/533
https://stackoverflow.com/questions/59357144/npm-package-development-run-executable
https://github.com/npm/cli/issues/2380
https://github.com/npm/npm/issues/1573
https://github.com/npm/npm/pull/8501
Tested with: npm 6.12.0, Node.js 10.15.1 installed with NVM and npm-safe-install 1.0.0.

Your issue has been resolved and changes are published with some added features. Changes are available in npm-safe-install#1.1.0. Hope it resolves your issue.

Related

Why doesn't npm install correctly build dependency from a fork of a package on npm?

I have a project that uses an older version of react-bootstrap
in my package.json I had
"react-boostrap": "^0.13.3"
And there is a bug in there that is causing an issue, the fix for it is very simple so I forked the repo, rolled back to the commit for v0.13.3 doing:
git reset --hard <commit-hash>
made my 1 line fix, then force pushed back to my fork.
Then I updated my package.json in the main project to point to my fork:
"react-boostrap": "mygithubrepo/react-bootstrap"
I deleted the node_modules directory and ran sudo npm cache clear to make sure everything was nice and fresh. Then I ran npm install which did pull down my version of react-bootstrap from the repo.
However, the version it now pulls down isn't in the same format in the node_modules folder. Essentially, it doesn't seem as if it's built the project.
If I use:
"react-boostrap": "^0.13.3"
then the node_modules folder contains the built code like so:
+node_modules
--+react_bootstrap
----+utils
-----Acordion.js
etc.....
But when I point it to my forked version of the repo:
"react-boostrap": "mygithubrepo/react-bootstrap"
Then I get just the source repo structure in node modules (and it doesn't seem to be built)
+node_modules
--+react_bootstrap
----+docs
----+ie8
----+src
-------+utils
--------Acordion.jsx
........etc.....
----+tools
etc.....
Now when I reference react bootstrap using require('react-bootstrap') then it doesn't work (because the files haven't been built).
So what is different between me pointing to the file on npmjs rather than on github? There isn't any prepublish/publish/postpublish script in react-bootstrap package.json so I'm not sure if they manually built it before pushing to npmjs.
Basically, I need to get my forked version automatically built when I run npm install on my main project. Any ideas?
Edit 1
The errors I get running npm install on the main project repo after updating my fork of react-bootstrap as per Jonathan Muller's answer below:
>> Local Npm module "grunt-contrib-uglify" not found. Is it installed?
>> Local Npm module "grunt-amd-wrap" not found. Is it installed?
>> Local Npm module "grunt-react" not found. Is it installed?
>> Local Npm module "grunt-contrib-clean" not found. Is it installed?
>> Local Npm module "grunt-contrib-watch" not found. Is it installed?
>> Local Npm module "grunt-contrib-copy" not found. Is it installed?
>> Local Npm module "grunt-browserify" not found. Is it installed?
>> Local Npm module "grunt-contrib-requirejs" not found. Is it installed?
Warning: Task "clean:amd" not found. Use --force to continue.
Aborted due to warnings.
In your package.json, add the following to build it when you npm install it:
{
"scripts": {
"postinstall": "grunt build"
}
}
This way the package will be built after install
Then to get it working with require, add the following to the package.json:
{
"main": "amd/react-bootstrap.js"
}
So the correct file can be found when you "require" it. Otherwise it search for index.js

`npm link --save` does not update dependencies on my package.json

I am using npm link package --save to create a local link to a globally installed package.
It correctly creates the link to the package (and would install it globally in case it were not already installed); but it fails to update the dependencies in package.json.
What I am missing here?
According the npm docs, npm link is not intended to change your package.json. It creates symbolic links on your file system for a package.
This allows you to still reference a module by name, but have it pull from your local filesystem:
cd ~/projects/node-redis # go into the package directory
npm link # creates global link
cd ~/projects/node-bloggy # go into some other package directory.
npm link redis # link-install the package
If you actually intend to insert a file path in your package.json, use npm install instead:
npm install --save /path/to/package
Then you'll see a reference in package.json file:
"dependencies": {
"local-package": "file:/path/to/package"
}
Though I highly recommend you use npm link instead, as it makes your package.json more portable. If you commit your changes with local file paths, it may become invalid on another system, or if you move around the files.
Update: Use npm-link-better
I created a little tool for this: npm-link-save
npm-link-save
npm-link with --save (or --saveDev) to save the linked dependency in your package.json.
You can also link multiple dependencies with this.
Install
npm i -g npm-link-save
Usage
npm-link-save express
# or
npm-links express
npm-links -D express // links in devDependencies
npm-links express morgan // multiple links
You're not missing anything, it's just not possible (yet).
There's an open feature request on the npm issue tracker (https://github.com/npm/npm/issues/1166).

How to install node.js modules downloaded manually [duplicate]

There are quite a few modules which are listed on node's github page but are not published with the npm-registry. These modules can't be installed using npm.
What is the correct way to install these nodejs modules after cloning them from Git?
You need to download their source from the github. Find the main file and then include it in your main file.
An example of this can be found here > How to manually install a node.js module?
Usually you need to find the source and go through the package.json file. There you can find which is the main file. So that you can include that in your application.
To include example.js in your app. Copy it in your application folder and append this on the top of your main js file.
var moduleName = require("path/to/example.js")
These modules can't be installed using npm.
Actually you can install a module by specifying instead of a name a local path. As long as the repository has a valid package.json file it should work.
Type npm -l and a pretty help will appear like so :
CLI:
...
install npm install <tarball file>
npm install <tarball url>
npm install <folder>
npm install <pkg>
npm install <pkg>#<tag>
npm install <pkg>#<version>
npm install <pkg>#<version range>
Can specify one or more: npm install ./foo.tgz bar#stable /some/folder
If no argument is supplied and ./npm-shrinkwrap.json is
present, installs dependencies specified in the shrinkwrap.
Otherwise, installs dependencies from ./package.json.
What caught my eyes was: npm install <folder>
In my case I had trouble with mrt module so I did this (in a temporary directory)
Clone the repo
git clone https://github.com/oortcloud/meteorite.git
And I install it globally with:
npm install -g ./meteorite
Tip:
One can also install in the same manner the repo to a local npm project with:
npm install ../meteorite
And also one can create a link to the repo, in case a patch in development is needed:
npm link ../meteorite
Edit:
Nowadays npm supports also github and git repositories (see https://docs.npmjs.com/cli/v6/commands/npm-install), as a shorthand you can run :
npm i github.com:some-user/some-repo
Download the code from github into the node_modules directory
var moduleName = require("<name of directory>")
that should do it.
if the module has dependancies and has a package.json, open the module and enter npm install.
Hope this helps
You can clone the module directly in to your local project.
Start terminal. cd in to your project and then:
npm install https://github.com/repo/npm_module.git --save
Step-by-step:
let's say you are working on a project use-gulp which
uses(requires) node_modules like gulp and gulp-util.
Now you want to make some modifications to gulp-util lib and test it locally with your use-gulp project...
Fork gulp-util project on github\bitbucket etc.
Switch to your project: cd use-gulp/node_modules
Clone gulp-util as gulp-util-dev : git clone https://.../gulp-util.git gulp-util-dev
Run npm install to ensure dependencies of gulp-util-dev are available.
Now you have a mirror of gulp-util as gulp-util-dev. In your use-gulp project, you can now replace: require('gulp-util')...; call with : require('gulp-util-dev') to test your changes you made to gulp-util-dev

How to specify local modules as npm package dependencies

I have an application which has the usual set of dependencies on third party modules (e.g. 'express') specified in the package.json file under dependencies. E.g.
"express" : "3.1.1"
I would like to structure my own code modularly and have a set of local (meaning on the file system I am currently in) modules be installed by the package.json. I know that I can install a local module by running:
npm install path/to/mymodule
However, I don't know how to make this happen via the package.json dependencies structure. Using the --save option in this command is simply putting "mymodule": "0.0.0" into my package.json (doesn't reference the filepath location). If i then remove the installed version from node_modules, and try to re-install from the package.json, it fails (because it looks for "mymodule" in the central registry, and doesn't look locally).
I'm sure the is a way of telling the "dependencies": {} structure that I want it to be installed from a file system path, but don't know how.
Anyone else had this problem?
Thanks.
npm install now supports this
npm install --save ../path/to/mymodule
For this to work mymodule must be configured as a module with its own package.json. See Creating NodeJS modules.
As of npm 2.0, local dependencies are supported natively. See danilopopeye's answer to a similar question. I've copied his response here as this question ranks very high in web search results.
This feature was implemented in the version 2.0.0 of npm. For example:
{
"name": "baz",
"dependencies": {
"bar": "file:../foo/bar"
}
}
Any of the following paths are also valid:
../foo/bar
~/foo/bar
./foo/bar
/foo/bar
syncing updates
Since npm install <folder> adds the package in the directory as a symlink in the current project any changes to the local package are automatically synced.
See: Local dependency in package.json
It looks like the answer is npm link: https://docs.npmjs.com/cli/link
I couldn't find a neat way in the end so I went for create a directory called local_modules and then added this bashscript to the package.json in scripts->preinstall
#!/bin/sh
for i in $(find ./local_modules -type d -maxdepth 1) ; do
packageJson="${i}/package.json"
if [ -f "${packageJson}" ]; then
echo "installing ${i}..."
npm install "${i}"
fi
done
After struggling much with the npm link command (suggested solution for developing local modules without publishing them to a registry or maintaining a separate copy in the node_modules folder), I built a small npm module to help with this issue.
The fix requires two easy steps.
First:
npm install lib-manager --save-dev
Second, add this to your package.json:
{
"name": "yourModuleName",
// ...
"scripts": {
"postinstall": "./node_modules/.bin/local-link"
}
}
More details at https://www.npmjs.com/package/lib-manager. Hope it helps someone.
You can just add to your package.json file in your project
"package-name" : "path/to/package"
and then run npm i in your project
At work we have a common library that is used by a few different projects all in a single repository. Originally we used the published (private) version (npm install --save rp-utils) but that lead to a lot of needless version updates as we developed. The library lives in a sister directory to the applications and we are able to use a relative path instead of a version. Instead of "rp-utils": "^1.3.34" in package.json it now is:
{
"dependencies": { ...
"rp-utils": "../rp-utils",
...
the rp-utils directory contains a publishable npm package
use install-local
I had issues with conflicting react installations from the local dependency.
I solved the error by using install-local npm package. This package does not create symlinks, which solved my issue.
Steps:
run npm i -g install-local
run npx install-local --save <local-path> inside the target repository to install the local dependency
Further reading: https://www.npmjs.com/package/install-local
The error I received, when trying to install the local package with npm install --save <local-directory>:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
If it's acceptible to simply publish your modules preinstalled in node_modules alongside your other files, you can do it like this:
// ./node_modules/foo/package.json
{
"name":"foo",
"version":"0.0.1",
"main":"index.js"
}
// ./package.json
...
"dependencies": {
"foo":"0.0.1",
"bar":"*"
}
// ./app.js
var foo = require('foo');
You may also want to store your module on git and tell your parent package.json to install the dependency from git: https://npmjs.org/doc/json.html#Git-URLs-as-Dependencies

How to install a node.js module without using npm?

There are quite a few modules which are listed on node's github page but are not published with the npm-registry. These modules can't be installed using npm.
What is the correct way to install these nodejs modules after cloning them from Git?
You need to download their source from the github. Find the main file and then include it in your main file.
An example of this can be found here > How to manually install a node.js module?
Usually you need to find the source and go through the package.json file. There you can find which is the main file. So that you can include that in your application.
To include example.js in your app. Copy it in your application folder and append this on the top of your main js file.
var moduleName = require("path/to/example.js")
These modules can't be installed using npm.
Actually you can install a module by specifying instead of a name a local path. As long as the repository has a valid package.json file it should work.
Type npm -l and a pretty help will appear like so :
CLI:
...
install npm install <tarball file>
npm install <tarball url>
npm install <folder>
npm install <pkg>
npm install <pkg>#<tag>
npm install <pkg>#<version>
npm install <pkg>#<version range>
Can specify one or more: npm install ./foo.tgz bar#stable /some/folder
If no argument is supplied and ./npm-shrinkwrap.json is
present, installs dependencies specified in the shrinkwrap.
Otherwise, installs dependencies from ./package.json.
What caught my eyes was: npm install <folder>
In my case I had trouble with mrt module so I did this (in a temporary directory)
Clone the repo
git clone https://github.com/oortcloud/meteorite.git
And I install it globally with:
npm install -g ./meteorite
Tip:
One can also install in the same manner the repo to a local npm project with:
npm install ../meteorite
And also one can create a link to the repo, in case a patch in development is needed:
npm link ../meteorite
Edit:
Nowadays npm supports also github and git repositories (see https://docs.npmjs.com/cli/v6/commands/npm-install), as a shorthand you can run :
npm i github.com:some-user/some-repo
Download the code from github into the node_modules directory
var moduleName = require("<name of directory>")
that should do it.
if the module has dependancies and has a package.json, open the module and enter npm install.
Hope this helps
You can clone the module directly in to your local project.
Start terminal. cd in to your project and then:
npm install https://github.com/repo/npm_module.git --save
Step-by-step:
let's say you are working on a project use-gulp which
uses(requires) node_modules like gulp and gulp-util.
Now you want to make some modifications to gulp-util lib and test it locally with your use-gulp project...
Fork gulp-util project on github\bitbucket etc.
Switch to your project: cd use-gulp/node_modules
Clone gulp-util as gulp-util-dev : git clone https://.../gulp-util.git gulp-util-dev
Run npm install to ensure dependencies of gulp-util-dev are available.
Now you have a mirror of gulp-util as gulp-util-dev. In your use-gulp project, you can now replace: require('gulp-util')...; call with : require('gulp-util-dev') to test your changes you made to gulp-util-dev

Resources