localhost:3000 This site can’t be reached after installing http-proxy-middleware - reactjs

I am building a newsletter sign-up form that uses .netlify-lambda to send my form submission to Mailchimp. I installed http-proxy-middleware to help the front end find the netlify-lambda folder. After writing the proxy setup code below my React start script stopped working. It appears the proxy setup below is interfering with localhost:3000.
My proxy setup looks like this
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
console.log('Using proxy...')
app.use(proxy('/.netlify/functions/', {
target: 'http://localhost:9000/',
"pathRewrite": {
"^\\.netlify/functions": ""
}
}));
};
If the target is localhost:9000 why is it interfering with localhost:3000?
When I start my Lambda server it says: Lambda server is listening on 9000.
I am also getting this error when trying to compile my client app.
crbug/1173575, non-JS module files deprecated

Short answer (for #lachnroll and anyone who might be encountering the same problem):
Please use const { createProxyMiddleware } = require("http-proxy-middleware") and app.use(createProxyMiddleware('/.netlify/functions/' ...)...) , instead of using const proxy = require('http-proxy-middleware'); and app.use(proxy("/.netlify/functions/" ...)...) , it should work.
Long one:
I've come across the same "can't be reached" thing in a React project when using http-proxy-middleware(2.0.3), until I changed const proxy = require('http-proxy-middleware'); and proxy("/.netlify/functions/" ...) to const { createProxyMiddleware } = require("http-proxy-middleware"); and app.use(createProxyMiddleware('/.netlify/functions/' ...)...) , I think the proxy has been removed, see: https://github.com/chimurai/http-proxy-middleware#readme

Related

Vite serving shader file with wrong (none) MIME type

I'm developing a BabylonJS application. BabylonJS PostProcess class appends .fragment.fx to a given file name and requests that from the server. When my local Vite (version 4.0.4) dev server serves this file the content-type header is empty. This causes Firefox to intepret it as type xml and fail. Chrome fails through a different, but I think related, mechanism.
How do you configure Vite to serve the *.fragment.fx static files as text/plain? I assume I need to disable the default middleware and write some custom code instead, like this: https://vitejs.dev/config/server-options.html#server-middlewaremode but I wanted to first check there wasn't something else going on / a simpler way to configure / fix this.
The vite dev server is started using vite --host --port 3000 --force and the config in vite.config.js is:
import { defineConfig } from 'vite';
export default defineConfig(({ command, mode }) => {
// if (command === 'serve') {
// return {
// // dev specific config
// }
// } else {
// // command === 'build'
// return {
// // build specific config
// }
// }
return {
resolve: {
alias: {
"babylonjs": mode === "development" ? "babylonjs/babylon.max" : "babylonjs",
}
},
base: "",
// assetsInclude: ['**/*.fx'],
};
});
* edit 1 *
I have seen there's a parameter ?raw that can be added to the URL however I don't control how BabylonJS forms the URL so I can't see how to make this work in this situation.
I followed these instructions and set up a dev server using express. I added this block of code above the call to app.use(vite.middlewares):
app.use("**/*.*.fx", async (req, res, next) => {
const url = req.originalUrl
const file_path = path.resolve(__dirname, "." + url)
const file = fs.readFileSync(file_path, "utf-8")
res.status(200).set({ "Content-Type": "text/plain" }).end(file)
})
I now start the dev server using the following script line in the package.json of "dev": "node server",
I could not find a way to solve this by configuring the default vite dev server.

Fetching a github repo in react gives a "Module "stream" has been externalized for browser compatibility and cannot be accessed in client code" error

I am currently stuck with a problem trying to fetch github repo data using the octokit npm package.
I use vite to run a dev server and when I try to make a request, the error that i get is:
Uncaught Error: Module "stream" has been externalized for browser compatibility and cannot be accessed in client code.
My React .tsx file looks like this:
import { Octokit, App } from 'octokit'
import React from 'react'
const key = import.meta.env.GITHUB_KEY
const octokit = new Octokit({
auth: key
})
await octokit.request('GET /repos/{owner}/{repo}', {
owner: 'OWNER',
repo: 'REPO'
})
export default function Repos() {
return (
<>
</>
)
}
I have redacted the information for privacy purposes.
If anyone knows how to resolve this issue with vite, please let me know!
Check first if this is similar to octokit/octokit.js issue 2126
I worked around this problem by aliasing node-fetch to isomorphic-fetch. No idea if it works for all usages within octokit, but works fine for my project.
You'll need to install the isomorphic-fetch dependency before making this config change.
// svelte.config.js
const config = { // ... kit: {
// ...
vite: {
resolve: {
alias: {
'node-fetch': 'isomorphic-fetch',
},
},
},
},
};
export default config;
Note: there are still questions about the support/development of octokit: issue 620.

