White page deploying react app with webpack in IIS Server - reactjs

I'm trying to deploy a react web application based in microfrontends using ModuleFederationPlugin and webpack, but when I try to deploy one of microfrontends in isolation I get a white page without errors.
My webpack configuration to production:
const { merge } = require('webpack-merge')
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin')
const commonConfig = require('./webpack.common')
const packageJson = require('../package.json')
const prodConfig = {
mode: 'production',
output: {
filename: '[name].[contenthash].js',
publicPath: '/Microfrontends/marketing/'
},
plugins: [
new ModuleFederationPlugin({
name: 'marketing',
filename: 'remoteEntry.js',
exposes: {
'./MarketingModule': './src/bootstrap'
},
shared: packageJson.dependencies
})
]
}
module.exports = merge(commonConfig, prodConfig)
My webpack common with babel:
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-react', '#babel/preset-env'],
plugins: ['#babel/plugin-transform-runtime']
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html'
})
]
}
My App.js component with React-Router:
export default function App({ history }) {
return (
<Fragment>
<StylesProvider generateClassName={generateClassName}>
<Router history={history}>
<Switch>
<Route exact path="/Microfrontends/marketing/pricing" component={Pricing} />
<Route path="/Microfrontends/marketing/" component={Landing} />
</Switch>
</Router>
</StylesProvider>
</Fragment>
)
}
When I deploy in server all status requests are 200 and the chrome console hasn't errors

Try adding or changing the homepage attribute in the package.json file.
Set it to be relative to the path by using homepage: '.';.
If you still get a white page after doing this it may be that the basename for your Router is not set:
<Router basename='/name' history={history}>
<Switch>
<Route exact path="/Microfrontends/marketing/pricing" component={Pricing} />
<Route path="/Microfrontends/marketing/" component={Landing} />
</Switch>
</Router>

Related

Webpack React error: You should not use <Switch> outside a <Router>

so i'm trying to setup server side rendering with my React app and I have solved every problem so far but I have run into this one which I cannot solve after a few days of trying.
I'm using the latest of everything included and I run into this error: Error: Invariant failed: You should not use <Switch> outside a <Router>
Below is the react app index
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
const SSR = (
<BrowserRouter>
<App/>
</BrowserRouter>
);
if(typeof document === "undefined") {
module.exports = SSR;
} else {
ReactDOM.hydrate(SSR, document.getElementById("app"));
}
And the component
import React from 'react';
import { Route, Switch } from 'react-router-dom'
import Home from './components/index'
const NavRoute = ({exact, path, component: Component}) => (
<Route exact={exact} path={path} render={(props) => (
<React.Fragment>
<Navbar/>
<Component {...props}/>
</React.Fragment>
)}/>
)
export default class App extends React.Component {
render() {
return (
<Switch>
<NavRoute exact={true} path="/" component={Home}/>
</Switch>
);
}
}
And my webpack config
const path = require('path');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
module.exports = [
{
entry: {
client: './server/index.js',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: "[name].js",
publicPath: '/',
},
target: 'node',
externals: [nodeExternals()],
module: {
rules: [
{ test: /\.jsx?/, loader: "babel-loader"}
]
},
},
{
entry: {
bundle: './src/App.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: "[name].js",
publicPath: '/',
libraryTarget: "umd",
globalObject: "this",
},
module: {
rules: [
{ test: /\.jsx?/, loader: "babel-loader"}
]
},
plugins: [
new webpack.DefinePlugin({
'process.env.BROWSER': JSON.stringify(true),
}),
]
}
]
any help is appreciated let me know if I missed any info out, thank you.

Not able to access URL manually in ReactJS build

I have created build using Webpack 4.2.0. But I'm not able to access URLs directly without landing to index page.
My WebPack Config:
var webpack = require('webpack');
const HtmlPlugin = require('html-webpack-plugin')
// require('react-select/dist/react-select.css')
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'build');
var APP_DIR = path.resolve(__dirname, 'src/');
var CSS_DIR = path.resolve(__dirname,'public/css');
// const HtmlPlugin = require('html-webpack-plugin');
var config = {
entry: APP_DIR + '/index.js',
output: {
path: BUILD_DIR,
filename: 'bundle.js'
},
plugins: [
// Configure HtmlPlugin to use our own index.html file
// as a template.
// Check out https://github.com/jantimon/html-webpack-plugin
// for the full list of options.
new HtmlPlugin({
template: 'public/index.html'
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
}),
// new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.LoaderOptionsPlugin({
minimize: true
})
],
module : {
rules: [
{
test: /\.js$/,
enforce: "pre",
include : APP_DIR,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
include : CSS_DIR
}
]
}
};
module.exports = config;
Index.js
render((
<BrowserRouter>
<App />
</BrowserRouter>
), document.getElementById('root'));
APP.JS
const Main = () => (
<main>
<Switch>
<Route exact path='/' component={Home}/>
<Route exact path='/contact' component={Contact}/>
<Route path='/listing' component={Listing}/>
<Route path='/product/:id' component={Product}/>
</Switch>
</main>
)
In Build folder, two files created.
- index.html
- bundle.js
And I have used http-server to open React Build
./node_modules/.bin/http-server build -p 3007
But In browser, it will throw 404 if I access URL localhost:3007/contact directly.
What is right way to deploy this for production which can be accessed via url say www.reactapp.com/contact
You need to configure your server to serve your index.html for all GET requests. ReactRouter just changes the navigation history, you don't actually leave the page when the route changes. Currently, your server is just serving the index.html page for the / route. Configure it to serve the page on all routes and you will be able to visit the routes by access their urls directly.

