reactjs – 使用webpack和react-router进行延迟加载和代码分割无
|
我正在努力将我的react v0.14 redux v3.0 react-router v1.0代码库从客户端渲染转移到服务器端渲染,使用webpack v1.12捆绑和代码分割成块来加载路由和组件一经请求.
我跟随并将我的设置基于https://github.com/rackt/example-react-router-server-rendering-lazy-routes,因为我认为它提供了简单性和出色的实用程序.整天昨天我一直在努力转向服务器端渲染,但我遇到了一些我无法解决的问题,我不能完全确定它们是否因为webpack没有正确设置,如果我正在做在服务器/客户端或路由配置上的react-router出了什么问题,或者如果我设置了导致这些问题的redux的错误. 我遇到了以下问题: >我能够加载初始页面,一切运行良好,但没有其他路线加载,并给了我GET http://localhost:3000/profile 404 (Not Found) webpack.config.js var fs = require('fs')
var path = require('path')
var webpack = require('webpack')
module.exports = {
devtool: 'source-map',entry: './client/client.jsx',output: {
path: __dirname + '/__build__',filename: '[name].js',chunkFilename: '[id].chunk.js',publicPath: '/__build__/'
},module: {
loaders: [
{
test: /.jsx?$/,exclude: /(node_modules|bower_components)/,loader: 'babel-loader'
}
]
},plugins: [
new webpack.optimize.OccurenceOrderPlugin(),new webpack.optimize.DedupePlugin(),new webpack.optimize.UglifyJsPlugin({
compressor: { warnings: false },}),new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
})
]
}
server.js import http from 'http';
import React from 'react';
import {renderToString} from 'react-dom/server';
import { match,RoutingContext } from 'react-router';
import {Provider} from 'react-redux';
import configureStore from './../common/store/store.js';
import fs from 'fs';
import { createPage,write,writeError,writeNotFound,redirect } from './server-utils.js';
import routes from './../common/routes/rootRoutes.js';
const PORT = process.env.PORT || 3000;
var store = configureStore();
const initialState = store.getState();
function renderApp(props,res) {
var markup = renderToString(
<Provider store={store}>
<RoutingContext {...props}/>
</Provider>
);
var html = createPage(markup,initialState);
write(html,'text/html',res);
}
http.createServer((req,res) => {
if (req.url === '/favicon.ico') {
write('haha','text/plain',res);
}
// serve JavaScript assets
else if (/__build__/.test(req.url)) {
fs.readFile(`.${req.url}`,(err,data) => {
write(data,'text/javascript',res);
})
}
// handle all other urls with React Router
else {
match({ routes,location: req.url },(error,redirectLocation,renderProps) => {
if (error)
writeError('ERROR!',res);
else if (redirectLocation)
redirect(redirectLocation,res);
else if (renderProps)
renderApp(renderProps,res);
else
writeNotFound(res);
});
}
}).listen(PORT)
console.log(`listening on port ${PORT}`)
服务器utils的 与我上面发布的repo相同,例如react-react-router-server-rendering-lazy-routes只是导航到repo中的/modules/utils/server-utils.js.唯一的区别是createPage函数: export function createPage(html,initialState) {
return( `
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="./../bower_components/Ionicons/css/ionicons.min.css">
<link rel="stylesheet" href="./../dist/main.css">
<title>Sell Your Soles</title>
</head>
<body>
<div id="app">${html}</div>
<script>window.__INITIAL_STATE__ = ${JSON.stringify(initialState)};</script>
<script src="/__build__/main.js"></script>
</body>
</html>
`);
}
rootRoute.js // polyfill webpack require.ensure
if (typeof require.ensure !== 'function') require.ensure = (d,c) => c(require)
import App from '../components/App.jsx'
import Landing from '../components/Landing/Landing.jsx'
export default {
path: '/',component: App,getChildRoutes(location,cb) {
require.ensure([],(require) => {
cb(null,[
require('./UserProfile/UserProfileRoute.js'),require('./UserHome/UserHomeRoute.js'),require('./SneakerPage/SneakerPageRoute.js'),require('./Reviews/ReviewsRoute.js'),require('./Listings/ListingsRoute.js'),require('./Events/EventsRoute.js')
])
})
},indexRoute: {
component: Landing
}
}
userProfileRoute.js import UserProfile from '../../components/UserProfile/UserProfile.jsx';
export default {
path: 'profile',component: UserProfile
}
client.js import React from 'react';
import { match,Router } from 'react-router';
import { render } from 'react-dom';
import { createHistory } from 'history';
import routes from './../common/routes/rootRoutes.js';
import {Provider} from 'react-redux';
import configureStore from './../common/store/store.js';
const { pathname,search,hash } = window.location;
const location = `${pathname}${search}${hash}`;
const initialState = window.__INITIAL_STATE__;
const store = configureStore(initialState);
// calling `match` is simply for side effects of
// loading route/component code for the initial location
match({ routes,location },() => {
render(
<Provider store={store}>
<Router routes={routes} history={createHistory()} />
</Provider>,document.getElementById('app')
);
});
我帮助你解决了不和谐,但我想我也会在这里发布答案.
如果您使用babel6(而不是babel5)并在组件中使用export default,则需要将路由更新为以下内容: getChildRoutes(location,(require) => {
cb(null,[
require('./UserProfile/UserProfileRoute.js').default,require('./UserHome/UserHomeRoute.js').default,require('./SneakerPage/SneakerPageRoute.js').default,require('./Reviews/ReviewsRoute.js').default,require('./Listings/ListingsRoute.js').default,require('./Events/EventsRoute.js').default
])
})
}
有关更多详细信息,请参阅此SO讨论:Babel 6 changes how it exports default (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
