When specified, "proxy" in package.json must be a string - reactjs

I would like to have proxy in my react client, my package.json contains:
...
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"proxy": {
"/auth/google": {
"target": "http://localhost:5000"
}
},
...
But when I ran it, I got error
When specified, "proxy" in package.json must be a string.
[1] Instead, the type of "proxy" was "object".
[1] Either remove "proxy" from package.json, or make it a string.
I tried to convert to string, no errors but proxy is not working
"proxy": "http://localhost:5000"
My App.js
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>hey there</p>
Sign In With Google
</header>
</div>

The issue that you are facing is because of CRA v2.
Firstly, you will not require any additional configuration if you are just using a plain string in your proxy. But the moment you use an object, you are using advanced configuration.
So, you would have to follow the steps listed below:
Install http-proxy-middleware by typing npm i --save http-proxy-middleware
Remove the entries from package.json:
"proxy": {
"/auth/google": {
"target": "http://localhost:5000"
}
}
Now create a setup file for your proxy. You should name it setupProxy.js in your src folder on the client side and type the following code:
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(proxy('/auth/google',
{ target: 'http://localhost:5000/' }
));
}
for more info check this

I think it is "create-react-app" issue.
You can go to https://github.com/facebook/create-react-app/issues/5103
to migration to the new proxy handling method.
For short, you just need to install a new library called "http-proxy-middleware"
npm install http-proxy-middleware --save
And then create a new file "src/setupProxy.js", and type
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(proxy('/auth/google', { target: 'http://localhost:5000/' }));
};
Hope this can solve your problem, happy hacking!

First, install http-proxy-middleware using npm or Yarn:
$ npm install http-proxy-middleware --save
$ # or
$ yarn add http-proxy-middleware
Next, create src/setupProxy.js and place the following contents in it:
const proxy = require('http-proxy-middleware')
module.exports = function(app) {
// ...
}
Now, migrate each entry in your proxy object one by one, e.g.:
"proxy": {
"/api": {
"target": "http://localhost:5000/"
},
"/*.svg": {
"target": "http://localhost:5000/"
}
}
Place entries into src/setupProxy.js like so:
const proxy = require('http-proxy-middleware')
module.exports = function(app) {
app.use(proxy('/api', { target: 'http://localhost:5000/' }))
app.use(proxy('/*.svg', { target: 'http://localhost:5000/' }))
}
You can also use completely custom logic there now!
I have got this working response from this link and hence sharing-https://github.com/facebook/create-react-app/issues/5103

For people in 2020,
Install http-proxy-middleware by typing npm i --save http-proxy-middleware inside the client folder.
Remove the entries from package.json:
"proxy": {
"/auth/google": {
"target": "http://localhost:5000"
}
}
Now create a setup file for your proxy. You should name it setupProxy.js in your src folder on the client side and type the following code:
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
createProxyMiddleware("/auth/google", { target: "http://localhost:5000/" })
);
};
PS: You don't need to include setupProxy.js anywhere in server.js or index.js. just copy and paste.

The following worked for me:
Remove "proxy" from your package.json.
Install 'http-proxy-middleware' in the client directory. To do this, cd into the client directory and run "npm i --save http-proxy-middleware". Then, create a new file in the src directory of your client called "setupProxy.js". Place the following code in this file:
const { createProxyMiddleware } = require('http-proxy-middleware');
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(createProxyMiddleware('/api/', // replace with your endpoint
{ target: 'http://localhost:8000' } // replace with your target
));
}
restart the server, and you should be good to go.

Change the proxy to something like this and hope it will work as it worked for me.
"proxy": "http://localhost:5000/auth/google"

At this moment i'm using React 16.8.13 this works fine:
1- delete "proxy": {***} from package.json file
2- type npm install http-proxy-middleware
3- create the file src/setupProxy.js
4-insert the code as following:
const {createProxyMiddleware} = require('http-proxy-middleware');
module.exports = (app) => {
app.use(
createProxyMiddleware('/endpoint/*', {
target: 'http://address/',
secure: false,
}),
);
};

