How to deal with dependencies when deploying a node.js app? - node.js

I'm setting up a gulp build file for a node.js project and I really don't have any experience with either of them.
So basically what I'm doing is simply copying all the code to a deployment directory, but I'm unsure of how to handle all the dependencies that are stored in node_modules. Do you simply copy all of them as well, or is there a more preferred way of doing it?
gulp.task('deliver', function() {
gulp.src('src/*.html').pipe(gulp.dest('deployment/'));
gulp.src('src/*.js').pipe(gulp.dest('deployment/'));
gulp.src('src/games/').pipe(gulp.dest('deployment/'));
});

The standard way would be to have a package.json file that lists all your dependencies. Then as part of your deployment process run npm install which will go through your package.json and install any necessary packages in the node_modules folder.

Related

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.)

Best practice for nodejs deployment - Directly moving node_modules to server or run npm install command

What is the best practice for deploying a nodejs application?
1) Directly moving the node_modules folders from the development server to production server, so that our same local environment can be created in the production also. Whatever changes made to any of the node modules remotely will not affect our code.
2) Run npm install command in the production server with the help of package.json. Here the problem is, any changes in the node modules will affect our code. I have faced some issues with the loopback module (issue link).
Can anyone help me?
Running npm install in production server cannot be done in certain scenario (lack of compiling tools, restricted internet access, etc...) and also if you have to deploy the same project on multiple machines, can be a waste of cpu, memory and bandwidth.
You should run npm install --production on a machine with the same libraries and node version of the production server, compress node_modules and deploy on production server. You should also keep the package-lock.json file to pinpoint versions.
This approach allows you also to build/test your code using development packages and then pruning the node_modules before the actual deploy.
Moving node_modules folder is overkilled.
Running npm install might break the version dependencies.
The best approach is npm ci. It uses the package_lock file and installs the required dependencies without modify the versions.
npm ci meant for continuous integration projects. LINK
I am an ASP.NET Core developer but I recently started working with Node.js apps. For me this was one of the challenges you mentioned to move the node_modules folder to production. Instead of moving the whole folder to production or only running the npm install command on production server, I figured out and tried a way of bundling my Node.js app using Webpack into a single/multiple bundles, and I just got rid of the mess of managing node_modules folder. It only picks up the required node_modules packages that are being used/referred in my app and bundles up in a single file along with my app code and I deploy that single file to production without moving the entire node_modules folder.
I found this approach useful in my case but please suggest me if this is not the correct way regarding the performance of the app or if any cons of this approach.
Definitely npm install. But you shouldn't do this by your own hand when it comes to deploying your app.
Use the tool for this like PM2.
As for your concern about changes in packages, the short answer is package-lock.json.
My guess is that by asking this question you don't really understand the point of the package.json file.
The package.json file is explicitly intended for this purpose (that, and uploading to the npm registry), the transfer of a node package without having to transfer the sizeable number of dependencies along with it.
I would go as far as to say that one should never manually move the node_modules directory at all.
Definitely use the npm install command on your production server, this is the proper way of doing it. To avoid any changes to the node_modules directory as compared to your local environment, use the package lock file. That should help with minimising changes to the source code in node_modules.
I mean no bad intent by saying this

Build strategies for utilizing npm packages

