Reputation: 2415
I have an app that uses react-router-dom
and I have a a basic setup like so:
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import { Box, Flex } from '@chakra-ui/react';
import CodeEntry from './pages/CodeEntry';
import Register from './pages/Register';
// import Login from './pages/Login';
import { useUI } from '../state/context/UIContext';
import { GlobalStyle } from '../styles/GlobalStyles';
import Header from './Header';
import Footer from './Footer';
import ErrorMessage from '../components/ErrorMessage';
import routes from '../config/routes';
const App = () => {
const {
state: { errorMessage },
} = useUI();
return (
<Router>
<GlobalStyle />
<Flex flexDir="column" justifyContent="space-between" minH="100vh">
<Box>
<Header />
{errorMessage.length > 0 && <ErrorMessage message={errorMessage} />}
<Switch>
<Route exact path={routes.APP.REGISTER}>
<Register />
</Route>
<Route exact path={routes.APP.DASHBOARD}>
<>Dashboard</>
</Route>
<Route exact path={routes.APP.HOME}>
<CodeEntry />
</Route>
<Route exact path={routes.APP.LOGIN}>
<>Login</>
</Route>
</Switch>
</Box>
<Box>
<Footer />
</Box>
</Flex>
</Router>
);
};
export default App;
When I run my app locally with npm run dev
it uses the following command to spin up a local server:
webpack serve --config webpack.dev.js
the webpack.dev.js file looks like so:
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const path = require('path');
const Dotenv = require('dotenv-webpack');
const plugins = [];
//if (process.env.CI !== 'true') plugins.push(new Dotenv({ systemvars: true, path: path.resolve(__dirname, '.env') }));
module.exports = merge(common, {
mode: 'development',
devServer: {
host: 'localhost',
port: 3000,
historyApiFallback: true,
open: true,
},
infrastructureLogging: {
level: 'error',
},
stats: 'none',
output: {
publicPath: '/',
},
plugins,
});
and the webpack.common.js like so:
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const path = require('path');
require('babel-polyfill');
module.exports = {
entry: {
main: ['babel-polyfill', './src/index.tsx'],
},
devtool: 'source-map',
output: {
filename: '[name].[fullhash].js',
path: path.resolve('./dist'),
},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
loader: 'ts-loader',
},
{
test: /\.js$/,
exclude: [path.resolve(__dirname, 'node_modules')],
use: [{ loader: 'babel-loader' }],
},
{
test: /\.(png|jpg|gif|svg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
outputPath: 'assets/img/',
},
},
],
},
{
test: /\.(woff(2)?|ttf|eot|otf)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'assets/fonts/',
},
},
],
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new HtmlWebPackPlugin({
template: 'index.html',
}),
new webpack.ProvidePlugin({
process: 'process/browser',
}),
new CleanWebpackPlugin({
cleanAfterEveryBuildPatterns: ['dist'],
}),
new webpack.DefinePlugin({
__REACT_DEVTOOLS_GLOBAL_HOOK__: '({ isDisabled: true })',
}),
],
};
Everything in dev works as it should but when I run a build for production non of my routes apart from the root route ('/') work. Here is how I run a production build:
npm run build && webpack --config webpack.prod.js
and here is how I serve that build locally using the npm package serve
:
serve dist --no-clipboard --listen ${PORT:-3000}"
My webpack.prod.js file is quite simple and adopts a lot of the webpack config from the webpack.common.js
config file. Here is my prod config:
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
//
module.exports = merge(common, {
mode: 'production',
});
I have tried adding a <Link>
component like so:
<Link to='/register'>
The link works fine when I click on it in prod as well as dev, it is just when I navigate directly to the page where I get a 404
Upvotes: 0
Views: 365
Reputation: 2415
Solution was simple, in the end it was an issue with the serve
package. All I had to do was a a -s
flag to the following command:
serve -s dist --no-clipboard --listen ${PORT:-3000}"
Upvotes: 1