(ReactJS +无服务器)静态服务页面与虚拟DOM错误

时间:2017-05-18 15:51:17

标签: javascript reactjs webpack webpack-dev-server serverless-framework

我们正在使用https://github.com/elastic-coders/serverless-webpack

拒绝服务器端的ReactJS组件

一切都很好,组件数据/标记被渲染出来。但是,当我们运行serverless webpack serve

时会出现问题

我们点击了本地主机链接,然后我们看到了应用程序,然后它就转到了白页。

如果我们进行View Source的深入检查,我们会看到所有标记,包括CSS和JS,所有内容。但是,在Chrome检查器中,我们只能看到应用<div>而已。就像我们的应用程序脚本行运行一样,我们用Virtual DOM替换静态内容。

对于那些使用React和无服务器渲染静态页面的人,你是如何克服这个问题的呢?

查看来源

enter image description here

Chrome Inspector

enter image description here

我们的handler.js文件

if (!global._babelPolyfill) {
  require('babel-polyfill');
}

import React from 'react'
import ReactDOMServer from 'react-dom/server'
import Home from './src/components/home/HomePage'
const component = ReactDOMServer.renderToStaticMarkup(<Home />);
const html = `<!DOCTYPE html>
<html lang="en">
<head>
    <title>WikiTags</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="author" content="WikiTags.com">
    <meta name="description" content="We rank what people are talking about.">
    <meta name="revisit-after" content="7 days">
    <link href="https://www.wikitags.com/" rel="canonical" />
    <meta name="twitter:card" content="summary">
    <meta name="twitter:site" content="@wikitags">
    <meta name="twitter:creator" content="@wikitags">
    <meta name="twitter:title" content="WikiTags">
    <meta name="twitter:description" content="We rank what people are talking about.">
    <meta name="twitter:image:src" content="http://admin.wikitags.com/dist/imgs/wikitags-twitter.jpg">
    <meta property="og:locale" content="en_US">
    <meta property="og:type" content="app">
    <meta property="og:site_name" content="WikiTags">
    <meta property="og:title" content="WikiTags | We rank what people are talking about.">
    <meta property="og:image" content="http://admin.wikitags.com/dist/imgs/wikitags-twitter.jpg">
    <meta property="og:url" content="https://www.wikitags.com/">
    <meta property="og:description" content="We rank what people are talking about.">
    <link rel="icon" href="http://admin.wikitags.com/dist/imgs/favicon.ico">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap-theme.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <link href="http://admin.wikitags.com/dist/wikitags.css" rel="stylesheet">
</head>
<body>
    <div id="wikitags-app">
        ${component}
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="http://admin.wikitags.com/dist/wikitags.bundle.js"></script>
</body>
</html>`;

export const home = (event, context, cb) => {
  const prom = new Promise((resolve, reject) => {
    resolve('success');
  });

  prom
    .then(r => cb(null, html))
    .catch(e => cb(e));
};

我们的webpack.serverless.config

module.exports = {
    entry: './handler.js',
    target: 'node',
    module: {
        loaders: [{
            test: /\.js$/,
            loaders: ['babel?' + JSON.stringify({
                plugins: [
                    'transform-runtime',
                    'transform-es2015-modules-commonjs'
                ],
                presets: ['es2015', 'react', 'stage-0'],
            })],
            include: __dirname,
            exclude: /node_modules/,
        },
        {
            test: /\.scss$/,
            loaders: ["css-loader", "sass-loader"]
        }]
    }
};

index.js

import React from "react";
import ReactDOM from "react-dom";

import App from "./app";

const root = document.getElementById("wikitags-app");

ReactDOM.render(<App/>, root);

思想

目前看来,我们仍然可以使用React来构建组件,我们从服务器返回数据并将这些数据作为道具传递到组件中以设置活动状态,选择状态等等......无服务器然后呈现静态视图。

但是,一旦用户获得该页面。我们无法添加实际的app.bundle.js文件,因为这会破坏应用程序,如上所示。但我们需要做的是在静态页面的底部添加原始Javascript或Jquery来处理任何逻辑。

这似乎是正确/唯一的举动吗?

1 个答案:

答案 0 :(得分:0)

我们想通了!我们从<Router>删除了Root,然后又返回了<HomePage />,因为我们不需要单页应用路由器,因为我们静态地为所有视图提供服务。

路由器破坏了应用程序,因为它试图在静态内容加载完毕后重新路由应用程序。

所以不是这个

import React from 'react';
import HomePage from './home/HomePage';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import CatgeoryPage from './category/CatgeoryPage';
import EntityPage from './entity/EntityPage';

export class Root extends React.Component {
    render() {
        return (
            <div>
                <Route exact={ true } path="/" component={ HomePage }/>
                <Route path="/category" component={ CatgeoryPage }/>
                <Route path="/entity" component={ EntityPage }/>
            </div>
        );
    }
}

export default Root;

我们有这个

import React from 'react';
import HomePage from './home/HomePage';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import CatgeoryPage from './category/CategoryPage';
import EntityPage from './entity/EntityPage';

export class Root extends React.Component {
    render() {
        return (
            <HomePage />
        );
    }
}


export default Root;