我正在尝试使用 react router 来拥有动态配置文件页面,最好是将其放在斜杠中,而不是像 URL 中的 ? 参数通配符。我正在寻找像/profile/{username}/
而不是/profile?user={username}
如果这有意义的话。
这是我用来尝试实现这一目标的路线;
<Route path="/profile/:name/" component={Profile}/>
但是当我尝试像"/profile/jeff/"或任何内容一样转到此路由时,它会返回一个捆绑包.js(webpack'd(,这是一个空白的 HTML 模板,它在捆绑包中是意外的.js并抛出错误。任何想法是我该如何解决这个问题?谢谢。
这是返回的捆绑包.js;
<html>
<body style="margin:0px; padding: 0px;">
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet">
<div id = "root" style="margin:0px; padding: 0px;"></div>
<script src="bundle.js"></script>
</body>
配置文件组件;
import React from 'react';
import styles from './profile.scss';
import astyles from './allpages.scss';
export default class Profile extends React.Component{
render(){
console.log("hello!");
const { match, location, history } = this.props
console.log(location);
console.log(match);
console.log(history);
return(
<div className = {styles.borderContainer}>
<p> {this.props.param.name} </p>
</div>
)
}
}
网络包配置;
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var path = require('path');
require('style-loader');
require('css-loader');
const loaders = {
css: {
loader: 'css-loader'
},
postcss: {
loader: 'postcss-loader',
options: {
plugins: (loader) => [
autoprefixer({
browsers: ['last 2 versions']
})
]
}
},
sass: {
loader: 'sass-loader',
options: {
indentedSyntax: true,
includePaths: [path.resolve(__dirname, './src/app')]
}
}
}
module.exports = {
context: __dirname,
entry: './src/app/index.js',
output: {
path: __dirname + '/dist/',
filename: 'bundle.js',
libraryTarget: 'umd'
},
devtool: "sourceMap",
module: {
loaders: [
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /.css$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
// Could also be write as follow:
// use: 'css-loader?modules&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader'
use: [
{
loader: 'css-loader',
query: {
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
},
'postcss-loader'
]
}),
},
{
test: /.scss$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
// Could also be write as follow:
// use: 'css-loader?modules&importLoader=2&sourceMap&localIdentName=[name]__[local]___[hash:base64:5]!sass-loader'
use: [
{
loader: 'css-loader',
query: {
modules: true,
sourceMap: true,
importLoaders: 2,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
},
'sass-loader'
]
}),
},
],
},
plugins: [
new ExtractTextPlugin('styles.css'),
],
}
当您请求/profile/jeff/
时,您会提供您发布的index.html
,并且大概是针对服务器上不存在的每个资源(作为后备(完成的。在index.html
中,您具有以下脚本标记:
<script src="bundle.js"></script>
这是一个相对路径。此时您实际上是在请求/profile/jeff/bundle.js
,并且由于不存在,因此您最终将index.html
作为捆绑包提供服务,这是有问题的,因为它不是有效的JavaScript。
无论当前 URL 如何,都应始终使用/bundle.js
。同样,你总是希望你的CSS /styles.css
。
<link rel="stylesheet" href="/styles.css">
<script src="/bundle.js"></script>
我没有更好的来源,但是需要将开发服务器配置为处理React Routers动态路由,因为它应该始终提供相同的html文件(index.html(,因为它是SPA。
https://redux.js.org/docs/advanced/UsageWithReactRouter.html
编辑:
特别是,我认为您在 webpack 配置中缺少这一点
devServer: {
historyApiFallback: true
}
编辑 2:
对于 ExpressJS,你需要这样的东西,
app.get('/*', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html'))
})
看起来这是您的样式表包含。我的理解是,您应该在组件中使用 babel import 语句,而不是链接标签,否则它们将 404 导致您看到的错误。