React router with basename and webpack initial url - reactjs

Hello i am stuck with this one and couldnt figure it out. So i have React router v6 with basename - "/ui/" , and i want that when i open localhost:8080 that it automatically turns into "localhost:8080/ui/" because the real view is actually rendered in /ui/ route.
Router setup:
<BrowserRouter basename="/ui/">
...routes here
</BrowserRouter>
Webpack dev:
module.exports = {
mode: 'development',
devtool: 'cheap-module-source-map',
devServer: {
hot: true,
historyApiFallback: true,
open: true,
port: 6969
}
}
And common webpack:
module.exports = {
entry: path.resolve(__dirname, '..', './src/index.tsx'),
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
module: {
rules: [
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
},
],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
"style-loader",
// Translates CSS into CommonJS
"css-loader",
// Compiles Sass to CSS
"sass-loader"
]
},
{
test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
type: 'asset/resource',
},
{
test: /\.(woff(2)?|eot|ttf|otf|svg|)$/,
type: 'asset/inline',
},
],
},
output: {
path: path.resolve(__dirname, '..', './build'),
filename: 'bundle.js',
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '..', './src/public/ui/index.html'),
}),
],
stats: 'errors-only',
}
I have tried to add to output publicPath: '/ui/' but it didnt work.
Or even something like this:
static: [
{
publicPath: '/',
directory: path.join(__dirname, "../public/ui/"),
}]
How i can achieve this withouth "redirecting" :\

Try this solution
<Route exact path="/">
<Redirect to="/home" />
</Route>

Check your main.js or similar in your src or sources.
Mine had:
const Root = () => (
<Provider store={store}>
<Router history={history}>
<Route path="/" component={App}>
{appRoute}
</Route>
</Router>
</Provider>
);
and so just had to move it to Route path="/ui/" component={App}

Related

Blocked due to MIME type mismatch (X-Content-Type-Options: nosniff)

I'm new to WebPack, and it's hard to debug it and I can't seem to find any right answer on google.
I'm trying to use react router, but it seems like it needs a lot of configuration to make it work exactly like create-react-app's.
React router sub-routes seems to work only when you redirect it with the Link component, example:
// App.jsx
<Route path="/profile/me/" element={<PrivateRoute component={Profile} />}>
<Route path="create" element={<PrivateRoute component={CreateProfile} />} />
</Route>;
// Sub-Component - Profile.jsx
<Link to="create">
<Button color="primary" variant="contained">
Set It Up
</Button>
</Link>;
But when I try to enter the URL in the browser search bar, I get an error:
GET
http://localhost:3000/profile/dist/bundle.js [HTTP/1.1 404 Not Found 4ms]
The resource from “http://localhost:3000/profile/dist/bundle.js” was blocked due to MIME type mismatch (X-Content-Type-Options: nosniff).
create
Here's my Webpack config:
const path = require("path");
const webpack = require("webpack");
const Dotenv = require('dotenv-webpack');
module.exports = {
entry: "./src/index.js",
mode: "development",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules)/,
loader: "babel-loader",
options: {
presets: ["#babel/env"],
},
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.js$/,
include: /node_modules\/react-dom/,
use: ["react-hot-loader/webpack"],
},
],
},
resolve: {
extensions: ["*", ".js", ".jsx"],
},
output: {
path: path.resolve(__dirname, "dist/"),
publicPath: "/dist/",
publicPath: "/profile/dist/",
filename: "bundle.js",
},
devServer: {
// contentBase
static: {
directory: path.join(__dirname, "public/"),
},
port: 3000,
// publicPath
devMiddleware: {
publicPath: "https://localhost:3000/dist/",
},
// hotOnly
hot: "only",
// To use router
historyApiFallback: true,
// Proxy
/*proxy: {
"/api/v1": "http://localhost:8000",
},*/
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new Dotenv({
systemvars: true,
}),
],
};

React webpack showing blank page on refresh

