CRA - how to proxy all requests but a specific one? - webpack-dev-server

create-react-app docs says you can configure your proxy objects manually. I'm following the http-proxy-middleware docs on matching
to exclude a specific route but haven't got it to work.
Basically I'm serving my app from the /app route instead of root. So I want the following to happen:
/app/api proxies to http://localhost:3001, my backend service
All requests that does NOT start with /app proxy to http://cloud.my-app.com
This is what I've tried so far with no luck:
"homepage": "https://cloud.my-app.com/app",
"proxy": {
"/app/api": { // Works
"target": "http://localhost:3001"
},
"!/app/*": { // Does not work
"target": "https://cloud.my-app.com",
"secure": false
}
},
What am I missing?

Add the below as your proxy:
"proxy": {
"/app/api":{
"target":"http://localhost:3001",
},
"/.*/":{
"target":"https://cloud.my-app.com",
"secure":"false",
"changeOrigin": true
}
}

Related

Cannot proxy requests with craco config

I am trying to proxy requests with craco config. however the proxy seems to be ignored. Why is it not working?
I have a create-react-app project that I started using:
npx create-react-app check-proxy-config --template typescript
and I've added craco to it:
npm i -D #craco/craco
In addition I defined a proxy in craco.config.cjs file:
module.exports = {
webpack: {
devServer: {
logLevel: "debug",
proxy: {
"/api": {
target: "https://<any Domain whatsoever>",
logLevel: "debug",
secure: true, // false
changeOrigin: true, //false
bypass: function(req, res, options) {
console.debug("bypass");
},
onProxyReq: function(proxyReq, req, res) {
console.debug(`Proxying request: ${req.originalUrl} => ${proxyReq.path}`);
}
}
}
},
The request I'm sending from the browser is:
http://localhost:3000/api/something
None of the console.debug statements is printed. Why? how can I make the proxy work?
The configuration worked after checking in the backend server i was able to ensure there was no issue with the config, hoewever the "on" methods (i.e. onProxyReq, etc) are not being called

StencilJS error with React output target - You may need an additional loader to handle the result of these loaders

I'm creating some basic elements in Stencil for a custom design system. I created some basic components, which work fine on their own as custom elements, but throw errors when used as React components.
I generated the React components via Stencil by includng the #stencil/react-output-target in stencil.config.ts.
reactOutputTarget({
componentCorePackage: '#sr-design-system/simple-stencil-demo',
proxiesFile: './react/src/components/index.ts',
includeImportCustomElements: true
}),
I then uploaded all of the components (custom elements & React) to a private npm package and installed them in a seperate project. The custom elements seem to work fine, but with the React elements I get the following error.
ERROR in ./node_modules/#sr-design-system/simple-stencil-demo/react/src/index.ts 6:12
Module parse failed: Unexpected token (6:12)
File was processed with these loaders:
* ./node_modules/source-map-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| import { createReactComponent } from './react-component-lib';
|
> import type { JSX } from '#sr-design-system/simple-stencil-demo/';
|
| import { defineCustomElement as defineSrText } from '#sr-design-system/simple-stencil-demo/dist/components/sr-text';
# ./src/App.jsx 7:0-73
# ./src/index.jsx 7:0-24 12:33-36
webpack 5.65.0 compiled with 1 error and 1 warning in 63 ms
I've been stuck on this issue for days now. Any idea what the solution could be?
===tsconfig.json===
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"allowUnreachableCode": false,
"declaration": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"lib": ["dom", "es2017"],
"module": "es2015",
"moduleResolution": "node",
"pretty": true,
"removeComments": false,
"strictPropertyInitialization": false,
"target": "es2017",
"baseUrl": ".",
"paths": {
"#srds/react": ["./react"]
},
"jsx": "react",
"jsxFactory": "h"
},
"include": ["src"]
}
===stencil.config.ts===
import { Config } from '#stencil/core';
import { reactOutputTarget } from '#stencil/react-output-target';
export const config: Config = {
namespace: 'simple-stencil-demo',
bundles: [{ components: ['sr-text'] }, { components: ['text-demo'] }],
outputTargets: [
reactOutputTarget({
componentCorePackage: '#sr-design-system/simple-stencil-demo',
proxiesFile: './react/src/components/index.ts',
includeImportCustomElements: true,
}),
{
type: 'dist',
esmLoaderPath: './loader',
},
{
type: 'dist-custom-elements',
},
{
type: 'docs-readme',
},
{
type: 'www',
serviceWorker: null, // disable service workers
},
],
buildEs5: 'prod',
};
I figured out what the issue. For some reason, the dist folder was not being generated for me every time I ran npm run build.
Sometimes it was generated, other times it wasn't. I believe it was due to some errors in my component code, which failed silently. So now I check for the dist folder every time I build the library.
In my final, working attempt I went with the monorepo approach as advised by the Stencil team in their documentation.
Here are all I took the steps for a basic Stencil library with a React output:
Create a monorepo
Create a Stencil Library
Generate components using npx stencil generate
Update name in package.json to MY_LIBRARY
npm i #stencil/react-output-target
Add the React Wrapper function to stencil.config.ts
react({
componentCorePackage: 'MY_LIBRARY',
proxiesFile: '../MY_REACT_LIBRARY/src/components/stencil-generated/index.ts',
includeDefineCustomElements: true,
}),
Move back to root level of monorepo
Create a React library
git clone https://github.com/ionic-team/stencil-ds-react-template react-components
Update name in package.json to MY_REACT_LIBRARY
Change private to false in package.json
In the Stencil Library
Run npm run build
Check if dist folder contains all subfolders (cjs, collection, components, esm, types, web-components, index.cjs.js, index.js)
Run npm link to generate a global symlink
In the React Library
Run npm link MY_LIBRARY
Run npm i
Run npm run build (Not sure if this step is required as it is not documented, but I did it anyway)
Run npm link
Move back to root level of monorepo
Create a React demo
npx create-react-app MY_REACT_DEMO --template typescript
npm link MY_REACT_LIBRARY
Import a component from the library and use it in App.tsx
npm run start
When I confirmed everything worked fine, I added a basic lerna.jsonconfig for npm package management. Using this config, Lerna will automatically handle symver for our packages.
{
"version": "independent",
"npmClient": "npm",
"command": {
"publish": {
"allowBranch": ["master", "react-generation"],
"ignoreChanges": ["*.md", "build.js", "config.json"],
"message": "(auto) Lerna publish",
"registry": "URL_TO_MY_PACKAGE_REGISTRY"
},
"bootstrap": {
"ignore": "component-*",
"npmClientArgs": ["--no-package-lock"]
}
},
"packages": ["MY_LIBRARY", "MY_REACT_LIBRARY"]
}
After configuring Lerna, I published using the command npx lerna publish, following their publishing wizard.
When it's published the package can be installed in any React project using npm i MY_REACT_LIBRARY and it should work.