Webpack dev server sockjs-node returns 404 error

I am running a simple Vue app with webpack that I created with the vue-cli. When I run the dev server wtih npm run serve, it shows several errors in the client console when using sockjs-node. I believe this module is used by webpack for hot reloading (HMR).
The first error is:
Access to XMLHttpRequest at 'http://192.168.1.4:8080/sockjs-node/info?t=1615330207390' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I can solve this in two ways by editing the devServer in my vue.config.js. The first method is by setting public: 'localhost:8080'; and the second is by setting headers: {'Access-Control-Allow-Origin': 'http://192.168.1.4:8080', 'Access-Control-Allow-Credentials': 'true'}.
In both cases, I then see the following two errors:
POST http://localhost:8080/sockjs-node/690/qvgqwbdo/xhr_streaming?t=1615330686134 404 (Not Found)
GET http://localhost:8080/sockjs-node/690/zympwfsc/eventsource 404 (Not Found)
How do I resolve these errors so that the hot reloader will connect?
In the function I set to devServer.before in my vue.config.js file, I created my own websockets using Socket.io on the same port as my devSever. When the function returned, the devServer could not use that port for websockets, so it failed to launch sockjs-node. Therefore, when the frontend client tried to connect to the devServer, the requests were going to my sockets, instead of the devServer sockets, and it was ignoring them. Hence the 404 errors.
Here is my original code:
// server.js
const { createServer } = require('http')
const io = require('socket.io')
const addSocketEvents = require('./socket-api')
const port = process.env.PORT || 8080
module.exports = {
port,
configure(app) {
// `app` is an instance of express
// add the websockets
const httpServer = createServer(app)
socket = io(httpServer, {
path: '/socket-api'
})
addSocketEvents(socket)
// starts the server
// cannot use app.listen() because that will not start the websockets
httpServer.listen(port)
}
}
// vue.config.js
const { port, configure } = require('./server')
module.exports = {
devServer: {
before: configure,
public: `localhost:${port}`,
},
}
To fix this issue, I needed to allow the devServer to use the original port for sockjs-node, and launch my sockets on a different port. However, because I need to use the same port in production (due to restrictions by my current hosting provider), I only want my sockets to use a different port when running the devServer. To do this, I simply created a different httpServer and launched it on a different port, then created a proxy in the devServer config for that port. In my configure function, I just check to see if it is running in dev or prod, and act accordingly.
My production server is a simple express instance which calls the same configure function after it is created. This allows me to put all my startup code in one place.
Here is my new code:
// server.js
const { createServer } = require('http')
const io = require('socket.io')
const addSocketEvents = require('./socket-api')
const port = process.env.PORT || 8080
const proxyPort = 8081
module.exports = {
port,
proxyPort,
configure(app) {
// `app` is an instance of express
// add the websockets
let httpServer, socketPort
if (process.env.NODE_ENV === 'development') {
httpServer = createServer()
socketPort = proxyPort
} else {
httpServer = createServer(app)
socketPort = port
}
// adds the socket-api to be used via websockets
socket = io(httpServer, {
path: '/socket-api'
})
addSocketEvents(socket)
// starts the server
httpServer.listen(socketPort)
}
}
// vue.config.js
const { port, configure } = require('./server')
module.exports = {
devServer: {
before: configure,
public: `localhost:${port}`,
proxy: {
'/socket-api': {
target: `http://localhost:${proxyPort}`,
ws: true
}
}
},
}

React build causes CORS error when there were no issues in development

I have built a React application (my first React application), and a C#.NET Core 3.1 Web API which serves data to the UI. I am deploying the API and the React application on the same server (Windows 10) with port 3030 for the API and port 3029 for the React build which was generated running the command "npm run build". The IIS site for the UI was pointed at the build directory.
In my development environment, running the application using the deployed API works and no proxy is needed. When deployed, my screen loads but no records are retrieved via the FETCH and instead there is a CORS error:
Access to fetch at 'http://localhost:3030/api/checking' from origin 'http://localhost:3029' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Why does this work when running out React in development out of Visual Studio Code with a hot load and why does this not work after the deployment? More importantly, how do I get this to work?
API code from Startup.cs
ConfigureServices method
services.AddCors(options => {
options.AddDefaultPolicy(builder => {
builder.WithOrigins(Configuration["AppSettings:CorsUrl"])
.AllowAnyHeader()
.AllowAnyMethod();
});
});
Configure method
app.UseCors();
AppSettings.js code
"AppSettings": {
"CorsUrl": "http://localhost:3029"
}
React
I am storing my url within an .env file at the root level as shown below.
REACT_APP_API_URL=http://localhost:3030/api/checking
React Fetch command
In my checking.js component, the data is loaded and a FETCH is performed.
const SERVER_URL=`${process.env.REACT_APP_API_URL}`
function Checking() {
const [rowData, setRowData] = useState([]);
const [newData, setNewData] = useState(initialState);
const [displayModal, setModalDisplay] = useState(false);
const columnDefinitions = Columns();
const rowDataRef = useRef(rowData);
useEffect(() => {
fetch(SERVER_URL)
.then((response) => response.json())
.then((rowData) => {
setRowData(rowData)
rowDataRef.current = rowData;
});
}, []);
.
.
.
You need to set the Access-Control-Allow-Origin header. try the following methods to solve this error.
1.Clear your cookies and add Access-Control-Allow-Origin': '*' by Mod Header extension and
try again to check the fix .
2.Try using a middle interface to control your request and guide them
into the special rules.
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
It turns out that I noticed a component misbehaving (ag-grid) and that caused me to run npm update. Once that was complete, I redeployed the build and everything is now working. I believe the update 'fixed' the issue.

React/Next.js recommended way to set constants such as backend API URLs

I am looking through next.js documentation and trying to understand what the suggested approach is for setting URLs that change in different environments. Mostly, I want to ensure that I'm pointing backend URLs correctly in development versus production.
I suppose you can create a constants configuration file, but is there a supported, best practice for this?
Open next.config.js and add publicRuntimeConfig config with your constants:
module.exports = {
publicRuntimeConfig: {
// Will be available on both server and client
yourKey: 'your-value'
},
}
you can call it from another .js file like this
import getConfig from 'next/config'
const { publicRuntimeConfig } = getConfig()
console.log(publicRuntimeConfig.yourKey)
or even call it from view like this
${publicRuntimeConfig.yourKey}
You can configure your next app using next-runtime-dotenv, it allows you to specify serverOnly / clientOnly values using next's runtime config.
Then in some component
import getConfig from 'next/config'
const {
publicRuntimeConfig: {MY_API_URL}, // Available both client and server side
serverRuntimeConfig: {GITHUB_TOKEN} // Only available server side
} = getConfig()
function HomePage() {
// Will display the variable on the server’s console
// Will display undefined into the browser’s console
console.log(GITHUB_TOKEN)
return (
<div>
My API URL is {MY_API_URL}
</div>
)
}
export default HomePage
If you don't need this separation, you can use dotenv lib to load your .env file, and configure Next's env property with it.
// next.config.js
require('dotenv').config()
module.exports = {
env: {
// Reference a variable that was defined in the .env file and make it available at Build Time
TEST_VAR: process.env.TEST_VAR,
},
}
Check this with-dotenv example.

Resources