Prerender将React应用为静态HTML

时间:2018-03-15 15:54:19

标签: javascript reactjs webpack html-webpack-plugin react-server

我有一个交互式登陆页面(单页 - 没有反应路由器)。此着陆页需要上传到CMS,您只需粘贴HTML即可 - 这意味着我不需要<html> <head> <body>标记,而且JavaScript文件会单独上传。目前,我只需将<div id="react-root"></div>粘贴到CMS中,然后上传我的捆绑JavaScript文件,页面即可运行。

但是,反馈是现在需要在所有搜索引擎上抓取此页面。这意味着我需要基本上渲染生成的初始HTML,以便粘贴到CMS中,并使页面仍然按预期工作。

我正在尝试使我的构建命令将呈现的HTML输出到index.html文件,我可以将代码复制并粘贴到CMS中。 (我的bundle.js文件工作正常。)

webpack.common.js

const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader',
        ]
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        use: [
          'file-loader'
        ]
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: [
          'file-loader'
        ]
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },
    ]
  },
  plugins: [
    new CleanWebpackPlugin(['dist'])
  ],
};

webpack.prod.js

const webpack = require('webpack');
const merge = require('webpack-merge');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const common = require('./webpack.common.js');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = merge(common, {
  plugins: [
    new UglifyJSPlugin(),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production')
    }),
    new HtmlWebpackPlugin({
      inject: false,
      template: require('./src/template.js'),
    })
  ]
});

template.js

const React = require('react');
const ReactDOMServer = require('react-dom/server');
const LandingPage = require('./App.js');
const html = ReactDOMServer.renderToString(LandingPage);

module.exports = function () {
  return ReactDOM.hydrate(html, document.getElementById('lp-root'));
};

所以我使用了react-dom-server来renderToString。这是最好的方法吗?如果是这样,这种方式不起作用,因为HtmlWebpackPlugin无法处理登陆页面中使用的ES6语法(导入和导出) - 无论如何围绕这个?

1 个答案:

答案 0 :(得分:0)

这种方法似乎是正确的 但是,您可能需要使用babel转换器来转换ES6语法中的代码 尝试在webpack配置中为js / jsx文件添加新规则 像这样:

  {
    test: /js$/,
    exclude: /(node_modules)/,
    loader: "babel-loader",
    query: { presets: ["react", "es2016", "es2015"], plugins: ["transform-class-properties"] },
  },

在使用之前,它会正确地传输您的代码。

希望它有所帮助。 如有任何疑问,请回复。