从零开始搭建React同构应用(三):配置SSR
从零开始搭建React同构应用(三):配置SSR这篇文章来讲解来配置 demo在这里 主要内容:
添加webpack的server render配置之前我是考虑在node端直接 //hook require require("babel-register")({ babelrc: "false",presets: ['react'],plugins: [ "transform-decorators-legacy","transform-es2015-modules-commonjs" ] }); //直接引入源码 const IndexBundle = require("./src/index/Index.jsx"); //do server side render... 这样少编译一套代码,觉得这样维护起来更方便,但是后来实践发现有几个问题:
最后权衡下,还是决定使用现在多一套ssr编译配置的方案。 在webpack.config.js添加以下代码 let serverConfig = {}; Object.assign(serverConfig,browserConfig,{ output: { path: path.join(__dirname,'build_server'),filename: "[name].bundle.js",libraryTarget: 'commonjs2' //设置导出类型,web端默认是var,node需要module.exports = xxx的形式 },module: { loaders: [ { test: /.jsx?$/,exclude: /node_modules/,loader: "babel-loader",query: { //node端的babel编译配置可以简化很多 babelrc: "false",plugins: [ "transform-decorators-legacy","transform-es2015-modules-commonjs" //如果不转换成require,import 'xxx.styl'会报错 ] } },{ test: /.(styl|css)$/,//node端不能 require('xx.css'),会报错 loader: 'null' },] },plugins: [ new webpack.ProvidePlugin({ React: 'react',ReactDOM: 'react-dom',fetch: 'isomorphic-fetch',promise: 'promise' }),new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) || JSON.stringify('development') }),],target: 'node',externals: [nodeExternals()],//不把node_modules中的文件打包 }); 因为
同时,在node环境不支持直接引入CSS文件的,如 这里我使用了webpack-node-externals插件,这个插件的原理是利用了webapck中的externals配置项,来剔除 执行试试 npm run watch
如果不用webpack-node-externals,打包出的文件体积会大很多
测试SSR输出其实使用React的ssr很简单,熟悉下面两个API即可:
React.createElement
这里简单解释下, ReactDOMServer.renderToString
而 测试这里我们先不搭建HTTP server,暂时用cli的方式模拟一下,方便大家理解。 新建cli.js,写入以下内容(以 /** * Created by chenchen on 2017/2/4. * * React server render 命令行测试 */ //以Index.jsx为例 const IndexBundle = require("../build_server/index.bundle.js"); const React = require("react"); const ReactDOMServer = require("react-dom/server"); let {renderToString} = ReactDOMServer; let initialData = {todoList: ['11','22','33']}; let instance = React.createElement(IndexBundle.default,initialData); //.defalut不能少 let str = renderToString(instance); console.log(str); 我们添加一条 "test-ssr": "node --harmony test/cli.js" 执行后效果如图
可以看到我们已经成功输出了组件渲染后的HTML文本了。 下一篇文章我将讲解如何搭建一个简单的 要注意的地方React生命周期React组件的声明周期只会到 前后端数据同步要注意浏览器端和服务器端的数据要一致,否则会出现HTML重用失败的错误: server side render 没有用到redux可能有人会疑惑,在浏览器编译的代码是: //初始数据,用于和server render数据同步 let initialData = window._SERVER_DATA || {}; let store = createStore(reducers,initialData,window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()); let App = connect(_ => _)(Layout);//用connect包装一下,这里只用到mapStateToProps,而且不对state加以过滤 ReactDOM.render( <Provider store={store}> <App/> </Provider>,document.getElementById('wrap')); 而server端的编译没有和Redux沾边,因为 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |