When working locally on a NodeJS project, nodemon is required in order to make the coding easier.
I frequently see the cases when it's installed as a dev-dependency only, so I wonder: what is the correct approach when it comes to deployment? Should we include it as a dev-dependency only, or should we include it into the server as well?
In this project I have, I see nodemon installed as regular dependency and then in the package.json configs:
"scripts": {
"start": "nodemon src/app.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
But I am thinking to install it as a dev-dependency only and then to rework the config like:
"scripts": {
"start-prod": "node src/app.js",
"start-dev": "nodemon src/app.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
So I wonder if this will be a correct approach?
I don't see a reason why on the server I would watch the file changes with nodemon, so I wonder if I got it right? In case sometimes it is needed, what are the possible cases when that will be required?
Short answer: You don't require nodemon in production.
According to nodemon on npm:
nodemon is a tool that helps develop node.js based applications by automatically restarting the node application when file changes in the directory are detected.
It is a tool to help in development, mainly restart the app server on file changes. You can add it to dev dependencies if you want to run nodemon via scripts. Otherwise you can install it globally.
npm install -g nodemon # or using yarn: yarn global add nodemon
And nodemon will be installed globally to your system path.
You can also install nodemon as a development dependency:
npm install --save-dev nodemon # or using yarn: yarn add nodemon -D
Edit:
If you want to keep your app alive even in case of any crash, you should consider using pm2.
PM2 is a production process manager for Node.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks.
I have a question regarding the script property in package.json of my app. If I type npm start, the app gets compiled successfully. And it seems that by typing the above command, www file starts running.
However, if I type npm webpack, nothing happens. I have a react/express app. And the server runs on localhost:3000 on npm start. I want to know, is webpack serving both react and express? I am able to send requests from the client to the server and show the result on the client-side. I just wanted to know how things are working.
"scripts": {
"start": "NODE_ENV=development nodemon ./bin/www",
"webpack": "webpack-dev-server --config ./webpack.config.js --mode development"
}
for other scripts than "start", you have to type npm run [scriptname].
in your case: npm run webpack
I am building an app using nodejs and express framework and have installed nodemon globally to restart the server automatically.
Now if I take this app and run in another machine/host/environment (without nodemon installed globally) then it would produce an error because package.json doesn't contain nodemon as a dependency.
What would be the best way to fix this?
Include nodemon in your package.json as a dev dependency. So it will be available in the context of the script.
{
"scripts": {
"start": "nodemon my_file.js"
},
"devDependencies": {
"nodemon": "<version>",
}
}
Then from the terminal you can use npm start
Nodemon has been the goto for a long time, but now with Node.js 19, we have --watch flag, which restarts server when files changes. Keep in mind this is experimental
Docs
:)
Here's the situation
nodemon ./app
works great.
nodemon "./app"
does not.
This results in nodemon constantly starting and restarting without ever actually running ./app. Why is this a relevant you may ask? Consider the following.
webpack-dev-server --config webpack/webpack.config.js
I want to run the above with nodemon but webpack-dev-server and nodemon both use the --config flag. This means that I have to place the above command in quotations resulting in the following.
nodemon "webpack-dev-server --config webpack/webpack.config.js"
which dunt work. Any pointers?
You can use
nodemon webpack-dev-server -- --config webpack/webpack.config.js
When testing locally I was previously running:
"build-live": "nodemon --exec ./node_modules/.bin/ts-node -r dotenv/config -- ./index.ts"
I then figured my Procfile should be something like:
web: ./node_modules/.bin/ts-node -- ./index.ts
But it says module 'typescript' not found, even when it is in package.json. I read in a few places that ts-node is not the way to go to deploy to Heroku, so I am not sure what to do.
UPDATE: I think I am supposed to compile it, so I tried:
web: ./node_modules/.bin/tsc --module commonjs --allowJs --outDir build/ --sourceMap --target es6 index.ts && node build/index.js
This succeeds, however when actually running it, a bunch of the libs I'm using get "Cannot find module '...'".
Alternatively you can have the TypeScript compile as a postinstall hook and run node build/index.js as the only Procfile command:
Your package.json should contain a postinstall hint that gets executed after npm install and before the node process launches:
"scripts": {
"start": "node build/index.js",
"build": "tsc",
"postinstall": "npm run build"
}
You can then leave your Procfile as is:
web: npm start
This 'build on deploy' approach is documented by Heroku here.
The command you've given Heroku is to launch the web "process" by compiling index.ts and dependencies and starting node at index.js. Depending on how things are timed, index.js might or might not exist at the time node starts.
You need to already have your sources compiled by the time you want to start your app. For example, web should just be web: node index.js or similar.
Each build process is different, so you need to figure that out for your own setup. But, suppose you have a classical setup where you push to git and then Heroku picks up that change and updates the app with the new slug. You could just compile things locally and include index.js and any other build output in the repository, for it to be available in the slug for Heroku to use.
A better approach is to use a build server which has an integration with Heroku. After you do the build there, configure it to send the build results to Heroku. Travis has a straighforward setup like this. This way you don't need to include build outputs in your repository, which is considered an anti-pattern.
On a sidenode, try using a tsconfig.json to keep the tsc configuration. It will save you from having to write such long command lines all over the place.
Fabian said that we could do something like:
"scripts": {
"start": "node build/index.js",
"build": "tsc",
"postinstall": "npm run build"
}
As of me writing this, I tested this and can state: postinstall is not required since build script is ran by Heroku. If you want to do it without build script, then you can use heroku-postbuild which will run after dependencies are installed there you run tsc to compile.
My problem was about missing Typescript npm modules. The Typescript compiler tsc was not found when deployed the app to Heroku.
The Heroku deploy process (rightly) does not install development dependencies, in my case the Typescript module was part of devDependencies and thus the tsc command was not running on the Heroku platform.
Solution 1
Add typescript to dependencies: npm i typescript -s
Solution 2
Open Heroku console:
Select console type:
Run the command npm i typescript && npm run tsc
Install typescript as a dev dependency (cf. https://www.typescriptlang.org/download). Once built, your app does not need typescript anymore!
npm install -D typescript
Then in your package.json:
{
"main": "index.js", // <- file will be generated at build time with `tsc`
"scripts": {
"build": "tsc",
"start": "node ."
"start:dev": "ts-node index.ts" // idem, install ts-node as a dev dependency
}
}
The key point here is "build": "tsc".
Why?
Heroku does install all dependencies during build and remove the dev dependencies before the app is deployed (source here).
Node.js deployments will automatically execute an app’s build script during build (since March 11. 2019 source here)
In package.json
"scripts": {
"tsc": "./node_modules/typescript/bin/tsc",
"postinstall": "npm run tsc"
},
Works for me for Heroku deployment.
Installing typescript npm install -D typescript and writing tsc in the build script "build": "tsc", does not work for me. Also, try to run npm i typescript && npm run tsc in the Heroku console which also does not work.
In my case, I remove some dependencies from "devDependencies" to "dependencies", so it goes like this:
"dependencies": {
// The other dependencies goes here, I don't touch them.
// But all TS dependencies I remove to here.
"ts-node": "^9.1.1",
"tsconfig-paths": "^3.9.0",
"typescript": "^4.2.3",
"ts-loader": "^8.0.18"
},