我正在尝试部署我的反应应用程序,它比我最初想的要困难得多。 好吧,我已经遵循了这个指南:https://github.com/reactjs/react-router-tutorial/tree/master/lessons/13-server-rendering并且它不起作用。
我收到此错误消息:
ERROR in ./modules/routes.js
Module parse failed: /Users/Alfred/React/newReactWebpack/reactWebpack/modules/routes.js Unexpected token (17:2)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (17:2)
我觉得我现在完全无法调试,因为我不知道 webpack.server.config.js 文件是如何工作的,也不知道 webpack .config.js 文件。
所以我正在寻找一位可以帮助我的webpack向导。我很感激TON!
提前致谢!
webpack.server.config.js
var fs = require('fs')
var path = require('path')
module.exports = {
entry: path.resolve(__dirname, 'server.js'),
output: {
filename: 'server.bundle.js'
},
target: 'node',
// keep node_module paths out of the bundle
externals: fs.readdirSync(path.resolve(__dirname, 'node_modules')).concat([
'react-dom/server', 'react/addons',
]).reduce(function (ext, mod) {
ext[mod] = 'commonjs ' + mod
return ext
}, {}),
node: {
__filename: true,
__dirname: true
},
module: {
loaders: [
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react' }
]
}
}
webpack.config.js
'use strict';
const path = require('path');
const args = require('minimist')(process.argv.slice(2));
// List of allowed environments
const allowedEnvs = ['dev', 'dist', 'test'];
// Set the correct environment
let env;
if (args._.length > 0 && args._.indexOf('start') !== -1) {
env = 'test';
} else if (args.env) {
env = args.env;
} else {
env = 'dev';
}
process.env.REACT_WEBPACK_ENV = env;
/**
* Build the webpack configuration
* @param {String} wantedEnv The wanted environment
* @return {Object} Webpack config
*/
function buildConfig(wantedEnv) {
let isValid = wantedEnv && wantedEnv.length > 0 && allowedEnvs.indexOf(wantedEnv) !== -1;
let validEnv = isValid ? wantedEnv : 'dev';
let config = require(path.join(__dirname, 'cfg/' + validEnv));
return config;
}
module.exports = buildConfig(env);
server.js
// ...
// import some new stuff
import React from 'react'
// we'll use this to render our app to an html string
import { renderToString } from 'react-dom/server'
// and these to match the url to routes and then render
import { match, RouterContext } from 'react-router'
import routes from './modules/routes'
// ...
// send all requests to index.html so browserHistory works
app.get('*', (req, res) => {
match({ routes: routes, location: req.url }, (err, redirect, props) => {
// in here we can make some decisions all at once
if (err) {
// there was an error somewhere during route matching
res.status(500).send(err.message)
} else if (redirect) {
// we haven't talked about `onEnter` hooks on routes, but before a
// route is entered, it can redirect. Here we handle on the server.
res.redirect(redirect.pathname + redirect.search)
} else if (props) {
// if we got props then we matched a route and can render
const appHtml = renderToString(<RouterContext {...props}/>)
res.send(renderPage(appHtml))
} else {
// no errors, no redirect, we just didn't match anything
res.status(404).send('Not Found')
}
})
})
function renderPage(appHtml) {
return `
<!doctype html public="storage">
<html>
<meta charset=utf-8/>
<title>My First React Router App</title>
<link rel=stylesheet href=/index.css>
<div id=app>${appHtml}</div>
<script src="/bundle.js"></script>
`
}
var PORT = process.env.PORT || 8080
app.listen(PORT, function() {
console.log('Production Express server running at localhost:' + PORT)
})
的package.json
"scripts": {
"start": "if-env NODE_ENV=production && npm run start:prod || npm run start:dev",
"start:dev": "webpack-dev-server --inline --content-base public/ --history-api-fallback",
"start:prod": "npm run build && node server.bundle.js",
"build:client": "webpack",
"build:server": "webpack --config webpack.server.config.js",
"build": "npm run build:client && npm run build:server"
},
routes.js
import React from 'react'
import { Route, IndexRoute } from 'react-router'
import LandingPage from '../src/compositions/landingPage/LandingPage'
import Webshop from '../src/compositions/webshopPage/Webshop'
import Gallery from '../src/compositions/galleryPage/Gallery'
import Services from '../src/compositions/servicesPage/Services'
import Checkout from '../src/compositions/checkoutPage/Checkout'
import Faq from '../src/compositions/faq/Faq'
import Products from '../src/components/webshop/products/Products'
import Product from '../src/components/webshop/products/Product'
import WebshopHome from '../src/compositions/webshopPage/WebshopHome'
import Admin from '../src/compositions/adminPage/Admin'
import Login from '../src/compositions/adminPage/Login'
module.exports = (
<Route path="/" component={LandingPage}>
<Route path="webshop" component={Webshop}>
<IndexRoute component={WebshopHome}></IndexRoute>
<Route path="/webshop/checkout" component={Checkout}></Route>
<Route path="/webshop/:category" component={Products}></Route>
<Route path="/webshop/:category/:subcategory" component={Products}></Route>
<Route path="/webshop/:category/:subcategory/:product" component={Product}></Route>
</Route>
<Route path="gallery" component={Gallery}></Route>
<Route path="services" component={Services}></Route>
<Route path="login" component={Login}></Route>
<Route path="admin" component={Admin} onEnter={requireAuth}>
<Route path="/admin/:site" component={Admin}></Route>
<Route path="/admin/:site/:section" component={Admin}></Route>
<Route path="/admin/:site/:section/:category/:subcategory" component={Admin}></Route>
</Route>
<Route path="faq" component={Faq}></Route>
<Route path="*" component={NotFound}></Route>
</Route>
)
index.js
import React from 'react'
import firebase from 'firebase/app'
require('firebase/auth')
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { Router, browserHistory } from 'react-router'
import routes from '../modules/routes'
import store from './store/store'
//Initialize firebase
var config = {
apiKey: ***********
authDomain: **********
databaseURL: **********
storageBucket: **********
}
firebase.initializeApp(config)
const app = document.getElementById('app')
const NotFound = () => (<h4 style={{textAlign: 'center', paddingTop: 100}}>404.. Oops, nu hamnade du fel!</h4>)
function requireAuth(nextState, replace, callback) {
firebase.auth().onAuthStateChanged((user) => {
if (null === user) {
replace({
pathname: '/login',
state: { nextPathname: nextState.location.pathname }
})
callback()
}
callback()
})
}
render(
(<Provider store={store}>
<Router routes={routes} history={browserHistory}>
</Router>
</Provider>), app)