I am new in the software field, please have patience with my question and mistakes of technical terms:
Premises:-
I have developed an front-end application using Angular4. The baseURL define in angular application is 'http://localhost:3000/'. My application uses restangular api to interact with json-server (I created a folder named json-server and it has db.json and public folder ). It is working perfectly fine when i start the json-server using command:
json-server json-server --watch db.json
My application is finalized and thus I created a production build. Thereafter I moved all my files from dist folder to public folder of json-server. When i start the json-server, my application works fine.
Actual problem:-
Now I wanted to host in azure. I simply copied all file/folder (db.json and public folder) from json-server folder as it is and put them in azure cloud. When azure hosting is done and I open the url in browser I got an error- "you don't have permission to view".
To rectify above error I deleted all files from azure and then I copied all files of dist folder and put them in azure cloud. Using this I could able to see the application in the browser but no images. At image there is an error- Response with status: 0 for URL: null
When I start json-server locally, everything works fine but of course when same web page open from other machines I got the same error- Response with status: 0 for URL: null
Is there any way to run json-server in azure so that all machines/mobile when accessing the url, can see proper web page without any error.
Step to step to run json-server on Azure Web App:
Open your browser and go to App Service Editor (https://<your-app-name>.scm.azurewebsites.net/dev/wwwroot/)
Run the command in the Console (Ctrl+Shift+C)
npm install json-server --save-dev
Put all file/folder (db.json and public folder) into wwwroot folder
Create a server.js with the following content
const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('db.json')
const middlewares = jsonServer.defaults()
server.use(middlewares)
server.use(router)
server.listen(process.env.PORT, () => {
console.log('JSON Server is running')
})
Click Run (Ctrl+F5), this will generate web.config file automatically and open your website in the browser.
You can use the following to quickly setup a mock service which can serve REST APIs off static JSON files.
json-server
Just install the NodeJS module ($npm install -g json-server). Populate a static json file in the format attached and then run the JSON server ($ json-server --watch db.json --port 3000)
Related
I have a working forge application ( bim360 hub sidebar with forge viewer and some charts).
It is currently running from Visual Studio Code IDE only. I want to build the app into an .exe file in order to be able to send it to a user, upload it to a server with IIS, etc..
General details:
I used Petr Broz tutorial to set up the backend of the viewer and hub
(Forge online training - view your models https://www.youtube.com/watch?v=-O1e3gXCOEQ&t=8986s )
The app is running on Node.js
I tried to use 'nexe' module and build executable file. With this method, I need to specify index.js file ("an entry point") and define a 'nexe.config.js' file. I used the entry point start.js.
Eventually, I managed to create an exe file - and when I run it from the command line, I get an error
Missing FORGE_CLIENT_ID or FORGE_CLIENT_SECRET env. variables.
although I have them in the config.js
Main questions:
Is there another way to build a close exe file from visual studio code - for a forge web application?
Am i doing something wrong with the processes I mention above?
Is it even possible to deploy a web application to IIS using an exe file?? all of the documentation points toward Azur, AWS and heroku..
Relevant files:
1) start.js:
const path = require('path');//bringing in built in node js modeules ( to resulve file system path )
const express = require('express');//module to create the express server
const cookieSession = require('cookie-session');
//any piece of code would have an opportunity to handle the request
const PORT = process.env.PORT || 3000;
const config = require('./config.js');
if (config.credentials.client_id == null || config.credentials.client_secret == null) {
console.error('Missing FORGE_CLIENT_ID or FORGE_CLIENT_SECRET env. variables.');
return;
}
let app = express();
//static middlewere to check for the front end files (html,js,css)
app.use(express.static(path.join(__dirname, 'public')));//method inside express module: a middlewere for serving static files this line will check in 'public' folder if the request
//that is sent (specific file) is in there. if so - it will ignore the rest of the stack(the rest of the code)
app.use(cookieSession({
// create 2 cookies that stores the name and encripted key
name: 'forge_session',
keys: ['forge_secure_key'],//takes cater of decipher the encription for the forge key for us
maxAge: 14 * 24 * 60 * 60 * 1000 // 14 days, same as refresh token
}));
app.use(express.json({ limit: '50mb' }));//middlewere that looks at the title of the request - and if its .json it will look at the body of the request and parese it to javascript object
app.use('/api/forge', require('./routes/oauth.js'));//adding our custom express routers that will handle the different endpoints.
app.use('/api/forge', require('./routes/datamanagement.js'));
app.use('/api/forge', require('./routes/user.js'));
app.use((err, req, res, next) => {
console.error(err);
res.status(err.statusCode).json(err);
});
app.listen(PORT, () => { console.log(`Server listening on port ${PORT}`); });
2) config.js:
// Autodesk Forge configuration
module.exports = {
// Set environment variables or hard-code here
credentials: {
client_id: process.env.FORGE_CLIENT_ID,
client_secret: process.env.FORGE_CLIENT_SECRET,
callback_url: process.env.FORGE_CALLBACK_URL
},
scopes: {
// Required scopes for the server-side application-->privliges for our internal opperation in the server side ("back end")
internal: ['bucket:create', 'bucket:read', 'data:read', 'data:create', 'data:write'],
// Required scope for the client-side viewer-->priveliges for the client ("front end")
public: ['viewables:read']
}
};
Author of the tutorial here :)
I'm not sure how nexe works exactly but please note that the sample app expects input parameters such as FORGE_CLIENT_ID or FORGE_CLIENT_SECRET to be provided as environment variables.
As a first step, try running your *.exe file after setting the env. variables in your command prompt.
If that doesn't work, try hard-coding the input parameters directly into the config.js file (replacing any of the process.env.* references), and then bundle everything into an *.exe file. This is just for debugging purposes, though! You shouldn't share your credentials with anyone, not even inside an *.exe file. So as an alternative I'd suggest that you update the sample app to read the input parameters from somewhere else, perhaps from a local file.
after trying a lot of solutions, i got to the conclusion that the reason that nothing happened was that the oathantication files ( with the clint_id and clint_password) was not embedded in the .exe file.
the way to include those files with the nexe module is to use the flag -r "Foldername/subfoldername/filename.js".
first, crate a nexe.config.js file that would contain the entry point file name to the app. ( in my case, the file name is " start.js")
second, write the following commands in the command line:
cd C:\Projects\MyAppFolder
npm install -g nexe
// specify all the files you want to include inside the exe file
nexe start.js -r "config.js" -r "nexe.config.js" -r "routes/common/oauth.js" -r "routes/*.js" -r "public//." -r ".vscode/**/." -r "package-lock.json" -r "package.json" --build --output "AppName.exe"
I am currently trying to connect a frontend (React) to a backend (Express/nodejs) within Azure App Services. I am using Windows, since "Virtual applications and directories" are currently not available for Linux. However, according to my research, that is necessary in this case.
Backend sample: server.js
const express = require('express');
const app = express();
const port = 3003;
require("dotenv").config(); // For process.env
[...]
app.get("/api/getBooks", async (req, res) => {
const books = await Books.find();
res.send(books);
});
Frontend sample: App.js
const getBooks = () => {
axios.get('/api/getBooks')
.then(res => {
setBooks(res.data);
console.log("Got books: ")
console.log(res.data);
})
.catch(err => {
console.log(err);
})
}
Azure: Folder structure
site/server/server.js (Express)
site/wwwroot/index.html (React)
I successfully executed "npm install" via "Development Tools/Console".
The two are already connected via Virtual applications in Azure by using the following configuration.
Virtual applications
The app generally loads succesfully. However, the connection to the backend is not working.
How can I start the node.js server now on Azure and make the proxy working?
I tried to start the server via "node server" on the console. But this does not seem to be working.
I discovered two possible ways to solve this issue.
Assuming you have a client (client/App.js) and a server (server/server.js).
Serve the React App via node.js/Express
Based on the above architecture, a little bit of structure needs to be changed here. Because the React app is no longer output through its own server, but directly through Express.
In server/server.js, the following function must be called after express is declared.
app.use(express.static("../client/build"));
After defining some endpoints to the APIs, the last API node to define is the default route - the static output of the React build.
app.get("/", (res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
Using an FTP client, you can now create the /client/build directory that will contain the built React app. Of course, another directory structure can be used.
The client files from the built React app are then simply uploaded there.
The deployment from the server is best done via Visual Studio Code and the Azure plugin.
In the above structure, /server would then be deployed to your in the Azure extension (Azure/App Services --> Right click on "myapp" --> Deploy to Web App ...)
Create two App Services
For example: myapp.azurewebsites.net & myapp-api.azurewebsites.net
myapp must simply contain the built React app (/build) in the wwwroot directory. This can be achieved via FTP.
The deployment from the /server to *myapp-api is best done via Visual Studio Code and the Azure plugin.
In the above structure, /server would then be deployed to myapp-api in the Azure extension (Azure/App Services --> Right click on "myapp-api" --> Deploy to Web App ...)
Also worth mentioning is that CORS should be configured, so that API calls can only be made from myapp.azurewebsites.net. This can be configured in the Azure Portal.
Occasionally the node dependencies have to be installed afterwards via the SSH console in the Azure Portal. For me it sometimes worked automatically and sometimes not.
To do this, simply change to the wwwroot directory (of the /server) and execute the following command.
npm cache clean --force && npm install
Combine this with React Router
React Router is usually used with React. This can be easily combined with a static-served web app from Express.
https://create-react-app.dev/docs/deployment/#other-solutions
Excerpt
How to handle React Router with Node Express routing
https://dev.to/nburgess/creating-a-react-app-with-react-router-and-an-express-backend-33l3
I have deployed a NextJs app on digitalocean droplet with Ubuntu 22.04.
"next": "12.2.3",
"react": "18.2.0",
I am getting this 404 error for _ssgManifest.js, _buildManifest.js and _next/static/chunks/pages/_app-83b8d0a73a58c453.js files.
enter image description here
I checked the build on server, files are present there, but in broweser they are showing 404. Another thing I noticed that the file _app-83b8d0a73a58c453.js getting fetched on browser but on server build it is with different name i.e. _app-8ba37a8edc5ef34c.js
What I Tried
I checked with and without custom dir for build, but it didn't worked
I checked with custom buildID too
const execSync = require("child_process").execSync;
const lastCommitCommand = "git rev-parse HEAD";
module.exports = {
async generateBuildId() {
return execSync(lastCommitCommand).toString().trim();
},
};
any help would be greatly appreciated
Solution:
These files were not matching to what is asked in browser request to what is available at build on server. In my case the reason was that, after build i was not restarting the application.
if you are using pm2 to serve your application named fe, please run:
pm2 restart fe
Then Hard refresh your website in browser, it will work.
If you are using other tool, then please follow docs for the same to restart the application. And if the issue is diffrent than this in your case, please share your solution here.
Thank you.
I'm trying to set up a reverse proxy on the development server for my VUE js webapp to get around the CORS issue that I was getting when I was trying to use my flask HTTP APIs with the vue js webapp.
I did this by creating a vue.config.js file in the root of the project directory:
module.exports = {
devServer: {
proxy: 'http://localhost:5001/'
}
}
when I run npm run serve, and try to use a REST API defined on port 5001 - I don't see the request going to port 5001, it uses the same port as the web app.
And there are no useful logs being written to stdout either to help me debug this.
Has anyone come across this issue before ?
I had a similar issue and found that the port was already in use by another application and hence it was not going to the correct port. Once i shutdown the other app, it started working as expected.
I have developed node rest api and vuejs web applications,
Im trying to deploy both project in to one aws server which run ubuntu.
Both applications have different port,
domain I try to configure api.example.com for api and example.com for vue app.
I can run both applications once after running the command in SSH, but I need them to run it forever.
What I did,
Deploy to apps separately
Apps can access with ports
I need them access
api.example.com
example.com
what are the step to do,
Any changes host file.
I found another way to deploy vue app and express/nodejs in one server without using PM. This what I did
Build your vue code using npm run build command. This will create a folder dist which should have index.html file and static folder.
Copy dist folder into your server code repository. In my case I created a folder public and moved the dist folder inside public.
In app.js file right before module.exports=app line, copy the following lines of code
//These 2 lines make sure that vue and express app are coming from the same server.
app.use('/static', express.static(path.join(__dirname,"../public/dist/static/")));
app.get('/', function(req,res) {
res.sendFile('index.html', { root: path.join(__dirname, '../public/dist/') });
});
First line make sure that the /static folder is accessible and second line will serve the index.html file when you run the node server. Routing between components will be taken care by vue.
This is how we are running our VueJS UI and ExpressJS REST API from the same server.
We are managing our services with PM2.
VueJS (Dev Environment, You can add the same settings to production)
In package.json add "start": "HOST='0.0.0.0' PORT=80 npm run dev",, where 80 is the port VueJS is listening on, to the "scripts": {..} array. Then, after installing PM2, (for dev) we can start VueJS with cd /location/of/vue/root; sudo pm2 start npm run dev --name Vue -- start. (Make sure that Apache is not running).
Please note that setting the HOST to 0.0.0.0 is important. Do not set it to LocalHost or your Servers IP address or you may run into issues.
ExpressJS
In the /location/of/express/app.js add this similar to the bottom of the file:
app.listen(process.env.PORT || 8081), where 8081 is the port your REST API should be listening on. I can then start it with sudo pm2 start /location/of/express/app.js --name Express
At this point, the VueJS should be available at www.example.com (implied Port 80) and the REST API would be available at www.example.com:8081.
If you want to have api.example.com/ point to the API, you need to make sure that your DNS is pointing the "api" subdomain to the desired port, or you may have to add the port into the URL as above.
Additionally, you can easily follow the logs through PM2 as well with pm2 logs APPNAME --lines 100.