Node.JS doesn't refresh the Nunjuck template - node.js

I'm using Node.JS and Nunjuck to make my templates.
When I change something on my .njk files, I have to stop the Node.JS server and start it back again so that the changes reflect on my browser (localhost:80).
Here is how my app.js (server) looks like:
var app = require("express")(),
nunjucks = require('nunjucks'),
server = require("http").createServer(app),
io = require("socket.io").listen(server)
path = require("path");
nunjucks.configure('views',
{
autoescape: true,
express: app
});
app.get("/", function (req, res)
{
res.render(__dirname + "/views/index.njk");
});
server.listen(80);
And in my index.njk, I have two lines:
{% set x = 5 %} and {{ x }}.
For example, when I change the value of 5 to 7, I have to restart my node.JS server and then refresh the page in order to get a 7. If I just refresh the page without restarting the server, I still get a 5.

Are you using nodemon?
If not do this:
npm i -D nodemon
than on your package.json do the following:
"scripts": {
"start": "nodemon LOCATION/OF/index.js"
}
now you have to run npm rum start to build you project.
On "LOCATION/OF/index.js" should be something like: nodemon src/index.js
Nodemon https://www.npmjs.com/package/nodemon

The problem is that nodemon doesn't watch for changes in .njk files.

You can use nodemon
By default, watching extensions for changes: js,json,md
Here's how to add .njk
Then run these commands:
npm install nodemon -g
nodemon app.js

Related

How to deploy React application to Heroku

I have built a single-page weather app with React and Node.js but can't seem to get it to deploy to Heroku. So far, I have:
Created a new app on Heroku called weather-app-react-node
Logged into Heroku on the CLI
Run the command 'heroku git:remote -a weather-app-react-node' in my terminal
Added a Procfile with 'web: npm start' in it
Ran 'git add .', 'git commit -m "Pushed to heroku"', 'git push heroku master'
My terminal tells me it is deployed and waiting but when I click on the link, I get this error message:
SecurityError: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.
I've tried to google it but can't seem to find anything relevant to my situation. Anyone know how to fix it?
heroku-site: https://weather-app-react-node.herokuapp.com/github: https://github.com/caseycling/weather-app
To deploy the React app to Heroku, I performed the following steps...
1. In your terminal, enter npm -v and node -v to get your npm and node version. In my case, my npm version is 6.14.1 & my node version is 12.13.0.
2. In package.json, add "main": "server.js", and "engines": { "npm": "6.14.1", "node": "12.13.0" }, under the "private" property. In your scripts property, add "heroku-postbuild": "npm install" and set "start" to "node server.js".
3. In the root directory, create a Procfile with one line of text: web: node server.js.
4. In the root directory, create the server.js file with the below code..
const express = require("express");
// eslint-disable-next-line no-unused-vars
// const bodyParser = require('body-parser');
const path = require("path");
const app = express();
const port = process.env.PORT || 8080;
app.use(express.static(path.join(__dirname, "build")));
// This route serves the React app
app.get('/', (req, res) => res.sendFile(path.resolve(__dirname, "build", "index.html")));
app.listen(port, () => console.log(`Server listening on port ${port}`));
5. Enter npm run build in the terminal to produce the build directory. Next, remove (or comment out) /build from .gitignore file (in root directory).
6. Test if server.js works by entering node server.js (or nodemon server.js) in the terminal. If it works, server.js should serve the React app.
7. Commit everything from step 1-6 to GitHub and Heroku repository. To commit to Heroku repository, in your terminal, enter heroku git:remote -a weather-app-react-node and afterward, enter git push heroku master.
You can try logging in to heroku directly and deploy your github repository's desired branch from there directly.
I used create-react-app-buildpack
npm install -g create-react-app
create-react-app my-app
cd my-app
git init
heroku create -b https://github.com/mars/create-react-app-buildpack.git
or
heroku create -b mars/create-react-app
git add .
git commit -m "I am the newborn app"
git push heroku master
heroku open
Note: In my case, buildpack config from CLI did not work, I still had nodejs-build pack, so I manually changed the build pack to mars/create-react-app in the Heroku project dashboard
The best practice to push React apps to Heroku with a node js backend is to use the Heroku Post Build Script, The post build will take care of all the work under the hood
Follow the steps below
Add This below snippet to your package.json under the scripts
scripts{
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix reactFolderName && npm run build --prefix reactFolderName"
}
And add this snippet to your index.js file
app = express()
app.use(express.static('reactFolderName/build'));
app.get('*', (req, res) => res.sendFile(path.resolve(__dirname, 'reactFolderName', 'build', 'index.html')));
After I set up the all the things above mentioned I'm facing this issue.
When I'm using the URL like http://localhost:8080/ & http://localhost:8080/button
Cannot GET /button
In Console
Failed to load resource: the server responded with a status
of 404 (Not Found)
DevTools failed to load source map: Could not load content
for chrome-
extension://gighmmpiobklfepjocnamgkkbiglidom/browser-
polyfill.js.map: System error: net::ERR_FILE_NOT_FOUND