I am serving my static files from express and i can see that it loads index.html
But the problem is when on a rout for example localhost:8080/users and i refresh the page, the .css and main.js does not seam to be loaded so it returns blank page.. Any idea on what night be the problem?
My app.js
function App (){
return (
<div className="wrapper">
<Routes>
{routes.map(({ path, name, Component }, key) => (
<Route exact path={path} key={key} element={Component} />
))}
</Routes>
</div>
);
}
export default App
My index.js:
ReactDOM.render(
<Provider store={store}>
<React.StrictMode>
<BrowserRouter>
<Routes>
<Route path="*" element={<App />} />
</Routes>
</BrowserRouter>
</React.StrictMode>
</Provider>,
document.getElementById('root')
);
This is my webpack:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const Dotenv = require('dotenv-webpack');
const webpack = require('webpack');
require('dotenv').config({path:__dirname+'/../.env'})
module.exports = {
entry: {
app: path.join(__dirname, "/src/Index.js"),
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "main.js",
},
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
exclude: /node_modules/,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
},
{
test: /\.css$/,
use: 'style-loader!css-loader'
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: "babel-loader",
},
{
test: /\.html$/,
exclude: /node_modules/,
use: "html-loader",
},
],
},
resolve: {
extensions: [".js", ".jsx"],
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
APP_API_URL : JSON.stringify(process.env.APP_API_URL)
},
}),
new Dotenv(),
new HtmlWebpackPlugin({
filename: "index.html",
template: "./src/index.html",
}),
new MiniCssExtractPlugin({
filename: "app.css",
chunkFilename: "[id].css",
}),
],
devServer: {
historyApiFallback: true,
contentBase: path.join(__dirname, "dist"),
compress: true,
port: process.env.PORT_CLIENT,
open: true,
stats: "errors-only",
}
};
Check out this finished example using React Router and compare it with your App.
https://stackblitz.com/edit/github-agqlf5?file=src%2Fmain.jsx

Route Component dose not render even though url changes. with custom webpack

code repository url
below is my file structure
and webpack.config.js looks like something like below
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const entryPoint = path.join(__dirname, "src", "index.js");
module.exports = {
entry: entryPoint,
output: {
path: path.join(__dirname, "public"),
filename: "bundle.js",
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
],
},
plugins: [
new HtmlWebPackPlugin({
template: path.join(__dirname, "public", "index.html"),
filename: "./index.html",
}),
],
devServer: {
contentBase: path.join(__dirname, "public"),
historyApiFallback: true,
// publicPath: "/dist/",
},
devtool: "source-map",
stats: {
errorDetails: true,
},
};
i don't know why is it still not working eventhough i have give historyApiFallback
below is my app.js
when i click on the /home route the content is not changing.
could any one please explain me what more i have to add
and my index.js
You need to add exact to your / route otherwise it will match anything starting with / and since it is in a Switch it will be the only one to be matched.
<Switch>
<Route exact path="/" component={() => <div>i am in home</div>} />
<Route exact path="/home" component={() => <div> i am user</div>} />
</Switch>
If the url is not parameterized, i would add exact to /home as well
See: https://reactrouter.com/web/api/Route/exact-bool

Webpack uses wrong path to import bundle

so I'm having a problem with webpack codesplitting. It creates bundles correctly but then everything is getting messed up when it sends xhr request for the bundle. Only the index route works correctly 'cause it's just a / but it actually uses client side route as path to bundle. So using the example below it goes with the path localhost:3000/dir/something/0.bundle.js instead of localhost:3000/0.bundle.js. I'm new to webpack, is there a way to make it use the / route every time?
pseudo markup
<Link to="/dir/something/else"/>
<!-- <App/> -->
<BrowserRouter>
<Switch>
<Route path="/dir/:param1/:param2">
<Bar/>
</Route>
<Route path="/">
<Foo/>
</Route>
</Switch>
</BrowserRouter>
I'm using #loadable/component so each component is imported with a loadable(()=>import('path/to/component'))
webpack.config.js
{
mode,
entry: './src/index.tsx',
target: 'web',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'app.bundle.js'
},
module: {
rules: [
{
test: /\.ts(x)?$/,
use: 'ts-loader',
exclude: /node_modules/,
include: path.join(__dirname, '/src'),
},
{
test: /\.svg$/,
use: {
loader: 'url-loader',
options: {
limit: 5000
}
}
}
],
},
devServer: {
hot: true
},
plugins: [new HTMLWebpackPlugin({
template: 'src/index.html'
})],
resolve: {
modules: ['node_modules'],
extensions: ['.ts', '.tsx', '.js', '.json']
}
}

