All the tutorials I can find use some kind of app.js to run their node server on heroku.
I have already configured my grunt - connect task to use modRewrite for my single page app so that all requests simply return index.html. So it would be convenient for me to somehow just have heroku run my grunt dist once it npm installs.
I have tried adding this line to my package.json
"scripts": {
"postinstall": "echo postinstall time; ./node_modules/grunt/lib/grunt.js dist"
}
But I think there is something wrong with my path, because it doesn't work. I get a Permission denied error.
I also tried using a simple app.js express server (even though I would have to re-figure out how to do the modRewrite) -- but that failed somewhere along the line - heroku was looking for an index.js, which I don't have.
Thanks!
The solution I ended up with is a simple connect server using the same modRewrite code from my grunt task:
var connect = require('connect');
var modRewrite = require('connect-modrewrite');
var app = connect()
.use(modRewrite(
['^[^\\.]*$ /index.html [L]']
))
.use(connect.static('./dist/'))
.listen(process.env.PORT || 3000)
And the following Procfile:
web: node app.js
Related
Following this tutorial to get an api and client on google cloud platform:
https://www.freecodecamp.org/news/create-a-react-frontend-a-node-express-backend-and-connect-them-together-c5798926047c/
I have a root dir with an /api and /client inside it
the /api package.json has the following script
"scripts": {
"start": "node ./bin/www"
},
the /client package.json has the following script
"scripts": {
"client-install": "npm install --prefix client",
"start": "node server.js",
"server": "nodemon server.js",
"client": "npm start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\""
},
When I try to deploy it says:
Step #0: Application detection failed: Error: node.js checker: Neither
"start" in the "scripts" section of "package.json" nor the "server.js"
file were found. Finished Step #0
I'm thinking it can't find the scripts? What is the best approach to start my api and client at the same time when I deploy?
My supposition is that the reported problem is generated by the fact that in root directory there is no package.json file. You could try to add one in root directory to handle stuff in app and client directories, but...
... but a taken a look to the tutorial you used and I found some things I don't like, so you want to give you some suggestions. I recently developed a simple tool to visualize charts about covid-19 diffusion in Italy, it uses same structure as your app with different approaches. The main difference is I deploy it in a VPS and I use external tool to launch it so in my package.json file there is not the script command to launch it in prod. It is something like:
cd client && npm install && npm run build && cd .. && npm install && node server.js
You can take a look to github repos to get ideas, but I'm going to explain the main differences.
server stuff (with package.json) is in root directory (simply this could solve your problem)
as per other answers, you need to add two lines to your express app to serve the built client as static files:
I suggest to use proxy features rather than cors package.
In your express app:
// At the begenning, with other middlewares
app.use(express.static(path.join(__dirname, "client", "build")));
// As last, to substitute any 404 with your client home page
app.get("*", (req, res) => res.sendFile(path.join(__dirname, "client", "build", "index.html")));
I don't know which kind of data you are going to treat, but CORS is a sort of protection you should never disable (by cors package), at least as it is possible. More than this, once you'll be able to solve the reported problem, I'm afraid that following part from the tutorial you used will not work, as it will try to fetch APIs from your app users's localhost:9000.
callAPI() {
fetch("http://localhost:9000/testAPI")
.then(res => res.text())
.then(res => this.setState({ apiResponse: res }));
}
To both enable CORS and solve fetching from localhost problem you should use proxy feature. In your client package.json file just add:
"proxy": "http://localhost:9000/",
This makes your webpack dev server to proxy calls it can't handle to your dev server, than changing your client fetching function to:
callAPI() {
fetch("/testAPI")
.then(res => res.text())
.then(res => this.setState({ apiResponse: res }));
}
it will automagically works both in dev and prod envs and let you to enable back CORS.
Hope this helps.
Well in that tutorial that guy creates the react app using create-react-app and because of that I don't know why you have in the 'start' command in your second package.json the following command 'node server.js'. You should have "start": "react-scripts start", that won't fix your problem but I'm not sure if server.js another server or what.
Anyway I'll try to help you, first 'create-react-app' creates an app which internally uses webpack-dev-server which is cool for developing, but in order to deploy your app you need to run this command
npm run build
After that you will have a folder called 'build' with your react app. Then you need to copy that folder and go to your server project and paste the
'build' folder there. Once you finish that you need to add the following code to tell your server that you want to serve static files
app.use(express.static(path.join(__dirname, 'build')));
And you also need to add the route
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
Now you can test it locally running only your server and the '/' path should take you to the react app. Once you know that is working, you can deploy ONLY that server with the build folder and just one package.json to google app engine.
I hope helped you!
I am trying to deploy next js app on cPanel. I have installed node and npm on it.
How can I deploy the next js app on this set up?
I am getting the following error while trying to build the app on cpanel terminal:
Unhandled rejection TypeError: child.send is not a function
You'll need root privileges. If you've got them you can remote into your server via SSH and run the npm commands there. Then it should work. I.e, from console:
ssh user#serverip
cd /path/to/appdirectory
npm run start
There are some options to deploy NextJS app in CPanel:
You just deploy serverless app (without NodeJS) in CPanel. NextJS has provided a syntax like next export to producing optimized frontend files.
New version of CPanel already has entry point for your nodejs application:
Specify your server file on that field.
You should run next export to make static html and js files in out you can directly upload it to Cpanel as normal html website
you can run npm run export or yarn export by adding
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start",
"export": "next export"
},
these in package.json
Next.js applications should run fine on a web hosting provider using cPanel, but running the default next.js server tends to exceed process count and memory quotas applied by those types of providers.
However you can make hosting next.js apps work if you build a production version of your app elsewhere and then use a custom server to call your next.js app to handle incoming requests.
I describe the process to deploy a very basic application as a subsite on my website here - https://www.watfordconsulting.com/2021/02/08/deploy-next-js-applications-to-a-cpanel-web-host/
All you really need to do is run next export and put the contents of the out folder in the public_html folder or /var/www/html/, /sites-available/, etc, depending on setup.
serve has been installed globally using npm install -g serve command and It works locally, but deploying to a Windows server gives the following error:
"serve" is not recognized as an internal or external command
How to fix this error? Also, what is the use of the server.js file in a react project, and how does it help with deployment?
npm serve is installed globally please click here to see the image
I know that running npx serve -s build should work. I had the same problem as you. The npx command works for me. If you have npx problems, check your version of nodejs. I'm running 10.16.2 (so that we're on the same page). https://www.npmjs.com/package/serve
The rest of your question is relative to the rest of your set up. I don't have a server.js file of my own (there are some node_module server.js files, is that what you mean)?
As I understand a create-react-app, npm run start will allow you to run your application locally. I don't need serve -s build for that.
I used an amplify create react app. For an amplify application, I just run amplify publish and my application's build directory is sent to an S3 bucket for me. If you don't have that configuration, and you want the quick and dirty answer... just take the contents of your build directory in your react application and drop those files on your web server. That should get you 90% of the way there (mind the default page that renders).
Serving React Files
Basic Exapmle:-
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(9000);
For your base path in the domain serve the index.html you fetched from your build process.
If you need more info :- https://create-react-app.dev/docs/deployment
I will make my Angular 2 question very precise.
1. I am using:
Angular 2,
angular-cli: 1.0.0-beta.15, ( webpack building )
node: 6.4.0,
os: linux x64
2. What I want to achieve:
I want to build my project in a way that after the build ( ng build project-name ) I get static files of my Angular 2 application, which I can run directly from chrome without using ng serve or the node server. I just want to double click index.html and run the app locally.
3. Meanwhile, what I get in the chrome browser console output when I double click the generated index.html is:
file:///inline.js Failed to load resource: net::ERR_FILE_NOT_FOUND
file:///styles.b52d2076048963e7cbfd.bundle.js Failed to load resource: net::ERR_FILE_NOT_FOUND
file:///main.c45bb457f14bdc0f5b96.bundle.js Failed to load resource: net::ERR_FILE_NOT_FOUND
file:///favicon.ico Failed to load resource: net::ERR_FILE_NOT_FOUND
As I understand this is related to paths. The built and bundled application cannot find the right paths. So my question is where and how I should change the paths in my app or in any build configuration files in order for my app to work like I would like it to work in the way I have described in point number 2
Thank you in advance for a direct and full answer on that topic, because other topics are not explaining the full scope on that subject.
First Step:
Run the command
ng build
or
ng build -prod (then it will compact all files for production version)
Second Step:
Change in index.html
<base href="/"> to <base href="./">
Third Step:
Put all files into server(may be htdocs in localhost or any server)
Hopefully it will work.
Solution without server:
First Step:
Change in index.html:
remove <base href="/">
Second Step:
Change in app.module.ts:
import { CommonModule, APP_BASE_HREF, LocationStrategy, HashLocationStrategy} from '#angular/common';
#NgModule({
providers: [
{ provide: APP_BASE_HREF, useValue: '/' },
{ provide: LocationStrategy, useClass: HashLocationStrategy }
]
})
Third Step:
Run the command
ng build
or
ng build -prod
Doubleclick dist/index.html to see the result.
If you're using Angular-Cli you don't need to amend index.html after building the project.
As per Angular-CLi github document https://github.com/angular/angular-cli#base-tag-handling-in-indexhtml
you can simply modify argument while you're building the project:
Example: ng build --prod --base-href .
The actual Usage is:
ng build --base-href <base>
you can simply introduce a specific url instead of base. In this example we use . (dot) as an argument
A simple solution: Change your base href when you build.
ng build --prod --base-href .
Now you can double click the index.html file and it will work.
Here is an example of this working: https://mattspaulding.github.io/angular-material-starter/
You must serve the /dist folder using an HTTP server. You can't get around this because loading files locally doesn't allow code execution for security reasons.
The server doesn't have to be something heavy like Express or even a highly featured minimalist one like HapiJS. The built in Node http-server will do just fine. If you've already got Apache, nginx, or IIS set up you can also use them to serve your app.
EDIT: I did some moral searching and decided to offer up a solution I personally wouldn't use, but may be a good fit for you: Web Server for Chrome Extension
All you need is to build your app using this one line of code:
ng build --prod --base-href ./
I recommend use Expressjs, why servers how xampp, laragon, etc... the routes not work well, I did it like that: I created new folder with name server, inside copied an file index.js, the route would be "src/assets/server/index.js" ,
Index.js content
var express = require('express'),
path = require('path'),
fs = require('fs');
var app = express();
var staticRoot = __dirname + '/../../';
app.set('port', (process.env.PORT || 80));
app.use(express.static(staticRoot));
app.use(function(req, res, next){
var accept = req.accepts('html', 'json', 'xml');
if(accept !== 'html'){
return next();
}
var ext = path.extname(req.path);
if (ext !== ''){
return next();
}
fs.createReadStream(staticRoot + 'index.html').pipe(res);
});
app.listen(app.get('port'), function() {
console.log('app running on port', app.get('port'));
});
In package.json, inside the root of project
{
"dependencies": {
"express": "4.13.4"
}
}
later, run in console command ng build prod and run
node dist/assets/server/
this command execute an express server, indicating the direction of file config our server, on this occasion, the file index.js preconfigured
p.s: sorry for my bad english, I am learning
Removing <base href="/"> from index.html worked for me.
You can achieve something like this using nw.js for example (or electron). I created an app myself that uses angular 2 locally with nw.js and it works like a charm ;)
nwjs.io
use ng serve --open to build the application and start a web server
I'm trying to install a simple node webserver following the example in Pro AngularJS from apress.
I've installed node.js and the connect and karma modules.
I do get a warning when I installed karma via: "npm install -g karma" that says "optional dep failed, continuing" but then seems to install correctly.
I created a server.js based on the example:
var connect = require('connect');
connect.createServer(
connect.static("../angularjs")
).listen(5000);
when I run it I get TypeError:Undefined is not a function pointing to connect.static.
Apparently in the latest build of connect the static middleware has been moved to it's own package.
nodejs connect cannot find static