If you need to proxy requests and rewrite urls, for example localhost:3000/api/backend/some/method to https://api-server.example.com/some/method, you need to use pathRewrite option also:
const {createProxyMiddleware} = require("http-proxy-middleware");
module.exports = function(app) {
app.use(
"/api/backend",
createProxyMiddleware({
target: "https://api-server.example.com",
changeOrigin: true,
pathRewrite: {
"^/api/backend": "",
},
})
);
};

install "http-proxy-middleware" into your client, "not inside server".
Add setupProxy.js inside of your client/src/ directory.
(should be like this: client/src/setupProxy.js)
Add the below lines to it.
const proxy = require("http-proxy-middleware");
module.exports = app => {
app.use(proxy("/auth/google", { target: "http://localhost:5000/" }));
};
That's it, get inside of your google dev console and add localhost:3000/auth/google/callback to your project.

https://github.com/facebook/create-react-app/issues/5103
Move advanced proxy configuration to src/setupProxy.js
This change is only required for individuals who used the advanced proxy configuration in v1.
To check if action is required, look for the proxy key in package.json. Then, follow the table below.
I couldn't find a proxy key in package.json
No action is required!
The value of proxy is a string (e.g. http://localhost:5000)
No action is required!
The value of proxy is an object
Follow the migration instructions below.
If your proxy is an object, that means you are using the advanced proxy configuration.
Again, if your proxy field is a string, e.g. http://localhost:5000, you do not need to do anything. This feature is still supported and has the same behavior.
First, install http-proxy-middleware using npm or Yarn:
$ npm install http-proxy-middleware --save
$ # or
$ yarn add http-proxy-middleware
Next, create src/setupProxy.js and place the following contents in it:
const proxy = require('http-proxy-middleware')
module.exports = function(app) {
// ...
}
Now, migrate each entry in your proxy object one by one, e.g.:
"proxy": {
"/api": {
"target": "http://localhost:5000/"
},
"/*.svg": {
"target": "http://localhost:5000/"
}
}
Place entries into src/setupProxy.js like so:
const proxy = require('http-proxy-middleware')
module.exports = function(app) {
app.use(proxy('/api', { target: 'http://localhost:5000/' }))
app.use(proxy('/*.svg', { target: 'http://localhost:5000/' }))
}
You can also use completely custom logic there now! This wasn't possible before.
It's worked.

app.use(
'/api',
proxy({ target: 'http://www.example.org', changeOrigin: true })
);
changeOrigin:true

In my cases i didn't need src/setupProxy.js...
I do that with axios... Check About Axios Proxy
Check in node library if you have it or not: http-proxy-middleware is optional i didn't need it!!!
Just try to restart server side, and that's it!!!
Add to check:
componentDidMount(){
axios.get('/api/path-you-want').then(response=>{
console.log(response)
})
}

This is related to a bug in create-react-app version2.
Just run
$ npm install react-scripts#next --save
$ # or
$ yarn add react-scripts#next
Answer found at:
https://github.com/facebook/create-react-app/issues/5103

...
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"proxy": {
"/auth/google": {
"target": "http://localhost:5000"
}
},
...
When specified, "proxy" in package.json must be a string.
Just change `"proxy": "http://localhost:5000"` and you are good to go.
If that doesn't solve the problem then register your proxy using **http-proxy-middleware**
$ npm install http-proxy-middleware --save
$ # or
$ yarn add http-proxy-middleware
Then create setypProxy.js file under src directory the put the following code.
const proxy = require('http-proxy-middleware');
module.exports = app => {
app.use(
proxy('/auth/google', {
target: 'http://localhost:5000'
})
);
app.use(
proxy('/auth/facebook', {
target: 'http://localhost:6000'
})
);
};

Create a setupProxy.js file inside the src folder and copy-paste the below code.
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
createProxyMiddleware("/auth/google", {
target: "http://localhost:5000/",
})
);
};