This must be a commonly solved problem, but I cannot find a whole lot on Google/SO so far.
When we run npm install and fetch say 50+ packages including devDependencies as well as runtime dependencies, npm creates node_modules (if needed) and adds each of those packages inside that folder. This means we end up with thousands of extraneous files included under node_modules. Each of those packages contains their own package.json, README.md, minified files, source files, etc. Our application really only cares about jquery.js (for DEV) and jquery.min.js (for PROD), so it seems to be a waste to include all of these other files into our build and therefore our web server.
Is there a standard when it comes to handle these npm packages in a way so that we simply expose ONLY the necessary files to the user? I imagine many people have this kind of issue but I don't see any built in npm constructs that allow us to do this easily.
See below.. the yellow highlighted files are the only files we really care about in Production, but we get all these extra files as well including the source code.
The most common solution consist of bundling your application on a different machine and then expose the built artefacts on production server.
There are a lot of great JS bundlers out there. The ones I have personally used are Browserify, Webpack, and Rollup. All amazing tools.
The main idea consists of writing your application in a Node environment and then bundle it to make it readable to the browser.
For simpler projects I find Browserify a very good compromise between power and ease of configuration. But it's a matter of taste, at the end. :)
Base on what I read about npm install documentation I do not think there is a option to manipulate the installation in the way you want. The packages will install the way the package author decides to package it, sometimes minified sometimes not.
Having said that, you should look for third party solutions like modclean which does exactly what you want post package installation. Run this command in the root of your project directory
npm install modclean -g
modclean
As long as your test coverage is good, ModClean would be perfect for your need.
Edit the package.json file and remove all the unnecessary dependencies then do
npm install --save
By doing this, it will create a local node_modules folder and only download the necessary packages into it (not the global node_modules folder)
Keep in mind, by default, node checks for local node_modules folder. If it couldn't find it, it will use the global folder.
Also, you don't expose all the packages in the node_modules folder. In fact, they will not be used unless you require(); them in the node.js file
EDIT:
For jQuery to work in Node, a window with a document is required. Since no such window exists natively in Node, one can be mocked by tools such as jsdom. This can be useful for testing purposes. https://www.npmjs.com/package/jquery
require("jsdom").env("", function(err, window) {
if (err) {
console.error(err);
return;
}
var $ = require("jquery")(window);
});
So jquery module do things a bit differently behind the scene for node.js comparing to the regular front-end jquery.
It requires jsdom so you will have to download that as well from here https://github.com/tmpvar/jsdom

Node.js npm dependencies in subfolder

I have a project in which I use node-webkit. node-webkit allows npm packages to be used for developing desktop applications. I make use of grunt to build my application.
My folder structure looks like this at the moment:
project root
node_modules/ (1)
package.json (1)
App/
node_modules/ (2)
package.json (2)
bower.json
bower_components/
...
controllers/
filters/
...
app.js
The npm dependencies for the application itself are kept within the App folder, but the dev dependencies for building the project are not related to the application source code, so i keep them in node_modules (1) inside the root folder. I also know that in a package.json file one can express dependencies and dev dependencies, exactly for this reason. I would rather have one package.json file in the root expressing ALL dependencies, including dev dependencies, but i would rather have a separation of those dependencies on folder level.
Two questions arise:
Is this a good way to organize my npm dependencies? If yes, awesome? If no, which I expect:
What is a better way to organize my dependencies? Is it possible to specify that dev dependencies go into folder a, and 'regular' dependencies go into folder b? If so, how do I do this?
In case anyone is wondering, this is the project i am talking about:
https://github.com/michahell/pinbored-webkit
[updated folder structure to include app.js for clarity]
It is perfectly fine to keep more than one package.json file and multiple node_module directories for a project. If you consider the parts as separate components.
An example might be if, you have one directory containing a node server, another containing a react app, and a third containing some kind of deployment script written in javascript.
#Michael package.json file contains all the dependencies related to that project.There is no need for multiple package files and multiple node_modules folders..
But you need to check where is your App.js file!!
your App.js , package.json must be in same folder unless configured.

is it necessary to have node_modules folder created for every project while using grunt

while using grunt node_modules directory is created for every project I create and their is a lot of duplication going on, which I don't like....
I am using grunt-collections now but it is very inefficient, and looking for an alternative solution for this.
I don't know much about node but is it not possible to use grunt modules from the central node_modules directory within nodejs directory????
Edit:
Is their any way to install packages globally...????
yes, it is necessary. First, to deal with grunt version mismatch issues, all the global grunt command really does is delegate to a local grunt dependency installed in your project's node_modules directory.
Second, you really want a local version of your grunt plugins/modules as well. Having everything installed locally to each project allows you to have two separate projects on the same machine that depend on different versions of the same grunt plugin. This would not be possible if everything was installed globally.

Resources