我正在尝试将我的express,node和react应用程序部署到heroku。一切都可以完美构建和运行。但是,当我尝试发送时,部署因语法错误而失败。它应该编译所有内容,但令人窒息。配置不是我的专长。你能帮我吗?谢谢!
这是错误(还显示了我的server / index.js文件的样子)
remote: Module build failed: SyntaxError: /tmp/build_932acc5e4d70ba43150e066b1e0f5fe1/src/server/index.js: Unexpected token (45:6)
remote:
remote: 43 | app.get("*", (req, res, next) => {
remote: 44 | const markup = renderToString(
remote: > 45 | <StaticRouter location={req.url} context={{}}>
remote: | ^
remote: 46 | <App />
remote: 47 | </StaticRouter>
remote: 48 | )
我也收到客户端的错误
remote: ERROR in ./src/browser/index.js
remote: Module build failed: SyntaxError: /tmp/build_932acc5e4d70ba43150e066b1e0f5fe1/src/browser/index.js: Unexpected token (10:2)
remote:
remote: 8 |
remote: 9 | const jsx = (
remote: > 10 | <Router><App /></Router>
remote: | ^
remote: 11 | )
remote: 12 |
remote: 13 | hydrate(
这是我的package.json
{
"name": "client",
"version": "0.1.0",
"private": true,
"main": "index.js",
"scripts": {
"dev": "webpack -w & nodemon server.js",
"start": "webpack & node server.js",
"heroku-postbuild": "yarn && yarn build",
"build": "webpack"
},
"dependencies": {
"@babel/plugin-transform-runtime": "^7.5.5",
"@babel/runtime": "^7.5.5",
"@emotion/core": "^10.0.16",
"aws-sdk": "2.x",
"babel-loader": "^8.0.6",
"bcrypt": "^3.0.6",
"body-parser": "~1.18.2",
"cookie-parser": "~1.4.3",
"cors": "^2.8.5",
"debug": "~2.6.9",
"ejs": "2.x",
"es6-promise": "^4.2.8",
"express": "^4.17.1",
"form-data": "^2.3.2",
"fs": "^0.0.1-security",
"history": "4.9.0",
"http": "0.0.0",
"isomorphic-fetch": "^2.2.1",
"jade": "~1.11.0",
"jsonwebtoken": "^8.1.1",
"mime": "^2.2.0",
"mongodb": "^3.0.1",
"mongoose": "^4.13.9",
"morgan": "~1.9.0",
"multer": "^1.3.0",
"multer-s3": "^2.7.0",
"prop-types": "^15.7.2",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-router-dom": "^5.0.1",
"react-scripts": "1.1.0",
"react-validation": "3.0.7",
"request": "^2.83.0",
"serialize-javascript": "^1.8.0",
"serve-favicon": "~2.4.5",
"validator": "^11.1.0",
"webpack-node-externals": "^1.7.2",
"webpack-cli": "^3.3.7",
"webpack-dev-server": "^3.8.0"
},
"devDependencies": {
"@babel/cli": "7.6.0",
"@babel/core": "7.6.0",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/plugin-proposal-do-expressions": "7.6.0",
"@babel/plugin-syntax-flow": "7.2.0",
"@babel/plugin-transform-regenerator": "7.4.5",
"@babel/preset-env": "^7.6.0",
"@babel/preset-flow": "7.0.0",
"@babel/preset-react": "7.0.0",
"@babel/preset-stage-2": "7.0.0",
"css-loader": "^0.28.11",
"emotion": "^10.0.14",
"html-webpack-plugin": "^3.2.0",
"jest": "22.1.4",
"nodemon": "^1.14.11",
"react-test-renderer": "16.2.0",
"regenerator-runtime": "^0.13.3"
}
}
和我的.babelrc
{
"env": {
"development": {
"presets": [
[ "@babel/preset-env", {
"targets": {
"browsers": [ "last 2 versions", "ie >= 11" ]
}
} ],
"@babel/preset-react",
"@babel/preset-flow"
],
"plugins": [
["emotion"],
"@babel/plugin-transform-runtime",
"@babel/plugin-proposal-do-expressions",
"@babel/plugin-syntax-flow",
"@babel/plugin-proposal-class-properties",
],
"comments": true
},
"test": {
"sourceMaps": false,
"presets": [
[ "@babel/preset-env", {
"targets": {
"browsers": [ "last 2 versions", "ie >= 11" ]
}
} ],
"@babel/preset-react",
"@babel/preset-flow"
],
"plugins": [
["emotion"],
"@babel/plugin-transform-runtime",
"@babel/plugin-proposal-do-expressions",
"@babel/plugin-syntax-flow",
"babel-plugin-dynamic-import-node",
"@babel/plugin-proposal-class-properties",
],
"comments": true
}
}
}
这是我的webpack配置
var path = require('path')
var webpack = require('webpack')
var nodeExternals = require('webpack-node-externals')
var browserConfig = {
entry: './src/browser/index.js',
output: {
path: path.resolve(__dirname, 'public'),
filename: 'bundle.js',
publicPath: '/'
},
node: {
fs: 'empty'
},
module: {
rules: [
{ test: /\.(js)$/, use: 'babel-loader' },
]
},
plugins: [
new webpack.DefinePlugin({
__isBrowser__: "true"
})
],
externals: [
'child_process'
]
}
var serverConfig = {
entry: './src/server/index.js',
target: 'node',
externals: [nodeExternals()],
output: {
path: __dirname,
filename: 'server.js',
publicPath: '/'
},
node: {
fs: 'empty'
},
module: {
rules: [
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
plugins: [
new webpack.EnvironmentPlugin({ NODE_ENV: 'development' }),
new webpack.DefinePlugin({
__isBrowser__: "false"
})
],
externals: [
'child_process'
],
}
module.exports = [browserConfig, serverConfig]
和我的server / index.js
import express from "express"
import { renderToString } from "react-dom/server"
import App from '../browser/App'
import React from 'react'
import { StaticRouter } from "react-router-dom"
import "isomorphic-fetch" // gives the ability to use fetch in server-loaded react code
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var env = process.env.NODE_ENV || 'development';
if (env === 'test' || env == 'development') {
require('./config/config');
}
require('./routes/api/cors');
var books = require('./routes/api/book');
var blogposts = require('./routes/api/post');
var projects = require('./routes/api/project');
var users = require('./routes/api/user');
var external = require('./routes/api/external');
const app = express()
app.use(logger('dev'));
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({ extended: false, limit: '50mb' }));
app.use(cookieParser());
app.use('/api/users', users);
app.use('/api/books', books);
app.use('/api/projects', projects);
app.use('/api/blogposts', blogposts);
app.use('/api/external', external);
app.use(express.static("public"))
app.get("*", (req, res, next) => {
const markup = renderToString(
<StaticRouter location={req.url} context={{}}>
<App />
</StaticRouter>
)
res.send(`
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Open+Sans|Medula+One">
<title>Website</title>
<script src="/bundle.js" defer></script>
<style>
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
</style>
</head>
<body>
<div id="app">
${markup}</div>
</body>
</html>
`
)
});
app.listen(3000, () => {
console.log(`Server is listening on port: 3000`)
})
有什么主意我做错了吗?谢谢!
答案 0 :(得分:1)
var express = require('express');
var path = require('path');
var serveStatic = require('serve-static');
const history = require('connect-history-api-fallback');
app = express();
const staticFileMiddleware = express.static(path.join(__dirname + '/build/'));
app.use(staticFileMiddleware);
app.use(history({
disableDotRule: true,
verbose: true
}));
app.use(staticFileMiddleware);
var port = process.env.PORT || 5000;
app.listen(port);
console.log('server started '+ port);
用此代码替换您的服务器端代码,安装这4个软件包
npm i express -s
npm i path -s
npm i serve-static -s
npm i connect-history-api-fallback -s
您的React App现在将在Express服务器localhost上运行。 另外,请查看此React Starter Kit,我使之很容易在Github
上在快速服务器上制作和部署应用答案 1 :(得分:0)
Heroku回到我身边,并指出我在.babelrc中缺少生产配置。他们很棒。