Sails + react on a single heroku server ? - node.js

I have a single project which runs sails app on 1337 port and react on 3000. How can I deploy both to single heroku instance ? Which runs sails on 1337 and react on 3000.

You need to integrate React with Sails.
React is all about static files (e.g. HTML, JS and CSS). To integrate React with Sails, a naive solution is to copy the compiled React files to the Sails assets folder.
Below is what I have tried with a brand new Sails app. It just works.
Edit config/blueprints.js to change the API prefix. From now on, the APIs changes from http://localhost:1337/<RESOURCE> to http://localhost:1337/api/<RESOURCE>.
module.exports.blueprints = {
// ...
prefix: '/api',
// ...
}
Edit config/routes.js. Remove the following lines if they exist. This makes sure that when someone visit http://localhost:1337, Sails will search for index.html inside the assets folder.
'/': {
view: 'homepage'
}
Update the React application in case it consumes the APIs from Sails (Remember that we have changed the API prefix). Also make sure that the application entry point is index.html.
Compile your React application (by Webpack or Grunt or whatever packaging tool you are using) and copy the compiled files to the Sails assets folder.
Deploy the Sails app to Heroku.
Done!
A better but more tedious solution is to migrate the React development to Sails. I found an example on Google. It might be outdated because the last update was Feb 2016, but you shall use it as a reference.

Related

How can I connect my NodeJS/Express backend to my VueJS frontend using only one port on my local machine?

My Vue app is set up using Vue CLI (Webpack) and it's working as it should. My NodeJS/Express REST API is also working properly. However, to run them simultaneously I now start a local server for each of them -- each with its own port. I would like to have both of them communicate over one port.
Localhost:8080 should point to the home page of my Vue App and the API requests should follow localhost:8080/api/...
In my production environment I use one and the same port/URL by serving the Vue App as a set of static files ('dist' folder). In my development environment I don't know how to set this up, however.
I looked around for answers online, but feel lost among all the different terms I have come across (.env, crossenv, nginx, cors) and that I am running in circles.
What would be a good way of setting this up?
Thank you
Edit:
I ended up creating three modes to run my application:
Development
I use one script in a package.json to start the frontend and backend server on different ports, using pm2 to run the servers in the 'background' rather than blocking further commands in the terminal/cmd. I use configured a proxy inside my vue.config.js to redirect my API calls made in the frontend to the right base URL and used cors as middleware to allow requests to my API from other domains/ports.
Staging
I use one script in a package.json to build the Vue app into a folder ('dist' folder inside my backend folder) that is a collection of static files and start the backend server. My backend is set up to know when I want to go into staging mode and then serve the static files in the 'dist' folder.
Production
I use one script in a package.json to build the Vue app into a folder ('dist' folder inside my backend folder) that is a collection of static files and push my backend (incl. the built static files) to Heroku.
Well if you need to run both on the same port you could first build your app so that you receive a dist directory or whatever your output directory is named and set up an express server that serves that app and otherwise handles your api requests
const express = require("express");
const path = __dirname + '/app/views/';
const app = express();
app.use(express.static(path));
app.get('/', function (req,res) {
res.sendFile(path + "index.html");
});
app.get('/api', function (req,res) {
// your api handler
}
app.listen(8080)
Assuming that node and the 'app' will always run on the same server you can just use a template library like ejs.
You would then just bundle the app and api together, assuming that the front-end is tied to the backend, realistically you would not even need to hit the API as you could just return the records as part of the view, however if dynamic elements are needed you could still hit the API.
Now, with that said, if the API is something used by many applications then it would probably make sense to build that out as its own microservice, running on its own server and your frontend would be on its own. This way you have separation of concerns with the API and Vue app.

How to connect NodeJS with ReactJS front-end

I am new to reactJS. I am working on project which uses following :
Front-end : ReactJS
Backend : NodeJS (Express)
Front-end runs on port 3000
Back-end runs on port 8088.
I am planning to deploy application on amazon AWS.
What i am trying to do is load reactJS front-end when i make request on http://localhost:8088/
I know using axios we can make request on backend server and display fetched data.
What would be standard way of loading ReactJS front from the nodeJS ?
I'm not sure if this is the answer you are looking for, but generally in development you use something called proxy in your package.json in the client (react) folder:
{
// Other stuff
"proxy": "http://localhost:8088"
}
and then when you'd want to deploy you'd run npm build for your react folder and serve that generated folder called build. But as I said, you usually do that only when deploying your application onto server, not the actual development.
Also I'd suggest checking some of these videos, that are focused on deployment, because that is what I think you are asking, right ?

merge existing nodejs server app with the existing angular2/5 client app

I have built an angular5 client app and a nodejs (using express) server app working on ports 4200 and 3000 respectively. Now I want to merge them both in a single app as a deliverable.
Will just copying the angular folder into nodejs work?
Not sure how to go about it.
From a code organizing perspective.
For development, keep each app in its own folder, something like
nodejs
angular-app
In production,
nodejs
public
angular-dist-folder
Deployment scripts can handle this for you, you should avoid doing manual copy pasting of stuff, It is important to keep code organized, it is absolutely important and vital for the success and health of any project.
Edit:
I ld like to add, modern JS projects makes use of some sort of file system watchers, Ex fs.watch . Keeping apps in separate directories, prevents the unnecessary rerun of processes during development.
In your angular folder, run ng build --watch. This will build your project and create a dist folder. Also, it will watch for any code changes and rebuild.
You can copy this dist folder in your node project's public folder and make a few changes in your server.js file to integrate that.
You can use nodemon server.js to look for changes in node project.
Below are the changes which I made in my server.js to make it work.
app.use(express.static(path.join(__dirname, 'public/dist')));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'public/dist/index.html'));
});

