Use different node module depending on environment? - node.js

I have a npm package that we use for multiple projects. Currently when I want to make a change to something on these projects that requires a change on the npm package I need to make a change to the npm package, submit a pr, wait for someone to merge it for me and then I can actually test the changes I made on the other projects (no testing is set up currently sadly).
What I want to do is on the other projects have a way to install / use the local module instead of the global one so I can test the full flow before I submit any prs. Im using config package and ideally I can set it up so if I use a specific config file it defaults to local npm package instead of global.
Is this possible?

Based on what you are describing, take look at the link command offered by package managers to help solve this:
https://classic.yarnpkg.com/en/docs/cli/link#search
https://docs.npmjs.com/cli/v8/commands/npm-link

Related

NodeJS sub-projects installation

I have a large project that contains multiple sub-modules, many of which are optional. And I have each sub-module sitting in its own folder with local package.json.
I'm trying to figure out the best way to create an integral package.json that would be able to run npm install on a specific subset of those modules.
Question
Is there a more civilized approach these days than just running npm install from every sub-module folder? I want to be able to halt the integral installation when it fails for one module, and hopefully do it on a declarative level within package.json, rather than implementing such logic myself. Plus, I want postinstall-s run on each package (if present), and then one of the integration package.
Other than that, maybe there is a better way today to manage such projects? I'm open to any suggestions!

Modify npm package outside npm modules folder