express server starting react client

Until now, I have been using create-react-app for my projects, with the express-server and the react client each in their own folders.
However, I am now trying to avoid create-react-app in order to really understand how everything work under the hood. I am reading an Hacker Noon article that explains how to setup react with typescript and webpack. In this article they also have the express server at the root of the client which compiles everything itself:
const path = require('path'),
express = require('express'),
webpack = require('webpack'),
webpackConfig = require('./webpack.config.js'),
app = express(),
port = process.env.PORT || 3000;
app.listen(port, () => { console.log(`App is listening on port ${port}`) });
app.get('/', (req, res) => {
res.sendFile(path.resolve(__dirname, 'dist', 'index.html'));
});
let compiler = webpack(webpackConfig);
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true, publicPath: webpackConfig.output.publicPath, stats: { colors: true }
}));
app.use(require('webpack-hot-middleware')(compiler));
app.use(express.static(path.resolve(__dirname, 'dist')));
In the end, the start command looks like it:
"start": "npm run build && node server.js"
So I assume the client and the server start on the same port.
Why would you do such a thing? Are there any pros and cons?
It is true that this will allow your development to happen using the same server as express and that web pack will continuously update your dist/index.html file with whatever updates you make to your file. There's not too much of a disadvantage to this as this is just for development. But typically on prod you'll have a single built file that you will serve. And it will not web pack-dev-middleware to be running. Once you've built your server. For the purposes of production it might be possible that you'll only need static assets. But typically, even the server which serves mostly client files will potentially need a server if you want to do server side rendering and/or code splitting.
The command: "npm run build && node server.js" will run the bash/cmd commands into the terminal. npm run build is one step because of the use of && it will if that command succeeds, run the next command which is node server.js which is a strange command I would probably run node ./ (and put the server as index.js) or at least just write node server.
What I'd prefer to see in your package.json:
"start": "yarn build && node ./"
That would be possible if you mv server.js index.js (and npm i -g yarn).
Another thing to note, and look into is what the build step does.
Further Explanation:
The command runs the build step so check what your "build": key runs in your package.json.
This command will probably not exit with the code 1 (any exit code of a terminal process that is above 0 will result in an error and will not pass the &&).
Presumably, the build process described in the package.json will take all the javascript and CSS files and put them into the index.html file which will then be sent to the client side whenever someone access the '/' path.
After that succeeds, it will start the server that you put the code to above.
res.sendFile(path.resolve(__dirname, 'dist', 'index.html'));
will happen if anybody comes across the '/' path.

Configure nodemon to refresh same tab

