webpack-dev-server making sockjs request on wrong port - node.js

For development, I'm starting my Node application on port 4000 and Webpack Dev Server on port 4001
process.env.NODE_DEBUG --> [undefined][false]
[INFO] Port '4000' is available for http server.
[INFO] Port '4001' is available for dev server statics.
Webpack: Starting ...
In our Node application, whenever a 404 is encountered, we generally retry that error. The issue that's happening is that I'm seeing is that a sockjs-node request is made to the wrong port which causes a cascading series of 404s as the application tries to retry the invalid sockjs url. What I can't figure out is why it's being made to port 4000 instead of 4001 in the first place.
Here is my webpack dev server config
config.entry.client.unshift(`webpack/hot/only-dev-server`);
config.output = {
path: paths.appBuildPublic,
publicPath: 'localhost:4001',
pathinfo: true,
libraryTarget: 'var',
filename: 'static/js/bundle.js',
chunkFilename: 'static/js/[name].chunk.js',
devtoolModuleFilenameTemplate: info => path.resolve(info.resourcePath).replace(/\\/g, '/')
};
config.devServer = {
disableHostCheck: true,
clientLogLevel: 'info',
compress: true,
headers: {
'Access-Control-Allow-Origin': '*'
},
overlay: true,
port: devServerPort,
https: {
...createCertificate()
},
quiet: false,
watchOptions: {
ignored: /node_modules/
}
};
config.plugins = [
...(config.plugins || []),
new ErrorOverlayPlugin(),
new webpack.HotModuleReplacementPlugin({
}),
new webpack.DefinePlugin(dotenv.stringified)
];
In my express router I've configured the following
.use('/sockjs-node', (req: Request, res: Response) => {
if (process.env.NODE_ENV === 'development') {
res.status(200).send();
}
})
However, this is really a hacky way of solving the problem. Does anyone know why this sockjs request is made to my Node server instead of the webpack dev server? Any help would be really appreciated.

Related

I can't setup proxy in mern stack(react-vite) and do not know the reason

I'm developing mern stack web application with react from vite.js and have a problem to deal with proxy.
my client side runs at http://localhost:3000 and server side runs at http://localhost:5000.
usually I use http-proxy-midlleware to connect my server and client like below
src/setupProxy.jsx
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app){
app.use(
createProxyMiddleware('/api', {
target: 'http://localhost:5000',
changeOrigin: true
})
)
};
However, It didn't work and still sent to localhost:3000 when I post data to server with axios. I googled it and figured out that with vite.js I need to use vite.config.js
so I set up vite.config.js like below
import { defineConfig, HttpProxy } from 'vite'
import react from '#vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: {
host: true,
port : 3000,
proxy: {
'/api': {
target: 'http://localhost:5000',
changeOrigin: true
}
}
},
})
and tried axios call again.
const result = await axios.post('api/users/login', dataToSubmit)
.then(res => res.data);
return result;
However, contrary to my expectation, It still sent to 3000 and I do not have a clue about what is going wrong :/
xhr.js:210 POST http://localhost:3000/api/users/login 404 (Not Found)
could you tell me how to fix it? thanks for reading, your help will be appreciated.
It's required to specify secure: false like this. Reference
export default defineConfig({
plugins: [react()],
server: {
host: true,
port : 3000,
proxy: {
'/api': {
target: 'http://localhost:5000',
changeOrigin: true,
secure: false
}
}
},
})
I had this problem too.
My backend runs on http://localhost:8080, while my frontend runs on http://localhost:3000.
To resolve the cross-origin issue, I used the proxy alternative, but every request was returning a 404 error.
My solution was to add the rewrite: (path) => path.replace(/^\/api/, "") function in the vite settings file.
Finally, the final result of the file was:
import { defineConfig } from "vite";
import react from "#vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
server: {
proxy: {
"/api": {
target: "http://127.0.0.1:8080",
changeOrigin: true,
secure: false,
ws: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
port: 3000,
},
plugins: [react()],
});
Your port in vite.config.js file is set to 3000. So you have to set your target in src/setupProxy.jsx to 'http://localhost:3000'.
hope it helps

Multiples devServer proxies and multiples ports