Use javaScript file in angular 5 project

I am building a web application using Angular 5 and nodejs with express. As both the frontend and the backend are going to run in the same server I want to use my backend javascript functions in the frontend. The solutions that I have found didn't worked for me.
appController.js
var createApp = function (appData) {
console.log("App created")
}
exports.createApp = createApp;
This is the backend file that I want to use in the front.
Javascript files don't need to export things when used in the front-end. Most of the time, they use global variables. You should go with that.
To add it to your project, add it anywhere you want, and in your Typescript, you can simply use
declare var myGlobalVariable: any;
// ...
myGlobalVariable.createApp();
I did a similar thing. I have a frontend with Angular 5 and a backend serving an API via Express:
If you want to run your Angular frontend and your NodeJS backend on the same server you'll have to build your Angular project and serve the built files with your Express server.
I think I found a tutorial on that – but I can't find it right now...
Instead maybe have a look at my code for the backend:
https://github.com/saitho/ngHashi/blob/next/backend/src/index.ts
In production mode it will serve the files in the folder /backend/dist_frontend by default (apart from the backend routes (/api)). I use a build process (GitLab CI) to move the files I need to the respective place...
I finally find a solution. It would be necessary to modify the tsconfig.json:
tsconfig.json
{
compilerOptions: {
.....
allowJS: true,
......
}
}

Can I use webpack on the client side without nodejs server?

I am trying to build a web app where I want to store all html, js and css files on amazon s3, and communicate with a restful server through api.
I am trying to achieve lazy loading and maybe routing with react router. It seems that webpack has this feature code splitting that would work similarly as lazy loading.
However, all of the tutorial and examples I found involves webpack-dev-server, which is a small node express server. Is there anyway I could generate bundle at build time and upload everything to amazon s3 and achieve something similar to Angular's ocLazyLoading?
It's definitely possible to create a static bundle js file, which you can use in your production code that does not include webpack-dev-server.
See this example as a reference (note: I am the owner of this repo). webpack.prod.config.js does create a production ready bundle file using webpack via node.js which itself does not require node.js anymore. Because of that you can simply serve it as a simple static file (which is done in the live example).
The key difference is how the entry points are written in the dev- and production environments. For development webpack-dev-server is being used
module.exports = {
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./src/index'
],
// ...
}
In the production environment you skip the webpack-dev-server and the hot reloading part
module.exports = {
entry: [
'./src/index'
],
// ...
}
If you want to split your code into more than one bundle, you might want to have a look at how to define multiple entry points and link the files accordingly.

Resources