问题描述
我已经阅读了类似的回复,但无法根据这些问题/答案找到我的具体问题,因此对于经常出现的问题,我提前道歉。
我在托管 React 应用程序的 AWS EB 上运行快速服务器。但是,我目前正在使用通用路由,并希望出于 SEO 目的切换到同构路由/服务器端渲染。我按照 this guide 获得了托管 React 前端的初始 express 应用,效果很好!
然后我尝试使用 this guide 添加服务器端渲染。
我的错误是:
Module build Failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /express-app/client/src/index.js: Support for the experimental Syntax 'jsx' isn't currently enabled (13:5):
Add @babel/preset-react (https://git.io/JfeDR) to the 'presets' section of your Babel config to enable transformation.
这是我的文件结构:
express-app/
- package.json
- server.js
- router.js
- routes.js
- renderFullPage.js
- .babelrc
- webpack.config.js
- client/ // This houses the React app
-- package.json
-- src/
--- index.js
--- app.js
--- // Other component sources
-- build/
--- Output from `npm run build-web`
最初,express 应用程序基本上只是用于为客户端构建提供服务的单个 server.js。
express-app/.babelrc:
{
"presets": [
"@babel/preset-env","@babel/preset-react"
]
}
以前,这不包括“@babel/preset-react”行。
express-app/webpack.config.js:
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'inline-source-map',entry: ['./client/src/index.js'],output: {
path: path.join(__dirname,'client','build'),filename: 'bundle.js'
},module: {
rules: [
{
loader: 'babel-loader',include: path.join(__dirname,'src'),exclude: /node_modules/,/*query: {
presets: ['es2015','react']
}*/
}
]
}
};
这里值得注意的是,我遵循的指南有 module.loaders 而不是 module.rules,因为该指南较旧。首先我将加载器更改为规则,然后它抱怨查询,所以我将其注释掉。
express-app/package.json:
{
"name": "redacted","version": "1.0.0","description": "redacted","main": "server.js","scripts": {
"start": "nodemon --exec babel-node server.js --ignore client","build": "babel server.js --out-file server.compiled.js","build:client": "webpack --config ./webpack.config.js/","build:prod": "npm run build && npm run build:client"
},"author": "redacted","license": "ISC","dependencies": {
"cors": "^2.8.5","express": "^4.17.1","node-jsx": "^0.13.3"
},"devDependencies": {
"@babel/cli": "^7.13.10","@babel/core": "^7.13.10","@babel/node": "^7.13.12","@babel/preset-env": "^7.13.12","@babel/preset-react": "^7.12.13","nodemon": "^2.0.7","babel-loader": "^8.2.2","babel-preset-react": "^6.24.1","webpack": "^5.28.0","webpack-cli": "^4.5.0"
}
}
在之前的实现中,脚本部分不包括 build:client 或 build:prod 行。我会在创建我的构建文件夹的 npm run build-web
文件夹中运行 client/
,然后从顶级文件夹运行 npm run build
,这将创建我编译的 server.js 文件。然后我会把它上传到 EB 并且一切顺利! devDependencies
是相同的,除了 nodemon
下面的所有内容都是遵循第二个指南后的新内容。
express-app/client/package.json:
{
"name": "redacted","main": "./App.js","engines": {
"node": "12.21.0","npm": "6.14.11"
},// ...
"dependencies": {
"react": "^17.0.1","react-art": "^16.13.1","react-dom": "^17.0.1","react-native": "^0.63.4","react-native-linear-gradient": "^2.5.6","react-native-web": "^0.15.0","react-native-webview": "^11.3.1","react-router-dom": "^5.2.0","react-scripts": "4.0.1","request": "^2.88.2","web-vitals": "^0.2.4"
},"scripts": {
"start-web": "react-scripts start","build-web": "react-scripts build","test-web": "react-scripts test","eject-web": "react-scripts eject","start:prod": "NODE_ENV=production node build/index.js","eb:prod": "npm run build-web && npm run start:prod"
},"devDependencies": {
"@babel/preset-react": "^7.12.13","babel-cli": "^6.26.0","babel-plugin-module-resolver": "^4.1.0","babel-plugin-transform-object-rest-spread": "^6.26.0","babel-plugin-transform-react-jsx-source": "^6.22.0","babel-preset-es2015": "^6.24.1","babel-preset-expo": "^8.3.0","eslint": "^7.22.0","eslint-plugin-react": "^7.22.0"
}
}
从这个文件中为你剪下我认为是膨胀的内容。此文件目前未更改,但从其他一些类似的问题/答案来看,我尝试将 "main": "./App.js",
更改为使用 ./build/App.js
,但无济于事。
这是我的 express-app/server.js
//Server.js
const express = require('express');
const path = require('path');
import router from './router';
const PORT = process.env.HTTP_PORT || 4001;
const app = express();
app.use(express.static(path.join(__dirname,'build')));
// Old routing before using isomorphic
/*
app.get('/*',(req,res) => {
res.sendFile(path.join(__dirname,'build','index.html'));
});
*/
// Now using router.js for isomorphic handling
app.get('*',router);
app.listen(PORT,() => {
console.log(`Server listening at port ${PORT}.`);
});
我留下了之前版本的评论,所以你可以看到我的代码是如何变化的。
express-app/router.js:
import {renderToString} from 'react-dom/server';
import React from 'react';
import {matchPath,StaticRouter} from 'react-router-dom';
import routes from './routes';
import renderFullPage from './renderFullPage';
import App from './client/src/app';
export default function router(req,res) {
const match = routes.reduce((acc,route) => matchPath(req.url,{path: route,exact: true}) || acc,null);
if( !match ){
res.status(404).send('page not found :(');
return;
}
const context = {};
const html = renderToString(
<StaticRouter context={context} location={req.url} >
<App />
</StaticRouter>
);
res.status(200).send(renderFullPage(html));
};
我注意到 App 的路径是 ./client/src/app
,所以这可能是 an 问题,但似乎不是 the 问题,因为它是index.js 变坏了。
express-app/client/src/index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import {browserRouter as Router} from 'react-router-dom';
import './index.css';
import App from './App';
// For isomorphic handling
ReactDOM.render((
<browserRouter>
<App />
</browserRouter>),document.getElementById('root')
);
// This was used prior to isomorphic handling
/*
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,document.getElementById('root')
);
*/
我再次将旧代码注释掉以进行比较。这就是我的错误的根源。在 browserRouter
行抛出错误。
我一直在纠结如何在不破坏东西的情况下解决这个问题。我需要重构我的整个应用程序吗?基本上改变我对客户端目录的划分?有没有我错过的愚蠢的衬里?任何帮助非常感激!
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)