静态资源与react-router-dom路由冲突问题排查
React组件库静态资源被react-router-dom识别为路由导致图片加载失败
用tsdx构建React组件库,依赖react、react-router-dom、scss和antd。项目构建完成后,图片文件已生成且CSS内引用路径正确,但浏览器中图片无法加载,控制台报错:No routes matched location "/9db4e56265553721.svg",推测是react-router-dom将静态资源请求当成了路由路径处理。
项目配置文件
tsdx.config.js
const postcss = require('rollup-plugin-postcss'); const autoprefixer = require('autoprefixer'); const cssnano = require('cssnano'); const svgr = require('@svgr/rollup'); const url = require('@rollup/plugin-url'); const scss = require('sass'); const path = require('path') module.exports = { rollup(config, options) { config.plugins = [ svgr({ icon: true, compact: false, multipass: true }), postcss({ extract: false, // 设置为true可将样式提取到单独文件 modules: true, // 启用CSS modules exec: true, // 启用css-in-js(React内联样式) plugins: [ autoprefixer(),// 自动添加浏览器前缀 cssnano({ preset: 'default' }) ], use: [ ['sass', { includePaths: ['./src/Styles'], implementation: scss, // 指定使用Dart Sass }], ], }), url({ include: ['**/*.svg', '**/*.png', '**/*.jpg', '**/*.gif'], limit: 0, sourceDir: path.resolve(__dirname, 'src'), publicPath: '/', }), ...config.plugins, ]; return config; }, };
package.json
{ "version": "1.0.3", "license": "MIT", "main": "dist/index.js", "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "engines": { "node": ">=10" }, "scripts": { "start": "tsdx watch", "build": "tsdx build", "test": "tsdx test --passWithNoTests", "lint": "tsdx lint", "prepare": "tsdx build", "size": "size-limit", "analyze": "size-limit --why" }, "dependencies": { "@azure/msal-browser": "^3.5.0", "@azure/msal-react": "^2.0.8", "@iconify/react": "3.2.2", "axios": "^1.6.2", "formik": "^2.4.5", "lodash-es": "^4.17.21", "react-idle-timer": "^5.7.2", "react-jwt": "^1.2.0", "styled-components": "^6.1.3", "yup": "^1.3.3" }, "peerDependencies": { "antd": "4.24.4", "classnames": "^2.3.1", "react": ">=18.2.0", "react-dom": ">=18.2.0" }, "husky": { "hooks": { "pre-commit": "tsdx lint" } }, "prettier": { "printWidth": 80, "semi": true, "singleQuote": true, "trailingComma": "es5" }, "name": "test-lib-base", "author": "PradeepKumar", "module": "dist/test-lib-base.esm.js", "size-limit": [ { "path": "dist/test-lib-base.cjs.production.min.js", "limit": "10 KB" }, { "path": "dist/test-lib-base.esm.js", "limit": "10 KB" } ], "devDependencies": { "@rollup/plugin-url": "^8.0.2", "@size-limit/preset-small-lib": "^11.0.1", "@svgr/rollup": "^8.1.0", "@types/lodash": "^4.14.202", "@types/react": "^18.2.45", "@types/react-dom": "^18.2.18", "@types/react-router-dom": "^5.3.3", "antd": "4.24.4", "autoprefixer": "^10.4.16", "classnames": "^2.3.1", "css-loader": "^6.8.1", "cssnano": "^6.0.2", "husky": "^8.0.3", "lodash": "^4.17.21", "postcss": "^8.4.32", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.3.0", "rollup-plugin-postcss": "^4.0.2", "sass": "^1.69.5", "size-limit": "^11.0.1", "tsdx": "^0.14.1", "tslib": "^2.6.2", "typescript": "^5.3.3" } }
解决办法
1. 修改静态资源的公共路径
当前@rollup/plugin-url的publicPath设为根目录/,导致图片路径是绝对路径,react-router-dom会拦截这些根路径请求并尝试匹配路由。把它改成相对路径./:
// tsdx.config.js 中 url 插件配置 url({ include: ['**/*.svg', '**/*.png', '**/*.jpg', '**/*.gif'], limit: 0, sourceDir: path.resolve(__dirname, 'src'), publicPath: './', // 改为相对路径 }),
2. 避免SVGR与url插件的冲突
当前同时用@svgr/rollup和@rollup/plugin-url处理SVG文件,可能导致重复处理。可以让SVGR专门处理SVG,url插件处理其他图片:
// tsdx.config.js 中 url 插件配置 url({ include: ['**/*.png', '**/*.jpg', '**/*.gif'], // 移除SVG,交给SVGR处理 limit: 0, sourceDir: path.resolve(__dirname, 'src'), publicPath: './', }),
这样SVG会被转换成React组件引入,而非生成文件路径,从根源上避免路由拦截问题。
3. 确保组件库使用方的路由配置兼容
如果组件库被用于react-router-dom项目中,确保路由配置里添加静态资源的 fallback 规则,或者将组件库的静态资源复制到项目的public目录下。不过优先保证组件库自身输出相对路径的资源引用,减少使用方的配置成本。
内容的提问来源于stack exchange,提问作者pradeep kumar
相关产品推荐
相关产品推荐

