How to use fork version of npm package in a project - node.js

Let's say there is an npm package called abcd.
Normally in package.json, we specified the dependencies as
"abcd": "^1.0.0",
But this abcd does not work as expected, so I forked (and modified) it inside https://github.com/mygithubid/abcd
Then I run npm install git+https://git#github.com/mygithubid/abcd.git and in package.json, the definition is changed to
"abcd": "git+https://github.com/mygithubid/abcd.git",
After restarting the project that using this abcd, now it throws error
Module not found: Can't resolve 'abcd'
... even though I saw the abcd folder is added inside node_modules
Could you advise the mistake I made in above? Thanks!

One fairly clean option is to use patch-package:
https://www.npmjs.com/package/patch-package
If the people using your project might use either npm or yarn, then remeber to make the patch available for both. More info under patch-package --use-yarn.
Patch or fork? See https://www.npmjs.com/package/patch-package#benefits-of-patching-over-forking

Be sure that the github repository contains compiled files, at most cases you need build the package for npm first, the compiled files push only to NPM.
To find out how to build the package check the package.json file

Related

Is there a way to specify different paths for the same dependencies in package.json?

I am working on an npm package that includes an example directory to run/test the actual package. In the example directory, I have included back the parent package using "file:..".
This works fine when developing and making frequent changes to the parent package, but if I want to use the example as a stand-alone app, I would need to point to the actual npm package.
Is there a way to have "2 configs" in the same package.json:
one that points to `"file:.." for local development
one that points to the npm package to use as a stand-alone app
This would avoid duplicating the example directory
You could do this with lerna which is a mono-repository CLI tool.
First of all, you would have to define multiple projects within the same repository. Lerna calls these projects "packages" and stores all of them within a /packages folder.
package.json
/packages
/my1stPackage
package.json
/my2ndPackage
package.json
Lerna has all kind of optimizations, which I won't dive in too deep here. But there are a couple of basics:
to initially install all dependencies of all repos, run lerna bootstrap --hoist.
You can still run npm run ... as before, but those refer to your root package.json file. To run npm scripts for specific sub-package you should run lerna run <args> -scope=<packageName>. (e.g. lerna run build --scope=my1stPackage)
You can add shortcuts for this in the root /package.json script section.
"scripts": {
"setup": "lerna bootstrap --hoist",
"build:my1stPackage": "lerna run build --scope=my1stPackage"
}
What will interest you most, is that sibling packages can just reference each other from their specific package.json to include each other as dependencies.
So, let's assume that my1stPackage uses my2ndPackage. Inside the package.json file of my1stPackage there would be something like
"dependencies": {
...
"my2ndPackage": "^0.0.1"
}
The my2ndPackage could actually be a package which is published in npm. However (!) while developing locally, lerna will add a symbolic link inside the /packages/my1stPackage/node_modules/my2ndPackage, which points to the folder of /packages/my2ndPackage. (And that really does work on all relevant operating systems.)
You package.json looks the same for local development as it does for people who download your package through npm. However, it's your lerna setup that fixes this with this symbol link.
I found two potential ways to do this:
npm link : https://docs.npmjs.com/cli/v7/commands/npm-link/
npm workspaces : https://docs.npmjs.com/cli/v7/using-npm/workspaces
But in my specific case, there are packages that can conflict between the parent and child (example) packages.
I couldn't find a robust way to make it work and decided that the simpler approach would be to simply create a separate repository that would contain a stand-alone version of the example directory and a script that can keep it up to date with the "master example" in the original repository. This way development stays fast and the "example copy" is easy to keep up to date without duplicating code.

Why is my Node.js package missing the main file when installed globally?

This feels like an embarrassing question to ask but having recently published a Node package to the NPM registry, I now find it doesn't work.
The issue seems to be that my main file, ./src/index.js, isn't being included in the global install.
I know this because when I call the package from the command line it
runs ./bin/cli.js in the package as expected, but then throws:
Error: Cannot find module '../src/index.js'
Require stack:
- /usr/lib/node_modules/diffcraft/bin/cli.js
The error even references the line in ./bin/cli.js where the index
file is required, so that's definitely where the problem is.
I also know this because I checked the folder where the module is
installed globally and while the bin folder is there, the src
folder isn't. So the main code for my package just isn't there.
After discovering this, I even patched package.json to ensure that ./src/index.js was explicitly whitelisted in the files array. I hadn't done this before as NPM guidance states that whichever file is listed under main is also automatically whitelisted. But even including the file in files explicitly hasn't worked.
For reference, I don't have an .npmignore file.
I've got a horrible feeling I'm missing something simple and basic... Any ideas why my main file might be being skipped?
The package is diffcraft.
It works if you omit the ./ in front of the files (tested with npm 6.14.4 on Windows):
"files": [
"bin/cli.js",
"src/index.js"
],
This might be a bug in npm.
You can check this without publishing by running npm pack and checking the archive file.
Alternative is using an .npmignore file.

How to modify an npm package built with TypeScript

I want to try and make some changes to a package published in npm? (I've suggest some changes as an issue but I think they are simple enough for me to attempt them).
https://www.npmjs.com/package/bt-presence#contributing--modifying
The author supplies some information on how to modify the package, but not really enough for someone doing it for the first time.
Where should I clone the GitHub repo to? The folder where the package is installed? I tried it in my home folder and that would not build (unmodified).
The command npm run build - where is this run from? The root folder of the package where the package.json is?
Will I need to modify the package.json?
In general what is the best way to develop something like this for npm? I've worked on packages before but they were simply Javascript.
If you want to work on the bt-presence package in isolation, you can put the cloned repository anywhere. If you want to use your modified version of bt-presence in combination with an application, my recommended approach is to register bt-presence as a dependency in the application's package.json file with the version set to a relative path to your bt-presence repository; then running npm install in the application will make a symlink from node_modules/bt-presence in the application to your bt-presence repository.
npm run build should indeed be run from the root folder that contains the package.json of bt-presence.
If you just want to change the code of bt-presence, you won't need to modify its package.json. You would only modify the package.json if you need to change any of the settings in there, e.g, if you need to add additional dependencies to your version of bt-presence.
None of the above is really specific to TypeScript. (Some JavaScript packages have build processes too if they need to transform or package the JavaScript files in some way.)

Error when trying to reference a github repository

I am using angular 2 and I am trying to reference a github repo directly instead of an npm package in order to debug but the project does not compile.
In my packages.json I changed "primeng": "4.2.2", with "primeng": "git+https://github.com/primefaces/primeng.git"
When I build I get following errors
ERROR in multi ./node_modules/simple-line-icons/css/simple-line-icons.css ./node_modules/font-awesome/css/font-awesome.css ./node_modules/famfamfam-flags/dist/sprite/famfamfam-flags.css ./node_modules/bootstrap-select/dist/css/bootstrap-select.css ./node_modules/jquery.uniform/dist/css/default.css ./node_modules/toastr/build/toastr.css ./node_modules/sweetalert/dist/sweetalert.css ./node_modules/jstree/dist/themes/default/style.min.css ./node_modules/jtable/lib/themes/metro/blue/jtable.min.css ./node_modules/morris.js/morris.css ./node_modules/bootstrap-daterangepicker/daterangepicker.css ./node_modules/bootstrap-switch/dist/css/bootstrap3/bootstrap-switch.min.css ./src/app/shared/core.less ./src/app/shared/layout/layout.less ./src/assets/bootstrap-datepicker/css/bootstrap-datepicker.min.css ./node_modules/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css ./src/styles.css ./src/fonts.css ./src/Test-palette.css ./src/app/risk-management/styles/module-styles.css ./src/primeng-chips.css ./src/primeng-datatable.css ./src/primeng-multiselect.css ./src/primeng-sidebar.css ./src/animations.css ./node_modules/primeng/resources/primeng.min.css ./node_modules/primeng/resources/themes/redmond/theme.css ./node_modules/#angular/material/prebuilt-themes/indigo-pink.css ./node_modules/loaders.css/loaders.min.css
Module not found: Error: Can't resolve 'C:\SourceControl\Test\TestProject\src\TestProject.Client\node_modules\primeng\resources\primeng.min.css'
When I check the node modules/primeng I only see these files:
What am I doing wrong?
NPM primeng package was built for distribution and has resources directory, while Github repository contains only source files. This is very common among NPM packages.
Since Github repo source is used for the purpose of debugging, the solution is to build the package manually. Considering that resources are built with Gulp and not generic NPM build script, it should be something like:
cd ./node_modules/primeng
npm i
gulp build-assets
You do not need the github.com prefix there, this should be enough:
"primeng": "primefaces/primeng"
More about this here: https://docs.npmjs.com/files/package.json#github-urls
Problem is that the resources folder is ignore via .gitignore. There is a gulpfile.js, that is responsible for creating it. You could run that manually if you want to use github version directly.
https://github.com/primefaces/primeng/blob/master/gulpfile.js

npm update unlinks linked packages

I have a project, which consists of one root node package containing subpackages linked together by npm link - these subpackages depend on each other (listed in package.json dependencies) and the structure basically looks like this:
-rootpackage
--subpackageA
--subpackageB
Lets say subpackageA has dependency on subpackageB, so I link them to avoid publishing/reinstalling subpackageB in subpackageA after every change in the source of subpackageB.
The link works just fine until I run npm update in subpackageA, which causes the subpackageB to be unlinked.
Now, I see two options:
I can theoretically run the npm link operation after each npm install or npm update to ensure the links are always present. This works with postinstall in case of installation, but in case of an update the postinstall is not called. I don't know any postupdate command for npm, which is to be called after update.
Maybe there is a way to do this more cleverly, perhaps with yarn, which I am also using, in a way, that it kind of prevents unlinking or excludes the update for my subpackages, so I don't lose the links between my subpackages, but right now I am not aware of such a way.
Is there any way to make one of those options work or any other way to solve this problem ? I need to keep this and other links so we don't have to run npm link after every installation/update. I can't really find information about this issue anywhere. Btw I am using Node 6.4.0 and NPM 3.10.3.
So the solution is to use Yarn Workspaces or maybe project like Lerna.
Yarn Workspaces is a utility that expects a structure similar to what was described in the question and which maintains the linking subpackages and root automatically. It is very easy to set up (just 2 lines in root package.json and executing yarn for the first time) and after it you don't have to worry about upgrade or install at all, the links stay in place unless you delete them manually.
Lerna expands on that and provides you with additional tooling for managing multipackage projects. It can use Yarn Workspaces internally for the linking if you use yarn but it is not a requirement and works fine with npm. Just make sure to have Git because last time I checked Lerna didn't work with SVN or other VCSs.

Resources