How to configure webpack dev server with react router dom v4?

This is the code of my webpack configuration:
const compiler = webpack({
entry: ['whatwg-fetch', path.resolve(__dirname, 'js', 'app.js')],
module: {
loaders: [
{
exclude: /node_modules/,
test: /\.js$/,
loader: 'babel',
},
],
},
output: {filename: 'app.js', path: '/'},
});
const app = new WebpackDevServer(compiler, {
contentBase: '/public/',
proxy: {'/graphql': `http://localhost:${GRAPHQL_PORT}`},
publicPath: '/js/',
stats: {colors: true},
});
app.use('/', express.static(path.resolve(__dirname, 'public')));
Works fine, the app runs on localhost:3000/index.html but when I try to implement React Router dom v4. It doesn't work. This is the code:
const About = () => <div> <h1>About</h1> </div>
ReactDOM.render(
<BrowserRouter>
<div>
<Route exact path='/' component={App}/>
<Route path='/about' component={About}/>
</div>
</BrowserRouter>,
mountNode
);
This is the result on localhost:3000/
And on localhost:3000/about. I get an error: Cannot GET /about . Not what I'm expecting, why would this not render? About
I do not think it has anything to do with webpack-config. Here is a basic github repository using react-router-4.0. I have created this example without any specific changes related to react-router-4.0 in webpack config.
Add 'devServer' in your webpack config if not already:
devServer: {
historyApiFallback: true,
}
Two small suggestions in your code, try using 'exact' with the path for 'about' i.e.
<Route exact path='/about' component={About}/>
and, add parenthesis for const about i.e.,
const About = () => (<div> <h1>About</h1> </div>);
Hope, this solves your query. Let me know if you require any other information on this.
In my case I had to remove proxy config, because the webpack server wanted a response from http://localhost:3001.
// proxy: {
// '/': 'http://localhost:3001',
// },

React-Routing basic example path not working

Triyng for run basic example from here
I've got Yarn+Webpack2+Babel es2015
This is my entry point:
import React from 'react'
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom'
const BasicExample = () => (
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
<hr/>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
</div>
</Router>
);
const Home = () => (
<div>
<h2>Home</h2>
</div>
);
const About = () => (
<div>
<h2>About</h2>
</div>
);
ReactDOM.render(
<BasicExample/>,
document.getElementById('root')
);
Project at http://localhost:8080 starting good and Links working fine, rendering content from Home and About components.
But when I'm trying to enter url http://localhost:8080/about - console showing me
GET http://localhost:8080/about 404 (Not Found)
I found many almost same questions on Stack, but not found solution working for me.
What exactly in react-router intercept incoming url?
It possible that this not working because of mine Yarn\Webpack settings?
____________UPDATE_1
Webpack config
const path = require('path');
let webpack = require("webpack");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
template: path.join(__dirname, 'index.html'),
filename: 'index.html',
inject: 'body'
});
module.exports = {
/*devServer: {
host: "DESKTOP-A5FTMD8", // Can change port
port: 8080
},*/
entry: path.join(__dirname, 'index.jsx'),
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
module: {
loaders: [
{test: /\.(less|css)$/, loader: 'style-loader!css-loader!less-loader'},
{test: /\.(xml)$/, loader: 'xml-loader'},
{test: /\.(svg|png|jpg|jpeg)$/, loader: 'file-loader'},
{
test: /\.(js|jsx|es6)$/,
exclude: /node_modules/,
loader: 'react-hot-loader!babel-loader?presets[]=react,presets[]=es2015'
},
]
},
resolve: {
extensions: ['.js', '.jsx', '.es6']
},
plugins: [
HtmlWebpackPluginConfig
]
};
The problem solved by this solution in webpack config:
devServer: {
historyApiFallback: true <-- this needs to be set to true
}
This answer

react-router-dom 4 routing questions

I'm trying to use react-router-dom 4, But am unable to navigate directly to a route.
Here's a sample of my code:
let Test = (props) => (<div>This is a test component</div>);
let About = (props) => (<div>About us</div>);
class App extends Component {
render () {
return (
<Router>
<div>
<nav>
<NavLink to="/about" activeClassName="selected">About</NavLink>
<NavLink to="/" activeClassName="selected">Test</NavLink>
</nav>
<Route exact path="/" component={Test} />
<Route exact path="/about" component={About} />
</div>
</Router>
)
}
}
When i try to just go to localhost:3000/about, i get Not Found in the browser. But when i go to just localhost:3000, then click on the About link, i get redirected just fine.
in my Console, i get
Uncaught Error: uBlock Origin: aborting content scripts for http://localhost:3000/about
at contentscript.js:90
I'm assuming you're using Webpack. If so, adding a few things to your webpack config should solve the issue. Specifically, output.publicPath = '/' and devServer.historyApiFallback = true. Here's an example webpack config below which uses both of ^ and fixes the refresh issue for me. If you're curious "why", this will help.
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './app/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js',
publicPath: '/'
},
module: {
rules: [
{ test: /\.(js)$/, use: 'babel-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ]}
]
},
devServer: {
historyApiFallback: true,
},
plugins: [
new HtmlWebpackPlugin({
template: 'app/index.html'
})
]
};
when you go to localhost:3000/about,it's run server-side route,and the you don't set server-side route,so you got 404;when you go to just localhost:3000, then click on the About link,now, you run the client route that you have setted. In other word,it's run react-router-dom,so you can got the page

Resources