Rendering UI in React Router 4

I am still fairly new to ReactJS especially the routing portion of it. I have a couple of questions which I tried many solutions i found on stackoverflow but nothing seems to be helping me:
When i start my react project locally, i get localhost:3000. What if I want it to be shown as localhost:3000/extension/?
When i navigate about my project i can render the different pages. However, if i enter the URL directly into the browser, a blank page is rendered. There is no error. I read somewhere saying that my components are not connected to my routes. I am not sure what I need to do to correct it.
How can i ensure history is properly being utilized?
routes.js:
const RouteList = () => (
<Switch>
<Route path="/extension/" exact component={withRouter(HomePage)} />
<Route path="/extension/something" exact component={withRouter(SomethingPage)} />
<Route component={Error} />
</Switch>
);
App.js:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render () {
return (
<Router history={browserHistory}>
<div>
<Header />
<RouteList />
<Footer />
</div>
</Router>
);
}
}
export default App;
--EDIT--
Added my webpack.config.js
const commonConfig = {
resolve: {
modules: [path.resolve('./src'), 'node_modules'],
extensions: ['.js', '.csv', '.json', '.scss', '.css', '.html']
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
enforce: 'pre',
use: [{ loader: 'eslint-loader', options: { configFile: '.eslintrc' } }]
},
{
use: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
},
{
test: /\.html$/,
use: [{ loader: 'htmlhint-loader', options: { configFile: '.htmlhintrc' } }],
exclude: /node_modules/,
enforce: 'pre'
},
{
test: /\.(png|jpg|jpeg|svg|gif|svg|woff|woff2|ttf|eot)(\? v=\d+\.\d+\.\d+)?$/,
use: 'file-loader'
},
{
use: [{
loader: 'html-loader'
}],
test: /\.html$/
}
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(nodeEnv)
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
if (module.resource && (/^.*\.
(css|less|scss)$/).test(module.resource)) {
return false;
}
return module.context && module.context.indexOf('node_modules') !== -1;
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
new CopyWebpackPlugin([{
from: __dirname + '/src/images',
to: ''
}]),
new HtmlWebpackPlugin({
template: 'src/index.html',
chunksSortMode: 'dependency'
}),
new webpack.optimize.ModuleConcatenationPlugin()
]
};
const devConfig = {
entry: {
main: ['whatwg-fetch', 'core-js/es6', 'react-hot-loader/patch', 'index.js',
'webpack-hot-middleware/client?reload=true']
},
target: 'web',
devtool: 'inline-source-map',
output: {
path: path.join(__dirname, '/dev_build'),
filename: '[name].bundle.js',
publicPath: '/'
},
module: {
rules: [
{
test: /\.scss/,
include: path.resolve(__dirname, 'src/styles'),
use: ['style-loader', 'css-loader', {loader: 'sass-loader', options:
{sourceMap: true}}]
},
{
test: /\.css$/,
exclude: [/node_modules/],
use: ['style-loader', 'css-loader?modules']
},
{
test: /\.css$/,
include: [/node_modules/],
use: ['style-loader', 'css-loader']
}
]
},
devServer: {
contentBase: 'src',
compress: true,
hot: true,
port: 3000,
host: '0.0.0.0',
disableHostCheck: true,
historyApiFallback: {
disableDotRule: true,
index: 'build/index.html'
},
stats: 'minimal',
overlay: true,
proxy: {
'/api/**': {
target: {
port: 8080
},
secure: false
},
'/actuator/**': {
target: {
port: 8080
},
secure: false
},
}
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.NoEmitOnErrorsPlugin()
]
};
Please help cause I am not sure what I am doing wrong and i am splitting my brains over this. Thanks.
You can add a Redirect from / to /extension if you want that to be the landing page.
const RouteList = () => (
<Switch>
<Redirect from='/' to='/extension/'/>
<Route path="/extension/" exact component={HomePage} />
<Route path="/extension/something" exact component={SomethingPage} />
<Route component={Error} />
</Switch>
);
Your app currently only works when visited on / because your server will only serve index.html for the index route. You can use historyApiFallback if you want the index.html file to be served instead of any 404 responses.
webpack.config.js
module.exports = {
//...
devServer: {
historyApiFallback: true
}
};

Resources