I need to query automated routes generated from from https://github.com/o1lab/xmysql on port 3000 from my vue.js dev env running on port 8080 .
vue.config.js :
module.exports = {
devServer: {
proxy: {
"/api": {
target: "http://localhost:80", // Works perfeclty
},
"/": {
target: "http://localhost:80", // Works perfectly
},
"/generated": { // Not working
target: {
port: 3000
},
secure: false,
ws: false,
changeOrigin: true
}
},
hot: true,
liveReload: true,
}
};
xmysql params :
xmysql -h localhost -u root -p password -n 3000 -a /generated/ -d myDatabase
My vue.js axios "get" query :
axios
.get('/generated/meetings', {
headers: {
'Access-Control-Allow-Origin': 'all',
}
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error);
});
The Error :
Cannot GET /generated/meetings
I can access localhost routes on my localhost:3000 into my firefox navigator and they work really well:
Looks like the proxy is not working, any idea ?
I have tried this other vue.config.js params with no luck :
devServer: {
proxy: {
"/api": {
target: "http://localhost:80",
// ,pathRewrite: {'^/api' : ''}
},
"/": {
target: "http://localhost:80",
},
"/generated": {
target: "http://localhost:3000",
pathRewrite: { '/generated': '' },
secure: false,
ws: false,
changeOrigin: true
}
},
hot: true,
liveReload: true,
}
The only thing working is this query :
axios
.get('localhost:3000/generated/meetings', {
headers: {
'Access-Control-Allow-Origin': 'all',
}
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error);
});
But then, there is a CORS problem, and I can't get 'response', even if it gets displayed in the firefox console query, I can only get the error .
sorry, It seems that it was a /api/ conflict caused by a generic mongoDb back end starting by /api/ running in parrallel.
I ended up with this vue.config.js . Now my Mysql queries will go to /api routes, and my mongoDb queries will go to the generic-api routes, so I am able to handle 2 databases in one vue.js app:
module.exports = {
devServer: {
proxy: {
"/api": {
target: "http://localhost:3000", // This is set for xmysql routes generator https://github.com/o1lab/xmysql
},
"/": {
target: "http://localhost:80", // Serving the vue.js app
},
"/generic-api": {
target: "http://localhost:80", // When using generic-crud.js with mongoDb
}
},
hot: true,
liveReload: true,
}
}
And this is my xmysql standard config , now :
xmysql -h localhost -u root -p password -n 3000 -d myDatabase
EDIT : NEW :
Ho no, when I trigger NPM RUN BUILD, my /api routes are not working any more in my vue.js production app!
RESOLVED : Added a NODE EXPRESS proxy like this in my server.js node file :
// -------------------------------
// PROXY ALL API ROUTES QUERIES TO PORT 3000 TO USE WITH MYSQL ROUTES GENERATOR https://stackoverflow.com/questions/10435407/proxy-with-express-js
// -------------------------------
var proxy = require('express-proxy-server');
app.use('/api', proxy('http://localhost:3000/api'));
Now, even my vue.js production app queries are proxied to http://localhost:3000 , so it should work on heroku ...

Web process failed to bind to $PORT heroku deploy error with node.js

Error
I reread all the answers to a similar problem, but my problem is not solved.
My MERN app tree:
Weather-app:
client
dist/build
node_modules
server
babelrc
package.json
Procfile
server.js
webpack.config.js
Procfile:
web: npm start
Package.json
"scripts": {
"build": "webpack",
"start": "webpack-dev-server --open && node server.js"
},
server.js
mongoose.connect(process.env.MONGO_URL);
// Instantiate express
const app = express();
// Initialize routes middleware
app.use('/', require('./server/routes/user'));
app.use('/data', require('./server/routes/data'))
// Use express's default error handling middleware
app.use((err, req, res, next) => {
if (res.headersSent) return next(err);
res.status(400).json({ err: err });
});
// Start the server
app.listen(process.env.PORT, '0.0.0.0', () => {
});
webpack.config dev server
devServer: {
port: process.env.PORT || 3000,
host: 'localhost',
disableHostCheck: true,
public: 'weather-mern.herokuapp.com',
//Be possible go back pressing the "back" button at chrome
historyApiFallback: true,
noInfo: false,
stats: 'minimal',
publicPath: publicPath,
contentBase: path.join(__dirname, publicPath),
//hotmodulereplacementeplugin
hot: true
},
And in client/
I have request
How to change API_URL correclty?
const API_URL='http://localhost:3001'
axios({
method: 'post',
url: `${API_URL}/auth/login`,
data: formData
})

