Is there an equivalent to java .war files for NPM? - node.js

Using gradle and java, I can build and publish (into a local repository) various versions. If a deployment has issues, I can reroll by deploying a prior version.
I can't find anything comparable for NPM applications, e.g. vue.
I foun npm pack which seems to build something that I can later install via npm install.
But I could not find out I then "run" the application. Are the any good documentations?
Thanks in advance.

Unline Jave Javascript doesn't compile into anything (because its interpreted). This means that all you need it the source code.
A basic node app source code will look something like this
main.js # entrypoint
packege.json # dependencies
src/ # application codebase
So if you like to create an artifact that can be deployed to a server you need only to download the dependencies (that's what the npm install is for) and that's it basically.
Now a node_module directory will be created
main.js # entrypoint
packege.json # dependencies
src/ # application codebase
node_module/ # dependencies codebase
You can run the application with node run main.js. But if you are creating an artifact you should bundle (zip) all the files and upload then to a file server (this will be the closest thing to .war in this flow)
You can now unzip and run the node application on a server that has NodeJS installed.

Related

Use npm install to deploy a node application?

Say I have a node.js application (some web server for the manner of sake). So I have a directory structure with a src which contains my code and a package.json which includes some metadata about my project and all the packages needed to run it. So I run npm install to get all the packages and run node server.js to run the application.
I have a CI pipeline for my application that upon PR to master runs tests, and if succeeds, merges to master. The next step I want is to deploy the application on a server.
This means that eventually I need my source code plus all the dependencies on the server, and run node server.js.
Is it correct to publish my application as a package (as part of the CI pipeline), and then on the server run npm install to fetch it? Or is npm installing packages only makes sense for packages that serve as some functionality for other applications?
The reason I doubt this is that when you run npm install (at least on a directory with a package.json) you get all the packages in the node_modules directory, which makes me believe that the second option I stated is true.
NOTE
The application is running on a Windows server, no Dockers.

How to generate a production build of an API done with NESTJS

I am generating the production version of an API I made using the NESTJS framework and would like to know which files I should upload to the server. When I run the "npm run start: prod" compile it generates the "dist" folder but I tried to run only with it but it is not enough to run my application. Do I need to upload all files to the server? I did several tests removing the folders I used during development but only managed to run in production mode when I was all the same in dev mode.
I looked in the documentation for something about this but found nothing. can anybody help me?
Thank you
Honestly, you should only really need the dist folder as that's the JS 'complied' files. To run your application, commonly you'd use this command node dist/main.js. As to what files you upload it's up to you. Me personally, I use a lot of continuous integration so I would just clone to repo into my container/server and use yarn start:prod. This is so everytime I deploy I'm generating the required files to run in a production environment.
Like #Kim Kern mentioned, some node modules are native built using node-gyro; so it's also always best to build your node_modules on the server/container when deploying. Your deployment script should look something like this
git clone git#github.com:myuser/myrepo.git /var/www/
cd /var/www/
node -v && \
yarn && \
yarn build && \
yarn start:prod
The above script should
1) pull the required repo into a 'hosted' directory
2) check the node version
3) install node_modules and build native scripts etc
4) build the production distribution
5) run the production JS scripts
If you look in your package.json file you'll notice the different scripts that are run when you use yarn start, yarn start:dev and yarn start:prod. When in dev you'll notice the use of ts-node which is a typescript node runner type thing (can't remember the correct phrase). Also the start:dev script uses nodemode to restart the ts-node script. You'll also see the start:prod script uses node dist/main.js and that the prestart:prod script runs rm -rf dist && tsc which removes the dist folder and 'compiles' the javascript required for a production environment.
However, the drawback of a typescript application on your server without continuous integration is that there is the possibility of typescript compilation errors which you wouldn't see or know about until running the prod scripts. I would recommend putting a procedure in place to compile the javascipt from typescript before making a deployment as you don't want to delete the current dist build before knowing the next release will build and run!
For me this approach worked and all you need is the dist folder for this:
Create a prod build of your application using npm run start:prod, this would create a dist folder within your application source
Copy the dist folder to your server.
For getting all the node_modules dependencies on your server just copy your package.json file into the dist folder (that you have copied onto the server) and then run npm install from there.
If you are using pm2 to run your node applications just run pm2 start main.js from within the dist folder
Mostly, you will only need the dependencies in node_modules. You should build the libraries on your server though instead of copying them from your dev machine. Libraries like bcrypt have machine specific code and probably won't run on a different machine. (30% of the npm libraries have native bindings.)
So for your deployment I would recommend to checkout your git repository on your server and then just run npm run start:prod (which builds the project every time) directly there.
Just use the Nest-CLI and build with
nest build
Afterwards you get a dist folder with the compiled Code.
You can then place it on a server an run e.g. with PM2 proccess manager:
production=true pm2 start dist/main.js
In former command the environment variable production is set to true. That could e.g. be usefull when running the Nest.js server over HTTPS.
If you want to run a HTTPS secured server you also have to include the certificates in the starting process of the server. When the environment variable production is set and true the certificates get included in the starting proccess of the Nest.js application in main.ts like following:
async function bootstrap() {
let appConfig = {}
if (process.env.production) {
console.log('process env production: ', process.env.production)
const httpsOptions = {
key: fs.readFileSync('/etc/certs/letsencrypt/live/testtest.de/privkey.pem'),
cert: fs.readFileSync('/etc/certs/letsencrypt/live/testtest.de/fullchain.pem'),
}
// prod config
appConfig = {
httpsOptions,
}
}
const app = await NestFactory.create<NestExpressApplication>(
AppModule,
appConfig,
)
app.enableCors()
app.setGlobalPrefix('v1')
await app.listen(3300)
}
bootstrap()
We don't build our application on production, but instead build it when creating our docker container.
The steps for us roughly are:
Run npm install and whatever tooling you need to build the application.
Create docker container and copy dist/, node_modules and package.json
Inside the docker container run npm rebuild bcrypt --update-binary
We are using NX for monorepo where we hold our API's. And we use docker for our images and containers. When we have to create docker image, only run: npx nx build <project> and this generate build on dist/apps/<project>. This folder goes to the docker image, with the package.json and that's it. You don't need to add node_modules, because they are on the package.json. Just be sure to include npm install on your Dockerfile.

How to install and deploy node.js application?

I'm new to node.js. After creating modularized project with express, tests, .nvmrc etc. it's finally time to deploy the app. How it should be done? in java you bundle your project into a single file, self containing and you put in into a server with some configuration. what about node.js?
Should i just copy the whole directory with sources and node_modules to production machine and use systemd, pm2 or other process manager to just run it? but i heard some of the dependencies might be system-dependend so they may work incorrectly
or should i copy only sources and run npm install --production on the production machine? but this way the deployment is only possible when npm repositories are online. also it takes time to build the application and it has to be done on all machines in the cluster. also what about quickly rolling back to previous version in case there is some bug? again, time and online npm repos are needed
another option is to build a docker image. but it seems awkward that the only way to easily and safely deploy the app is using third party technology
how it's being done in real life scenarios?
sure don't copy the whole directory especially node_modules.
all the packages installed on your system should be installed with --save option example: npm install --save express if you do so you will have in your package.json the dependencies required for your project whether they are dev dependencies or production dependencies.
I don't know what your project structure looks like, but as a node application you have to run npm init . in your project to setup the package.json file and then you can start adding your dependencies with --save.
usually we use git
version control system
to deploy to the server, first we push our code to a git repository then we pull from it to the server git
you have to add .gitignore in your project and ignore node_modules from being committed to your git repository.
then you can pull to your server and run npm install on the server. and sure you need to launch your web server to serve your application example ngnix
you can try Heroku for an easy deployment, all you have to do is to setup your project with Heroku, and when you push your code, Heroku manages the deployment . Heroku

Best practice for distributing a nodejs command line application

How do people expect a nodejs commandline application to be organised when you distributed it via npm?
Would they expect to have to build it? Install it locally or globally? Should it always output a bin.js? Do you need some kind of alias / script to run it (via bin.js?).
Use the bin field in package.json to specify the entrypoint javascript file for your CLI.
Add #!/usr/bin/env node to the top of your entrypoint js file.
Specify the files which need to be packaged with your app, using the files field of package.json
In README, provide an npm install command line which a consumer can use to install your app, for example it could point at a github repository, or a package uploaded to the npm registry, which you can create with npm pack.
Upon installing the app locally or globally, a script will be created in the path (or locally in node_modules/.bin), which will let your command line app be run conveniently.

Deploying grunt based app in CloudControl

I'm trying to deploy a grunt based app to CC. I would like to deploy the dist version of the app, which is generated with the grunt build task. Right now, what I've done is to move my grunt devDependencies to dependencies and use the NPM postinstall hook to run the grunt build task. This way once updated NPM dependencies CC runs the task.
But, I've two issues with this approach:
1) compass is not working
2) it just doesn't feel correct to move all my grunt dependencies to dependencies. The first issue I think that I could fix it using another SCSS grunt module.
Any other alternative approach? Preferably I don't want to save my dist builds in the repository.
Can you please explain the situation a little bit more?
Normally I would follow the following steps
Local
Do the npm install
Do the grunt build
push to the cloud
Server
Set the environment as production(assuming that all your files check for the environment and load files accordingly)

Resources