Is it possible to have Heroku Local run like nodemon? - node.js

I'm new to Heroku, a little bit less to NodeJS (and Nodemon).
I am now using heroku local to run my app in local (and be as close as possible to my prod environment) but I'd like to have my app rebuilt and restarted everytime I make a change in local (as with Nodemon for example).
Is there nay way to do this with heroku local?
Thanks!
Nicolas.

Old question, I know, but came up while I was searching for the same. There is an answer here: https://stackoverflow.com/a/46561121
This is what I have in my package.json:
"scripts": {
"start": "nodemon --exec 'heroku local' --signal SIGTERM"
}

For anybody coming across this post in search of a solution. As mentioned by nicolasdaudin in response to tom, you can add nodemon to the heroku Procfile (https://devcenter.heroku.com/articles/procfile):
web: nodemon index.js
Note that nodemon must be installed globally for this to work:
npm i -g nodemon
Then you should be able to run heroku locally as normal with nodemon watching for changes:
heroku local web

Related

How do I run start script when deploying nuxt 3 app on Heroku

I've been trying to deploy a Nuxt 3 app that requires a Node.js instance to Heroku.
I've added Procfile to the root of my project, but the documentation, which I think is referencing Nuxt 2, says to add the script command 'yarn start' to get a node.js instance up and running on the server.
However, Nuxt 3 does not have a start command.
What command do I add to the Procfile for a Nuxt 3 app? Or is this no longer necessary?
And of course I found an answer as soon as I posted this.
Add "start": "node .output/server/index.mjs" to your package.json.
Then you can add 'web: yarn start' or 'web:npm run start' to your Procfile.
Source from the Nitro documentation.

Node.js applies the changes only after restart

I am very new to server side scripting. And I am using NodeJS. My Problem is that after adding some new features to the app, i.e. after changing the code, these changes will be applied only after restarting the server. Till then NodeJS behaves so as though I hadn't changed anything. So for instance if I add console.log("works") and don't restart the server, then it hasn't any effect.
I am using Nuxt.js, which is actually the Vue.js framework but with additional and very usefull features mainly for server side rendering. I didn't integrate the express.js at the beginning of the project, beacause it wasn't planned to write any server side code. So I am normally exporting express and using it, which is pretty fine for me, since I need just a couple lines of code to use the NodeJS file system.
So, as it is pretty hard to code, if I should restart the server once I changed anything, I want to ask you if there is any solution to this problem.
Use nodemon
step 1 : npm install -g nodemon <- this will install nodemon globaly in your system
step 2 : change your start script within package.json
"scripts": {
"start": "nodemon fileName" <- like this //filename is you root file which starts the app like app.js
}
step 3 : npm start
This is already build in into nuxt. You just need to run it in dev mode, not in production.
E.g. for dev with change monitoring
nuxt
For production without monitoring
nuxt start
So in this particular case the following changes to the "scripts" in package.json have solved my problem.
"scripts": {
"dev": "nodemon --watch api --exec \"nuxt\"",
"start": "nodemon nuxt",
}
The following link could also be usefull to you.
Install nodemmon in your application to allow live update npm -g install nodemon
and add the following codes inside your packages json file :
"main": "app.js",
"scripts": {
"start": "node app"
},
on your command line, just type : start

Setting up Angular Universal App for development

I have created a project with Angular-CLI. (using command: ng new my-angular-universal).
Then I carefully followed all the instructions from https://github.com/angular/angular-cli/wiki/stories-universal-rendering
It builds for --prod and works fine. But there are no instructions on how I can set up a --dev build and have it served with --watch flag.
I tried removing --prod flags from npm "scripts", and it doesn't even run in dev mode. It builds fine but when I open it in browser this is what I see (directly printed to response):
TypeError: Cannot read property 'moduleType' of undefined
at C:\Users\Mikser\documents\git\my-angular-universal\dist\server.js:7069:134
at ZoneDelegate.invoke (C:\Users\Mikser\documents\git\my-angular-universal\dist\server.js:105076:26)
at Object.onInvoke (C:\Users\Mikser\documents\git\my-angular-universal\dist\server.js:6328:33)
at ZoneDelegate.invoke (C:\Users\Mikser\documents\git\my-angular-universal\dist\server.js:105075:32)
at Zone.run (C:\Users\Mikser\documents\git\my-angular-universal\dist\server.js:104826:43)
at NgZone.run (C:\Users\Mikser\documents\git\my-angular-universal\dist\server.js:6145:69)
at PlatformRef.bootstrapModuleFactory (C:\Users\Mikser\documents\git\my-angular-universal\dist\server.js:7068:23)
at Object.renderModuleFactory (C:\Users\Mikser\documents\git\my-angular-universal\dist\server.js:52132:39)
at View.engine (C:\Users\Mikser\documents\git\my-angular-universal\dist\server.js:104656:23)
at View.render (C:\Users\Mikser\documents\git\my-angular-universal\dist\server.js:130741:8)
the versions of npm packages that I use are currently the latest:
#angular/* - #5.2.*
#angular/cli #1.7.3
except for ts-loader, had to downgrade it because it wasn't working:
ts-loader #3.5.0
So if anyone has any info on how to make this work, it would be very appreciated! Or maybe you know some project templates with Angular Universal App configured for both --dev and --prod builds and ability to --watch?
For development, run npm run start which triggers ng serve. The current setup has hot module reloading so it will watch for your changes and update your dev view. I used the same instructions and got it working here https://github.com/ariellephan/angular5-universal-template
In short, for development, run npm run start and look at http://localhost:4200.
For production, run npm run build:ssr and npm run serve:ssrand look at http://localhost:4000
As contributors have pointed out, it might not be the most efficient and fastest way to develop, but nevertheless I did not want to accept workarounds. Besides, hosting front and back on separate servers brings up CORS issues, and I never planned my app to run on separate hosts, I wanted it all on the same host together with API methods.
The problem with --dev build was this:
when building with the following command:
ng build --app 1 --output-hashing=false (note that there is no --prod flag)
AppServerModuleNgFactory turned out missing in the ./dist-server/main.bundle
I imagine that this relates to the ahead of time(--aot) compilation which is the default behavior if you are building for --prod. So the instructions from https://github.com/angular/angular-cli/wiki/stories-universal-rendering included instructions to configure express server for production build only. And since there is no need for server to be able to dynamically render html templates the working --dev build command would be:
ng build --app 1 --output-hashing=false --aot
and this gets rid of the TypeError: Cannot read property 'moduleType' of undefined
Now to watch this whole mess:
run these in separate command windows:
ng build --watch
ng build --app 1 --output-hashing=false --aot --watch
webpack --config webpack.server.config.js --progress --colors --watch
And for the server to restart on change, you have to install nodemon package and run it like this:
nodemon --inspect dist/server (--inspect if you wish to debug server with chrome)
Some other important stuff:
Angular/CLI has a command to generate necessary scaffolding for a universal app:
ng generate universal
and it generates a fixed version of main.ts that avoids client angular bootstrap issue:
document.addEventListener('DOMContentLoaded', () => {
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
});
a problem that I stumbled upon once I implemented TransferState
There are basically two parts - the server and the UI. While developing the UI, I simply use ng serve. That means when I make changes in my code in the IDE, the browser refreshes automatically. And, here the server part is not used.
I do prod build and run the server only for final testing to see if everything works as expected (No error due to any 3PP library DOM manipulation or AOT related issues, etc.)
Here, I have created a skeleton structure of an Angular Universal project. As I extensively use Vagrant and Docker in my projects, I run the server in a Docker container within the Vagrant guest system. And for development of the UI, I don't run the server. Simply, the ng serve is used.
If you look into my structure in the above Github link, you'll find the details as to how to run it for development and production in the Readme file.
The web server handler server.ts uses the server bundle
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main.bundle');
That's why the server bundle needs to be compiled before you can compile the server.ts file.
So having a watch system would mean
watching/recompiling the client bundle
watching/recompiling the server bundle
recompiling the server.ts once the server bundle is created
All of them take some time (especially if you do it with aot)
I'd recommend, like Saptarshi Basu mentionned, to develop as best as you can with ng serve and check with angular universal every so often.
Otherwise, it should be possible do achieve what you want with some kind of tasks (grunt/gulp/...) which triggers sequentially ng build ... and recompilation of server.ts file.
It is a bit messy no doubt, as we preferably wish for one command to rule them all.
I came up with a somewhat OK solution where my output will be:
dist/browser
dist/ng-server
Using the executable npm-run-all package (I find it working a lot better on windows machines than concurrently does) I run the three watch tasks: browser, ng-server and nodeJS. Watching node has a pre-task defined that simply runs a small utility/helper/file that watches for the existence of a dist/ng-server folder and terminate itself once found.
For all of this to work (based on the universal-starter repo as of november 2018) there's a couple of modifications to package.json required. Primarily, to support the --watch flag on ng run commands we need to update the compiler-cli (if memory serves), ng update --all should take care of that, giving you the latest angular/cli version in the process (assuming you have a recent cli version installed globally).
package.json
ng update --all
angular 6+
angular/cli 7+
yarn add/npm install the following
chokidar
npm-run-all
(runs our tasks in parallel with the -p flag. -p kills all processes, -l gives each running task a specific color and name in the console)
ts-node (runs nodejs in it's ts-format)
nodemon // for restarting ts-node
add something similar to my util/await-file.js (after some consideration I added my own file-watcher code below even though it wasn't exactly written with the intentions to be put up on display...)
modify your package.json scripts like below
modify your angular.json to match your folder names, following my examples, mainly the "server"'s outputPath should be changed from dist/server to dist/ng-server.
package.json scripts
"dev": "npm-run-all -p -r -l watch:ng-server watch:browser watch:node",
"watch:browser": "ng build --prod --progress --watch --delete-output-path",
"watch:ng-server": "ng run ng-universal-demo:server --watch --delete-output-path",
"watch:node": "yarn run watch:file-exist && yarn run ts-node",
"ts-node": "nodemon --exec ts-node server.ts -e ts,js",
"watch:file-exist": "node utils/await-file.js",
util/await-file.js
const chokidar = require('chokidar');
const fs = require('fs');
const path = require('path');
const DIR_NAME = 'ng-server';
const DIST_PATH = './dist';
// creates dist folder if it doesn't exist - prior to adding it to the watcher.
if (!fs.existsSync(DIST_PATH)) {
fs.mkdirSync(DIST_PATH);
}
const watcher = chokidar.watch('file, dir', {
ignored: '*.map',
persistent: true,
awaitWriteFinish: {
stabilityThreshold: 5000,
pollInterval: 100
}
});
const FOLDER_PATH = path.join(process.cwd(), 'dist');
watcher.add(FOLDER_PATH);
console.log(`file-watcher running, waiting for ${DIST_PATH}/${DIR_NAME}`);
function fileFound() {
console.log(`${DIR_NAME} folder found - closing`);
watcher.close();
process.exit();
}
watcher
.on('add', function (filePath) {
const matchWith = path.join('dist', DIR_NAME);
const paths = filePath.split(path.sep);
const fileName = paths[paths.length - 1];
if ((filePath.indexOf(matchWith) >= 0)
&& fileName.indexOf('.js') > fileName.length - 4) {
fileFound();
}
})
.on('error', error => console.log(`Watcher error: ${error}`));
"npm run start" and using "http://localhost:4200" works for me. Even with Angular 10

Using BrowserSync with only Node.js (MEAN)

Can anyone help me understand how to use BrowserSync with an already running node server?
I know that I have to proxy the server localhost:3000 but where and how would I do that?
Since I'm not using Gulp/Grunt my best guess is proxying a running BrowserSync with express.js but what would that look like?
EDIT:
#RunnyYolk's answer is correct, The best way is to create a script in the package.json file that has BrowserSync proxy your node server. However the issue is more specifically how to use BrowserSync when you need to wait for a process to finish first, such as Angular compilation, then reload your browser.
My build process looks like this:
"build": "del-cli public/js/app && webpack --config webpack.config.dev.js --progress --profile --watch",
How do I call browser-sync reload after that webpack compilation?
I've had browser sync running with a few Node projects. I remember it being a little bit of a fiddle the first couple of times, but definitely worth the effort.
I can't remember exactly what I got caught on, but try these things and let me know if it's still not playing:
Assuming browser-sync is installed, make sure your app.js file (or whatever you've called it) has the server listening on port 3000.
Start the app with a command similar to this:
browser-sync start --proxy localhost:3000 --files="public/stylesheets/*.css", "public/scripts/*.js" "public/views/*.ejs" --no-notify
That works for me. "--files" is a list of files for browser sync to watch, and --no-notify gets rid of some notifications that get fired on each file change - possibly useful in some situations, but I found them annoying.
Looking at this command I notice that there is no reference to node app.js to start up the app. I assume (although I'm not certain) that bowser-sync looks inside package.json for the "start" script. So if my assumption is correct, and if the above command isn't working for you, check that your package.json file has the script included.

Run node server and webpack together using package.json

I have completed todo app by learning from this video:
Super MEAN Stack Tutorial: Angular, Node/Express, Webpack, MongoDB, SASS, Babel/ES6, Bootstrap
In that video at time 19:18 at this url it is taught that I should use the below two commands in seperate git-bash instances if I want to run it in windows using npm run dev:
node server
webpack-dev-server --progress --colors
But in Linux (or any other OS than windows) you can use this script:
"Scripts": {
"start": "NODE_PATH=$NODE_PATH:./src node server",
"dev": "npm start & webpack-dev-server --progress --colors"
}
So, Is there any way I can do the same in windows?
Also, In that tutorial I can see that port no. 3000 is assigned to node server, but due to using dev dependencies he runs the localhost:8080 in browser. You can see that here. After the tutorial finishes, I followed along and created that app. Now I would like to deploy it. So, I would first like to learn to run test my site in non-dev dependencies mode. i.e. when I type localhost:3000 in browser, my app should run successfully. So, can anybody explain the steps for that?
Update:
I am a newbie in node.js. I watched many videos on node and tried to learn something from that. In all the videos I see that I run node server on port no. 3000 and then I type localhost:3000 in my browser. Now lastly I watched video about mean stack in which he uses webpack. Now, I am confused. I think there are two servers running. first server is webpack's server and second server is node's server. Upto today I typed localhost:3000 in my browser because I mentioned that port 3000 will be used by node in my code. But now in the video he is running localhost:8080 in browser. It means webpack's server is used. Then what happened to node server. Why can't I just run localhost:3000? Also in the video it is explained that webpack is a dev dependency. So, I think after the app is completed and ready to be deployed, my project can be run on the node server (by making some changes to the code, I am not sure). Let's take an example. Now I don't want to deploy the app to a real server. I want the same app to run on my friend's pc. He is not a developer. So, he should not depend on webpack as webpack is a dev dependency. So, he should be able to run the app on node server instead of webpack's server. So, he should type localhost:3000 instead of localhost:8080. That's what I don't understand.
Let's break this down:
If you've defined this script:
"Scripts": {
"start": "NODE_PATH=$NODE_PATH:./src node server",
"dev": "npm start & webpack-dev-server --progress --colors"
}
... then this npm command: npm run dev
... actually invokes these two actions:
a) npm start & # Runs NPM in the background
b) webpack-dev-server --progress --colors # Concurrently runs webpack in the foreground
You can accomplish the same thing in many ways using Windows, starting with a simple .bat file like this:
EXAMPLE: RunDev.bat:
start npm start
webpack-dev-server --progress --colors
=======================================================================
STRONG SUGGESTION:
Please forget about watching videos for a few moments. Try a couple of "hello world" tutorials. More importantly, play with the actual code. Try changing things in the code, and see what happens.
Forget about webpack, at least for the moment.
Think of npm as a "build tool"; not as a way to run your application. At least for a moment.
Focus on "node". Write a "node application".
Part of your "node application" will require "ExpressJS" and "Jade" (now renamed "pug" - I'm still using "Jade"). Use npm to get your ExpressJS and Jade dependencies, but stay focussed on Node.
SUGGESTED TUTORIAL:
A Simple Website in Node.js, Ben Gourley
Be sure to:
a. Download the code
b. Work through the tutorial, using the downloaded code
Please post back (a new post) with any specific questions you might have as you work through the tutorial.

Resources