This could be really rookie. I want to know if there is a way that I can configure nodemon to refresh the same tab instead of opening a new tab each time I make a change in my js files.
nodemon is not able to do that. What you are looking for is something like browser-sync or LiveReload.js.
I use a package called reload. Assuming you are doing this on your FE and that you already installed express.js and nodemon
first install reload
npm install --save-dev reload
Than create a index.js file or server.js or whatever name your want
this is my index.js:
const express = require('express')
const http = require('http')
const reload = require('reload')
const opn = require('opn')
const app = express()
app.engine('html', require('ejs').renderFile)
app.set('view engine', 'html')
app.set('src', './src')
app.use(express.static('src'))
app.get('/', (req, res) => res.render('index'))
const server = http.createServer(app)
server.listen(8080, function() {
console.log('Listening to port 8080...')
})
opn('http://localhost:8080')
reload(app)
the opn package can be intalled with
npm install opn
it will automatically open your localhost once you type npm start on your terminal
on HTML you have to insert something like this after the closing body tag:
</body>
<script src="/reload/reload.js"></script>
and on package.json the following:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon index.js -e els,js,html,css,json"
},
The only problem with this is that it will reopen the browser every time you make a change to those files and well as reload the current opened one sure to the opn package. I am still going to create a function to prevent that, eventually. Hope that helps!
Its Simple.
To run your server use
npm start
instead of
nodemon server
Just run npm start nodemon server.
It works for me. Make sure you have latest nodemon version installed.

How to set up dev and API server from create-react-app?

I've started a new app with create-react-app, and ejected from that. I made a small express server as follows:
const express = require('express');
const app = express();
if(process.env.NODE_ENV === 'production') {
app.use(express.static('build'));
}
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server started at: http://localhost:${port}/`);
});
In package.json I've added a line, "proxy": http://localhost:3000", as well as switching the commands:
"scripts": {
"run": "npm-run-all -p watch-css start-js",
"start": "node server.js",
},
run used to be start.
However now of course when I run npm start and go to localhost:3000, I get Cannot GET /. I need this server to receive and return local API calls I'll be making from my app, but I also want it to run a hot-reloading dev server just like the old npm start (now npm run) command did. How do I do this?
Some time ago I made a fork of the create-react-app repository adding webpack watch option because of this same reason. It might help you.
Just to add more info, I really invested time looking on how to get webpackdevserver to build the "bundle.js", and found that it is not possible because it loads the bundle into memory but doesn't persist it, so the file is never created. The only way available is the webpack watch option but, I don't understand why the create-react-app team can't add it to the repo, it's a really requested feature, and there are more forks than mine that solves this issue. So, you have three options:
Use the proxy server in package.json (if it works)
Make your own fork and add the watch option, or use an existing one
Don't use create-react-app

Why Angular 2 doesn't load default app-root component?

I'm trying to start Angular app generated via angular CLI, but it seems like the default app-root component doesn't load. Need to say, that I'm using proxy for connection between angular app and express server, and I'm running two scripts at the same time: node bin/www for express/node.js start and ng serve --proxy-config proxy.config.json for starting Angular and creating proxy connection, it looks like this (the part of package.json):
"scripts": {
"start": "concurrently --kill-others \"node bin/www\" \"ng serve --proxy-config proxy.config.json\""
}
The index page loads fine, but it seems that app-root component (the default component, which was created from angular CLI ng new) doesn't loading:
Here is my node.js/express uses and a route:
var express = require('express');
var router = express.Router();
var app = express();
var path = require('path');
app.use(express.static('./src/client/'));
app.use(express.static('./'));
app.use(express.static('./tmp'));
app.use('/*', express.static(path.resolve('src/client/index.html')));
router.get('*', function(req, res) {
res.sendFile(path.resolve('src/client/index.html'));
});
module.exports = router;
And the structure of my project (if needed):
What did I miss? Why the default app-root component doesn't loading? (need to say, when I run ng serve, it starts the angular homepage as needed and the component is OK, so I think the problem is somewhere in express).
Thanks in advance
You should serve the contents of the dist/ folder after calling ng build --prod (the --prod is important, as the default is --dev). So, it would be something like this:
"scripts": {
"start": "ng build --prod && node bin/www"
}
And, more or less adapting your express script:
app.use(express.static('./dist'));
app.use('/*', express.static(path.resolve('dist/index.html')));
router.get('*', function(req, res) {
res.sendFile(path.resolve('dist/index.html'));
});

Resources