This worked for me (just as several people have already replied). But I write this just in case someone asks whether this is still a valid answer in 2021.
Delete this from your package.json file:
"proxy": {
"/auth/google": {
"target": "http://localhost:5000"
}
Install proxy middleware by running npm install --save http-proxy-middleware.
Create setupProxy.js file in your src (right next to the index.js file) file on the frontend.
In that setupProxy.js file put:
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(proxy('/auth/google',
{ target: 'http://localhost:5000/' }
));
Of course, your port can be anything. It does not have to be 5000. Where ever you are running your backend service at.
That is it. You do not have to import this file anywhere. It works as it is.

After creating a file in the client side (React app ) called
src/setupProxy.js make sure you restart the server. The package.json file needs to restarted since you were dealing with a file outside the source directory.

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.

How to configure the start script in webpack to use the api I want?

How to configure the start script in webpack to use the api I want?
For example when I run "npm start" my webpack source will use the productuion api like 'https://abc_loginapi.com, and when I run "npm run dev" the webpack source Mine will use local apis like http://localhost:9500/login.
My current way of doing it is quite manual, when I want to run one, I will comment the other one
export const API_HOST_LIST =
{
HostBaseURL: 'https://abc_loginapi.com'
// HostBaseURL: 'http://localhost:9500/login'
}
Is there any way to handle this problem, my source is webpack4 + reactJS
You can use environment variables to handle it, add env to script with --env argument, like this:
webpack --env prod // result { prod: true }
And call it in webpack config file
const path = require('path');
module.exports = env => {
// Use env.<YOUR VARIABLE> here:
console.log('Production: ', env.prod); // true
return {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
};
For more detail, check Webpack docs here
Like Phr0gggg mentions, using environment variables is one option.
Another option is to use the "NODE_ENV" variable.
In dev mode, process.env.NODE_ENV is equal to 'development' and in production, it's equal to 'productoin'
And you can use something like this:
const isProduction = process.env.NODE_ENV === "production"
const hostBaseUrl = () => {
if (isProduction) {
return 'http://localhost:9500';
}
return 'https://abc_loginapi.com';
}
export const API_HOST_LIST =
{
HostBaseURL: hostBaseUrl()
}
You can use process.env api to judge in webpack,
The code in webpack file like.
export const API_HOST_LIST =
{
HostBaseURL: process.env.NODE_ENV ==='dev'? 'http://localhost:9500/login':'https://abc_loginapi.com'
}
The code in package.json file like.
"scripts": {
"dev": "NODE_ENV=dev npm run start",
"start": "npm start"
}

React Native 0.60.3 babel-plugin-transform-remove-console not working

I am trying to remove console.log outputs from my react-native application's output, but when I run
ENVFILE=.env.production react-native run-android --variant=release
and
adb logcat
I still see my app's data being logged to the console.
I used the following documentation: https://facebook.github.io/react-native/docs/performance.html#using-consolelog-statements.
Here is my .babelrc file:
{
"presets": ["react-native"],
"env": {
"production": {
"plugins": ["transform-remove-console"]
}
}
}
What am I missing ?
Im on react-native 0.60.3
and using "babel-plugin-transform-remove-console": "^6.9.4",
I have "#babel/core": "^7.5.5" and "react-native": "^0.60.5"
The approach descibed in React Native Documentation was not working for me.After many try and error and exploring issues on GitHub I got it working :
In babel.config.js add this -
module.exports = api => {
const babelEnv = api.env();
const plugins = [];
//change to 'production' to check if this is working in 'development' mode
if (babelEnv !== 'development') {
plugins.push(['transform-remove-console', {exclude: ['error', 'warn']}]);
}
return {
presets: ['module:metro-react-native-babel-preset'],
plugins,
};
};
To see changes run using npm start -- --reset-cache
More Info at
https://github.com/babel/minify/issues/934
https://github.com/babel/minify/issues/950#issuecomment-539590159
Using babel.config.js instead of .babelrc, it seems that process.env.BABEL_ENV is used to determine whether to include configs listed under env.production. However, process.env.BABEL_ENV is set to undefined during build.
To get around this, I'm returning a different object depending on if process.env.BABEL_ENV OR process.env.NODE_ENV indicate production build.
YMMV.
module.exports = function(api) {
api.cache(true); // necessary
if (process.env.NODE_ENV === 'production' || process.env.BABEL_ENV === 'production') {
return {
"presets": ["module:metro-react-native-babel-preset"],
"plugins": ["react-native-paper/babel", "transform-remove-console"]
}
} else {
return {
"presets": ["module:metro-react-native-babel-preset"],
}
}
}
install babel-plugin-transform-remove-console
yarn add babel-plugin-transform-remove-console -D
then add follow code in babel.config.js like this
module.exports = function (api) {
const babelEnv = api.env();
api.cache(true);
const plugins = [
[];
if (babelEnv === 'production') {
plugins.push(['transform-remove-console', {exclude: ['error', 'warn']}]);
}
return {
presets: ['babel-preset-expo'],
plugins,
};
};
then run this command
yarn start --reset-cache
NOTE:
this will remove console.log in the production build. if you wanna a test in development you can pass development instead of production

How To Create Worker in React

I'm trying to create a worker in an app created from create-react-app using react 16.8.6 and yarn 1.16.0. If I use
const backgroundWorker = new Worker('../assets/js/myWorker.js');
I get the console error: Uncaught SyntaxError: Unexpected token <
But I know that is the correct path. This works fine in Angular. Is there a good tutorial on how to create a worker in React?
The directory "assets" is the public directory for #angular/cli projects, not create-react-app projects. In create-react-app the equivalent of #angular/cli "assets" is "public" which is described in the create-react-app documentation under Using the Public Folder. Move your "js" directory and the "myWorker.js" file to the public directory and update the creation of the worker to point to that path instead:
const backgroundWorker = new Worker('/js/myWorker.js');
You can also use process.env.PUBLIC_URL instead:
const backgroundWorker = new Worker(`${process.env.PUBLIC_URL}/js/myWorker.js`);
Hopefully that helps!
Follow these steps in order to add your worker files to your create-react-app project.
1. Install these three packages:
$ yarn add worker-plugin --dev
$ yarn add comlink
$ yarn add react-app-rewired --dev
2. Override webpack config:
In your project's root directory create a config-overrides.js file with the following content:
const WorkerPlugin = require("worker-plugin");
module.exports = function override(config, env) {
//do stuff with the webpack config...
config.plugins = [new WorkerPlugin({ globalObject: "this"}), ...config.plugins]
return config;
}
3. Replace your npm scripts inside package.json by:
"start": "react-app-rewired start",
"build": "react-app-rewired build",
4. Create two files in order to test your configuration:
worker.js
import * as Comlink from "comlink";
class WorkerWorld {
sayHello() {
console.log("Hello! I am doing a heavy task.")
let numbers = Array(500000).fill(5).map(num => num * 5);
return numbers;
}
}
Comlink.expose(WorkerWorld)
use-worker.js
import * as Comlink from "comlink";
const initWorker = async () => {
const workerFile = new Worker("./worker", { name: "my-worker", type: "module" });
const WorkerClass = Comlink.wrap(workerFile)
const instance = await new WorkerClass();
const result = await instance.sayHello();
console.log("Result of my worker's computation: ", result);
}
initWorker()
5. See the output:
$ yarn start

How to use $npm_config_ in package.json?

I'm using create-react-app for my React project (ejected), and I've configured a proxy in package.json. But I don't want to have my credentials committed in this file. So I've added to npm using npm config set my_user xxxx.
I can see them in my ~/.npmrc, too.
"proxy": {
"/api/v3/": {
"target": "https://ourstagingserver.nl/",
"changeOrigin": true,
"ssl": false,
"secure": false,
"headers": {
"username": "$npm_config_my_user",
"password": "$npm_config_my_pass"
}
},
This doesn't work. The username and password are not used in the proxy requests.
But if I add this to "scripts":
"hello": "echo $npm_config_my_user $npm_config_my_pass
and run npm run hello, both are echoed...
Any ideas? Is this supposed to work or am I doing it wrong?
Thx! Gijs
I didn't figure out the use of $npm_config_ variables for this purpose but I did solve the issue of using ENV variables for the proxy in create-react-app:
In scripts/start.js (line 62, below const proxySetting = require(paths.appPackageJson).proxy), add this:
proxySetting[Object.keys(proxySetting)[0]].headers.username = process.env.PROXY_USERNAME;
proxySetting[Object.keys(proxySetting)[0]].headers.password = process.env.PROXY_PASSWORD;
or you could loop over the objects in proxySetting and set the credentials for every object in there if you have multiple API's to proxy to:
Object.keys(proxySetting).forEach(function(proxy) {
proxySetting[proxy].headers.username = process.env.PROXY_USERNAME;
proxySetting[proxy].headers.password = process.env.PROXY_PASSWORD;
});
Note: scripts/start.js is a file that's generated by create-react-app

Resources