Recently i encountered an issue with building multi slash routing paths for my react application configured with webpack and nodejs on the backend.
Issue started when i created following path inside routing:
// header
{[1, 2, 3, 4, 5].map((id) => (
<NavLink to={`/product/${id}`} className={({ isActive }) => (isActive ? 'active' : undefined)} key={`product-${id}`}>
Product
{id}
</NavLink>
))}
// router
<Routes>
<Route path="/product/:id" element={<Product />} />
</Routes>
The path itself is working correctly when accessed via link but when accessed from nodejs (refresh or type url directly) it is failing because its trying to load js
and css
files with following paths:
Refused to execute script from 'http://localhost:8080/product/js/main.2265f70c.js'
Refused to apply style from 'http://localhost:8080/product/css/style.2265f70c.css'
So its trying to load css
and js
relative to /products
path.
My webpack config:
const htmlPlugin = new HtmlWebPackPlugin({
template: './src/index.html',
filename: 'index.html',
});
const miniCssExtractPlugin = new MiniCssExtractPlugin({
filename: 'css/style.[fullhash:8].css',
chunkFilename: 'css/[id].style.[fullhash:8].css',
});
module.exports = {
...
output: {
filename: 'js/main.[fullhash:8].js',
},
module: {
rules: [
...
{
test: /\.(json)$/,
loader: 'file-loader',
type: 'javascript/auto',
options: {
name: 'translations/[name].[ext]',
},
},
{
test: /\.(png|jpg|jpeg|gif|ico|svg|eot|ttf|woff|woff2)$/,
type: 'asset',
generator: {
filename: 'assets/[name].[hash][ext]',
},
parser: {
dataUrlCondition: {
maxSize: 20 * 1024, // 20kb
},
},
},
],
},
devServer: {
historyApiFallback: {
rewrites: [{ from: /^\/$/, to: '/index.html' }],
},
},
};
my nodejs dev server:
const express = require('express');
const path = require('path');
const config = require('./config');
const app = express();
app.use(express.static(path.join(__dirname, 'dist'), {
maxage: '30d',
}));
app.use('*', express.static(path.join(__dirname, 'dist/index.html')));
app.listen(config.port, () => {
console.log(`Listening on :${config.port}`);
});
My first idea was to replace relative paths with absolute ones in webpack configuration but that action causes this error:
[webpack-cli] Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration.output.filename: A relative path is expected. However, the provided value "/js/main.[fullhash:8].js" is an absolute path!
Please use output.path to specify absolute path and output.filename for the file name.
What is the proper way / good practice of dealing with it, so multi slash url is just virtual and not actually / literally considered?
- nodejs v16.15.0
- webpack v5.74.0
- react v18.2.0
CodePudding user response:
Ok so i was able to solve the problem by modifying webpack output
configuratoin:
output: {
publicPath: '/', // this is the fix
filename: 'js/main.[fullhash:8].js'
},
After adding publicPath: '/'
it started to work properly (files are loaded from root, while virtual locations are routed correctly)