I am using react-gantt-timeline (https://www.npmjs.com/package/react-gantt-timeline ) library and need to modify css and some javascript to meet my demand. I tried to fork and then link back my project in which I was successful but my it's not a good solution since I need to also maintain the forked project.
In that case what will be the standard way to modify the npm package outside of npm module?
One way I was thinking is to import the css and javascript locally and then modify it. But I was unable to refer them properly.

Updating angular code dynamically when conditions are met in nodejs code

I was looking for something that can update the code automatically on certain conditions. It is similar to how the new dependencies are added to the package.json file, when we do an npm install.
How to make it possible ?
Explaining Further - When I run a command (in node), I have some code in some other folder (Angular)- the command will update the code like for example inserting new imports.
If you want to use Angular CLI +1.7 and update all dependency package you can use ng upadte
running the ‘update’ command will check for changes in the auto
generated files that come with angular projects out-of-the-box and you
be ask if you want to overwrite the existing with the new. You will
also be prompted to choose from four options, y(yes), n(no),
d(difference) and h(help). Choose with discretion.

Preventing global installations of an NPM package

I have a library and want to encourage/force users to use the locally installed version only. I could do this the hard way or the easy way.
The easy way would be if NPM had a mechanism to prevent using the --global switch with the npm install command, for any library.
The hard way would be to add code in my NPM packaged that returned early if the code determined it was globally installed not locally installed.
Does anyone know if you can prevent global installations of an NPM package? What might be the most user friendly way to approach this?
The best way to prevent users from installing your module globally would be to describe your preference in the documentation.
There is nothing you can do to force your users to never install it globally if they can install it locally. They will always be able to move the files manually if they want.
In the npm community the assumption is that the user has control over the modules he/she uses, not the other way around. Forcing people to use your module in certain ways will only make them unhappy.
So the only good answer to your question is to document the way your code should be used. You can ask them to use your module a certain way - but they are the ones who can choose to listen to you or not. You can state that using your module installed globally is unsupported, unwise, discouraged, dangerous, but you will not be able to force users to use the module as you want, and that's a good thing.
Now, for some bad answers, you can always test if the parent of your module's root directory is named node_modules or not and fail if it isn't but I'm sure it can cause some trouble if someone happens to install your module locally as you want but under a different directory. You can see if your module is run from one of the default paths that node uses to search for modules but those paths are not always the same, and you'd have to take the NODE_PATH environment variable into account as well.
You can do few tricks like that but they can only annoy users who know what they are doing because they will have to change the source code of your module to do what they want, and they will always be able to do that, no matter how hard you try to make their life harder.
In summary, my recommendation would be to document your module well and respect your users and their needs, and trust them to know what they're doing.
Update
For a working example of a Bash function that prevents global npm installation of a certain module, see this answer - section Working example of preventing global install.

Including local dependencies in deployment to lambda

I have a repo which consists of several "micro-services" which I upload to AWS's Lambda. In addition I have a few shared libraries that I'd like to package up when sending to AWS.
Therefore my directory structure looks like:
/micro-service-1
/dist
package.json
index.js
/micro-service-2
/dist
package.json
index.js
/shared-component-1
/dist
package.json
component-name-1.js
/shared-component-2
/dist
package.json
component-name-2.js
The basic deployment leverages the handy node-lambda npm module but when I reference a local shared component with a statement like:
var sharedService = require('../../shared-component-1/dist/index');
This works just fine with the node-lambda run command but node-lambda deploy drops this local dependency. Probably makes sense because I'm going below the "root" directory in my dependency so I thought maybe I'd leverage gulp to make this work but I'm pretty darn new to it so I may be doing something dumb. My strategy was to:
Have gulp deploy depend on a local-deps task
the local-deps task would:
npm build --production to a directory
then pipe this directory over to the micro-service under the /local directory
clean up the install in the shared
I would then refer to all shared components like so:
var sharedService = require('local/component-name-1');
Hopefully this makes what I'm trying to achieve. Does this strategy make sense? Is there a simpler way I should be considering? Does anyone have any examples of anything like this in "gulp speak"?
I have an answer to this! :D
TL;DR - Use npm link to link create a symbolic link between your common component and the dependent component.
So, I have a a project with only two modules:
- main-module
- referenced-module
Each of these is a node module. If I cd into referenced-module and run npm link, then cd into main-module and npm link referenced-module, npm will 'install' my referenced-module into my main-module and store it in my node_modules folder. NOTE: When running the second npm link, the name of the project is the one you find in your package.json, not the name of the directory (see npm link documentation, previously linked).
Now, in my main-module all I need to do is var test = require('referenced-module') and I can use that to my hearts content. Be sure to module.exports your code from your referenced-module!
Now, when you zip up main-module to deploy it to AWS Lambda, the links are resolved and the real modules are put in their place! I've tested this and it works, though not with node-lambda yet, though I don't see why this should be a problem (unless it does something different with the package restores).
What's nice about this approach as well is that any changes I make to my referenced-module are automatically picked up by my main-module during development, so I don't have to run any gulp tasks or anything to sync them.
I find this is quite a nice, clean solution and I was able to get it working within a few minutes. If anything I've described above doesn't make any sense (as I've only just discovered this solution myself!), please leave a comment and I'll try and clarify for you.
UPDATE FEB 2016
Depending on your requirements and how large your application is, there may be an interesting alternative that solves this problem even more elegantly than using symlinking. Take a look at Serverless. It's quite a neat way of structuring serverless applications and includes useful features like being able to assign API Gateway endpoints that trigger the Lambda function you are writing. It even allows you to script CloudFormation configurations, so if you have other resources to deploy then you could do so here. Need a 'beta' or 'prod' stage? This can do it for you too. I've been using it for just over a week and while there is a bit of setup to do and things aren't always as clear as you'd like, it is quite flexible and the support community is good!
While using serverless we faced a similar issue, when having the need to share code between AWS Lambdas. Initially we used to duplication the code, across each microservice, but later as always it became difficult to manage.
Since the development done in Windows Environment, using symbolic links was not an option for us.
Then we came up with a solution to use a shared folder to keep the local dependencies and use a custom written gulp task to copy these dependencies across each of the microservice endpoints so that the dependency can be required similar to npm package.
One of the decisions we made is not to keep two places to define the dependencies for microservices, so we used the same package.json to define the local shared dependencies, where gulp task passes this file and copy the shared dependencies accordingly also installing the npm dependencies with a single command.
Later we made the code open source as npm modules serverless-dependency-install and gulp-dependency-install.

Resources