NPM - Fork module, change code and send PR to author - node.js

For a particular npm package I want to create a PR with some code changes.. The author of the package told me, to create a PR from a particular branch..
All fine so far, I can change the url + branch inside the package.json and load the specific branch as npm module.. Also npm install works fine.
But then I want to change some code in that node_modules/module folder and create a PR from the code changes..
The only thing I can make to work for sure, is to first fork the entire repo in a separate folder, than checkout X branch, than change code, copy/past it to the node_modules/module folder every time I wanna check my code changes.. And than push it to my personal github page, and from there create a pull request..
But its really frustrating to copy/past my changes every time to the node_modules/module folder.
What is the best way to change a npm package and create PR for it, while still keeping the code inside the node_modules folder, so code changes can be checked?
Thanks!

This is the proper thing to do. Fork the github repo, create the branch that the guy told you, make the changes and send a pull request.
If you want to work in parallel and assuming that there are no compilation steps that npm should do, you can clone the forked repository within your node_modules and work directly there. As soon as you will make and commit the changes then you can send the pull request.
EDIT
I would say that this can be an acceptable approach that can work on linux:
~/projects/your-project/node_modules
~/projects/your-project/node_modules/name-of-module (symlink to the ~/projects/your-forked-cloned-repo)
~/projects/name-of-module (It should be your forked repo that you 've cloned from github/assembla etc)
~/projects/node_modules (symlink to the ~/projects/your-project/node_modules)

You're looking for npm link:
$ git clone your/npm-repo-fork
$ cd npm-repo-fork
# Link the project as a local dependency
$ npm link
$ cd ../some/other/project
# Use the linked project
$ npm link name-of-npm-dependency
# Now you can edit npm-repo-fork and the changes
# will be picked up by some/other/project
$ cd ../../../npm-repo-fork

Related

How to correctly push changes to Heroku

Currently whenever I make a change to some code I do the following in terminal:
git init
git add .
git commit -m "Some changes"
git push heroku master
I am not 100% certain, but this seems like it is redeploying the entire project and installing all packages again. If this is the case is there a way to only push the changes made?
For example, if I change one line of code, I just want to push that one file with the change, not the entire project again.
It depends how you're packaging the app, e.g. with webpack.config. Typically you'd package and deploy the entire project to the server each time. This is the correct way to do it (rather than just trying to replace one file), so that you can do project-wide actions like minifying code, processing your CSS, etc. The server would not download/install external packages that are already there unless you specify a different version in your package.json file.
git init only be oncethen every time you make a change just run
git add. (add all changes)
git commit -m "commit"
git push origin master
It's because react has to do some of its magic before Heroku can deploy it properly. That magic includes installing the node modules, compiling all the source files, and then optimizing everything before outputting the build folder with everything in it. There's not a 1:1 relationship between the one line in one file you changed and the build output - react requires a re-build.

Why does "npm install" modify package-lock.json? Why commit it to git then?

When I run "npm install" in a project it often modifies package-lock.json, for example if I work on the same project from another computer (with different node or npm version).
But at the same time the documentation suggests that the file is supposed to be added to version control (git in my case):
https://docs.npmjs.com/files/package-lock.json
This file is intended to be committed into source repositories, and
serves various purposes: ...
So should I commit the changes made by npm back and forth when switching work machines or when somebody else does npm install? This would be a nightmare.
Currently I just discard any changes to package-lock.json made by npm, and it's been working fine. So I might as well add it to .gitignore...
Am I doing it wrong? Should I use npm ci instead? I wouldn't call my computer a "CI", it's just a development machine, why should I use it there?
Basically I have the same question as this gentleman:
https://github.com/npm/npm/issues/18103#issuecomment-370401935
(Sadly I can't add a comment on that issue or create a new issue at all, the npm repo has issues disabled)
Yes you want to commit your package-lock.json file to source control. The reasoning behind this is to ensure that all of the same versions of each package are downloaded and installed for each user that pulls down the code. There are some other reasons to include the file such as tracking changes to your package tree for auditing.

Deploying node app with self-maintained NPM modules

I am developing a very complex app that is using internally developed, open source NPM modules.
I often need to change one of those modules (extra features, bug fixing, etc.) in order for the main application to work.
At the moment, I have:
A directory called my_modules, each containing a git repository one for each module. For example module1, module2.
A directory called my_apps, where for example there is app1 which has module1 as a dependency
Under my_apps/app1/node_modules I have module1 and module2, installed via NPM
In the server, deploy by pulling the git repository, running an npm install and npm dedupe, and running the server with forever.
At this stage, if I have to fix something in one of the modules, I:
Fix it within my_apps/app1/node_modules/module1 (not git)
When it's all working, COPY the files over to my_modules/module1 and do a git push and npm publish
The server will pull the latest modules after deploy thanks to npm install
This is way, way less than ideal. It's just too error-prone. However:
Having a symbolic link link my_apps/app1/node_modules/module1 => my_modules/module1 means that module1 will look for dependencies in its own path, which often causes problems (for example, I need to make sure that EVERY module uses the same copy of module1, which is imperative)
Having a git repo under my_apps/app1/node_modules/module1 feels dangerous, in case I accidentally overwrite changes using NPM on the module. Also, once fixed the change in the local git repo, I would still then need to pull the changes in my_modules/module1. Yes a step forward from copying files over...
What's the "recommended" way of dealing with this? Any best practices?

How can I switch between a linked npm dependency (in development) and an installed dependency (in staging/prod)?

I have a custom npm module that I am working on, and it has a GitHub repo. I'm also working on a project that uses the custom module. When working on the larger project, it is nice to use npm link so I can make changes to the module and see them right away in the main project.
To deploy to staging or production, I use shrinkwrap and shrinkpack so I can do an npm install after every deploy (some of the dependencies need binaries, and dev systems aren't the same as production systems, so they do need to be installed and not just kept in source control). Edit: I'm crossing this out as the answer below technically solves my issue, even though it doesn't solve for this particular point, but that wasn't as important as the rest of it.
Of course, since the module is linked to my main project and not listed in package.json, a deploy and install misses it entirely. I can go ahead and list it in package.json and have it point to the appropriate GitHub repo, but then every time I need to test a change in the main project I would have to commit and push those changes, then update the main project, kill and restart the app...that would get tiresome pretty quickly.
I guess I need something like the opposite of "devDependencies"; something where I can have it not install the module on dev, but do install it from GitHub when doing npm install on staging or production. Other than remembering to manually change package.json every time I need to go back and forth, is there a better way to do this?
you can specify a github repository as your package to install, in your package.json file:
{
dependencies: {
"my-library": "githubusername/my-library"
}
}
this will work in your production environment.
in your development environment, use "npm link".
from within the "my-library" folder, run npm link directly. that will tell npm on your local box that "my-library" is avaialable as a link.
now, in your project that uses "my-library", run npm link my-library. this will create a symlink to your local development version of "my-library", allowing you to change code in that repository and have it work in your other project that needs it.
once you are ready to push to production, push "my-library" to your github repository, and then you can npm install on your servers, like normal.

what is the best way to deal with local dependencies on submodules in node?

In our environment we have a node app with a dependency on a submodule which is also a node module. We ran into issues using npm link so we tried using local dependencies (i.e. setting the value of the dependency in package.json to file:./path/to/dep). The problem with this is that when you make a change in the submodule you have to then bump the version & update it in the parent. Is there a better way of dealing with this type of dependency so that I can just make changes in my submodule and have it just propagate to the parent?
If you want changes you make in your submodule to be reflected immediately in your main module, the only way I know to achieve that is to create a symbolic link from your main module's node_modules/ directory to your submodule's directory. I really recommend finding out why npm link doesn't work for you, because it's the nicest way to acieve this. However, if you want to, you can create the link manually too.
For instance, if your submodule's package name is 'wonderful' and your file structure looks like this:
main-module/
sub-module/
Then you can create a symbolic link main-module/node_modules/wonderful pointing to main-module/sub-module by running the following command from the root of the main module:
ln -s ../sub-module ./node_modules/wonderful
And then whatever change you make in the submodule will be immediately used in the main module.
Two notes on this:
Make sure main-module/node_modules/wonderful doesn't exist as an npm install-ed directory before creating the link, or it won't work.
When you npm install again, it will overwrite your symbolic link, so put the above command in a shell script if you want to execute it often.
When you make a change in the submodule, that means you have to make a commit in the parent repo (in order to record the new gitlink, a special entry in the index which memorize the new SHA1 of your submodule)
Why not use that commit opportunity to execute automatically a script which will modify the package.json file with the right information?
That is called a 'clean' script from a content filter driver:
(image shown in "Customizing Git - Git Attributes", from "Pro Git book")
The clean script is:
declared with git config filter.<filtername>.clean ./<filterscript>
used in a .gitattributes file.
Its function will be to fetch the version of the npm submodule and update the package.json file appropriately.

Resources