Testing API's With React Bundled With Webpack

I'm having trouble trying to run my API's when running my frontend react code. I am using webpack and webpack dev server but the problem seems to be that they run their own server while my apis are run by another. I think I can either make my application run entirely in my express backend but having trouble how or somehow use webpack dev server to run both. my backend express node looks like this
const express = require('express');
const bodyparser = require('body-parser');
const app = express();
require('./api/findMedia.js')(app)
var PORT = process.env.PORT || 8080;
const server = app.listen(PORT, () => {
console.log('server is working : ')
})
my webpack config looks like this. You can ignore my proxy key. I was testing webpack dev server to simultaneously run my express server.
var webpack = require("webpack");
var path = require('path');
module.exports = {
entry: {
app: "./src/app.js"
},
output: {
filename: "build/bundle.js",
sourceMapFilename: "build/bundle.map"
},
devtool: '#source-map',
devServer : {
historyApiFallback : true,
hot : true,
inline: true,
host: 'localhost',
port: 3000,
stats: 'errors-only',
proxy : {
'/api': {
host: 'localhost',
protocol: 'http',
port: 8080
}
}
},
plugins : [new webpack.HotModuleReplacementPlugin({multiStep: true})],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015']
}
},
{
test: /\.css$/,
loader: 'style!css'
}
]
}
}
and finally I call it in the front end with a simple post request using axios and inside my componentdidmount
componentDidMount(){
axios({
method: 'post',
url: '/find/media'
}).then((response)=>{
console.log('post request to mongo data from front end a success: ' + response)
console.log(response.data.findArticles)
}).catch((error)=>{
console.log('error'+error)
})
}
webpack-dev-server creates it's own server, like you said. If you want to run both webpack-dev-server and express, then you will need the proxy key in the devServer configuration object.
proxy : {
'/api': 'http://localhost:8080'
}
With your setup, what that would do is proxy any request beginning with /api to http://localhost:8080/api. So from your React code, you would do:
axios({
method: 'post',
url: '/api/find/media'
...
})
which webpack-dev-server would proxy to http://localhost:8080/api/find/media.
If your express router is listening for just '/find/media' the devServer.proxy config object has a rewritePath key.
proxy : {
'/api': {
target: 'http://localhost:8080',
rewritePath: {'^/api' : ''}
}
}
If you want express to handle everything, then I think you can use webpack-dev-middleware.

Getting browser-sync to play nice with ember-cli and a localhost API server

I've been trying to get browser-sync to play nice with ember-cli via ember-cli-browser-sync (installed via "ember-cli-browser-sync": "git://github.com/dylanharrington/ember-cli-browser-sync.git" in package.json as it isn't on the npm registery) with my localhost API server, but have been unable to get it to work.
Just doing
serverMiddleware: function(config) {
config.options.liveReload = false;
browserSync({
injectChanges: true,
reloadDelay: 10,
notify: false,
open: false,
proxy: "localhost:4200"
});
},
Works wonderfully for a local device, but fails at accessing my api at http://localhost:8000/api/1 from an external device (iPhone).
I tried to extend the proxy settings to include my local API via:
var url = require('url'),
proxy = require('proxy-middleware');
serverMiddleware: function(config) {
config.options.liveReload = false;
var proxyOptions = url.parse('http://localhost:8000/api/1');
browserSync({
injectChanges: true,
reloadDelay: 10,
notify: false,
open: false,
proxy: {
target: 'localhost:4200',
middleware: [proxy(proxyOptions)]
}
});
});
Which basically serves the API to my external URL provided by BrowserSync.
So I tried to utilise server:
serverMiddleware: function(config) {
config.options.liveReload = false;
var proxyOptions = url.parse('http://localhost:8000/api/1');
console.log(proxyOptions);
// proxyOptions.route = '/api';
browserSync({
injectChanges: true,
reloadDelay: 10,
notify: false,
open: false,
port: 3000,
server: {
baseDir: "./",
routes: {
"/app": "app",
"/assets": "dist/assets",
},
index: "app/index.html",
middleware: function (req, res, next) {
console.log(req.url);
next();
}
}
});
},
Which serves the correct index, and all the asset files, but causes an error with ember.
Does anyone have any experience doing this and which path I should try next? Is there a different NPM package I should try to use to proxy my API?
I gave up trying to solve this myself and ended up just using XIP, which might suit your needs.

Resources