How to add multiple proxies in React's package.json?

I have already one proxy added in my React project. Now I need to add more proxies in order to run project efficiently. As the thing is, when we add any URL in proxy doesn't give CORS error. So this is what my intention is.
{
"name": "react-app",
"proxy": "URL1....", /* <-- URL added and I want to add more URLs in proxy */
"version": "0.1.0",
"private": true,
"dependencies": {
"#material-ui/core": "^4.11.3",....
}
What could be the best solution to add multiple proxies?
As far as i know, you can't..
I use the package 'http-proxy-middleware' for this purpose. Works very well.
Link: https://github.com/chimurai/http-proxy-middleware
You can even proxy to different sites completely. Example:
app.use(
'/api',
createProxyMiddleware({
target: 'http://127.0.0.1:3001',
changeOrigin: true
})
);

how to handle client side react routing in loopback.js

I am using react with loopback. I wanted to integrate react code in loopback.
if i do these 3 steps
1)middleware.json - put this
"files": {
"loopback#static": {
"params":"$!../client"
}
},`
2)root.js
router.get('/');
3)front end code
"build": "react-scripts build && cp -r build/* ../client/",
That didopen my react site on localhost:3000 .Now issue is when i do this
i cant access my loopback on :3000/explorer
So my first question is in this scenario, how to access explorer.
But then i rolled it back , because i wanted to use loopback explorer again.
So, i deleted all these added code and explorer came back
but when i added it again
Now, i dont see my react code
I can still see explorer at http://localhost:3000/explorer/
if i go to http://localhost:3000/apphome
i see 404 error
Right now, my middleware.json file for loopback is
{
"initial:before": {
"loopback#favicon": {}
},
"initial": {
"compression": {},
"cors": {
"params": {
"origin": true,
"credentials": true,
"maxAge": 86400
}
},
"helmet#xssFilter": {},
"helmet#frameguard": {
"params": [
"deny"
]
},
"helmet#hsts": {
"params": {
"maxAge": 0,
"includeSubdomains": true
}
},
"helmet#hidePoweredBy": {},
"helmet#ieNoOpen": {},
"helmet#noSniff": {},
"helmet#noCache": {
"enabled": false
}
},
"session": {},
"auth": {},
"parse": {
"body-parser#json": {},
"body-parser#urlencoded": {
"params": {
"extended": true
}
}
},
"routes": {
"loopback#rest": {
"paths": [
"${restApiRoot}"
]
}
},
"files": {
"loopback#static": {
"params":"$!../client"
}
},
"final": {
"loopback#urlNotFound": {},
"./LoopbackUrlNotFoundCatch.js": {}
},
"final:after": {
"strong-error-handler": {}
}
}
root.js file
'use strict';
//router.get('/', server.loopback.status());
module.exports = function(server) {
// Install a `/` route that returns server status
var router = server.loopback.Router();
router.get('/');
server.use(router);
};
-edit
I made some changes. Now, i have react components showing, I can also see data when i use api routes. But, explorer is still missing.
middleware.json
"files": {
"loopback#static": [
{
"name": "publicPath",
"paths": ["/"],
"params": "$!../client"
},
{
"name": "reactRouter",
"paths": ["*"],
"params": "$!../client/index.html",
"optional":true
}
]
},
I have also changed named of root.js to root_something.js . In documentation, its written, no need of root.js
First of all you Should be create react app in an other director like
Root ->
|-- client // emply
|-- clint_src // react app
and getting build react app and copy build files to client
now you should be remove server.loopback.status() in "server/boot/root.js" file
Example:
router.get('/', server.loopback.status());
To :
module.exports = function(server) {
// Install a `/` route that returns server status
var router = server.loopback.Router();
router.get('/');
server.use(router);
};
after that you need say to loopback middleware which file should be load in your path
go to middlware /server/middleware.json and replace blow code to "files": {}
"files": {
"loopback#static": [
{
"paths": ["/"],
"params": "$!../client"
},
{
"paths": ["*"],
"params": "$!../client"
}
]
},
on "paths": ["*"], all route will be open react file exeption the "/api" and "explorer" so you should be handle page notfound inside react app
Hope This was help full
Good Luck
I suspect React's default service worker intercepts and tries to cache /explorer. It skips urls prefixed with __ so this might fix the need to clear browser:
In component-config.json:
{ "loopback-component-explorer": {
"mountPath": "/__explorer" }}
Then access explorer at /__explorer.
As the instructions for adding a GUI to a loopback application state, you need to remove the root.js '/' route completely, by either renaming the root.js file to something without a .js extension, or deleting the file altogether.
$ rm root.js
### or, you can do this
$ mv root.js root.js.old
In the loopback 3 server configuration, the client folder has to be setup as a middleware route in middleware.json, like so:
"files": {
"loopback#static": {
"params": "$!../client"
}
},
Now, your client application is served from the /client folder, and by default the static files are served with Express -- so, it will look for index.html when you hit localhost:3000/

Angular Using Random Url For Requests

I'm trying to create a proxy for my angular application and my post request keeps getting sent to
http://www.gamersunite.com/users
even though i'm trying to post to
http://localhost:3000/api/users
At one point I had my proxy set as
{
"/api": {
"target": "http://url.com",
"secure": false,
"pathRewrite": {"^/api" : ""}
}
}
but now it's currently
{
"/api": {
"target": "http://localhost:3000",
"secure": false,
"logLevel": "debug"
}
}
Why is it still redirecting to this random url?
Cleared the cache/cookies and now everything is working as expected

Resources