AWS放大Lambda函数ReactDOMServer.renderToString错误

时间:2019-10-02 04:57:19

标签: node.js reactjs aws-lambda aws-amplify

我正在使用以下方式构建类似于亚马逊的应用程序:

  • expo和本机反应
  • aws-amplify

我希望能够使用Expo Print API打印购物车(使用该应用程序,单击“打印”按钮,将购物车中的所有项目打印为pdf)。 Print API将HTML字符串作为输入。

有两种方法为购物车生成HTML:首先,将其硬编码为javascript字符串。这种方法很痛苦而且太老套了。

const html = cart => `
<!doctype html>
<html lang="en">
<head>
...
</head>
<div>
<h1>${cart.name}</h1>
...
</div>
`

或者利用某种工具将(更容易编写)react组件转换为HTML-react-dom-server看起来是正确的工具。但是,react-dom-server只能在服务器端而不是客户端使用,因此我尝试利用与aws-amplify很好集成的lambda函数。

这些是我尝试过的:

  • 添加放大功能
$ amplify function add
Using service: Lambda, provided by: awscloudformation
? Provide a friendly name for your resource to be used as a label for this category in the project: renderReact
? Provide the AWS Lambda function name: renderReact
? Choose the function template that you want to use: Serverless express function (Integration with Amazon API Gateway)
? Do you want to access other resources created in this project from your Lambda function? No
? Do you want to edit the local lambda function now? Yes
Please edit the file in your editor: /Users/evan/source/inventoryapp-mobile/amplify/backend/function/renderReact/src/index.js
? Press enter to continue
Successfully added resource renderReact locally.
  • 编辑放大/后端/功能/renderReact/src/app.js
import React from "react";
import ReactDOMServer from 'react-dom/server';

var express = require("express");
var bodyParser = require("body-parser");
var awsServerlessExpressMiddleware = require("aws-serverless-express/middleware");

// declare a new express app
var app = express();
app.use(bodyParser.json());
app.use(awsServerlessExpressMiddleware.eventContext());

// Enable CORS for all methods
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept"
  );
  next();
});

app.get("/render", function(req, res) {
  const reactDom = ReactDOMServer.renderToString(<div>hello world</div>);
  res.json({ success: htmlTemplate(reactDom), url: req.url });
});

function htmlTemplate(reactDom) {
  return `
        <!DOCTYPE html>
        <html>
        <head>
            <meta charset="utf-8">
            <title>React SSR</title>
        </head>

        <body>
            <div id="app">${reactDom}</div>
        </body>
        </html>
    `;
}

app.listen(3000, function() {
  console.log("App started");
});

// Export the app object. When executing the application local this does nothing. However,
// to port it to AWS Lambda we will create a wrapper around that will load the app from
// this file
module.exports = app;
  • 编辑amplify / backend / function / renderReact / src / package.json
{
  "name": "renderReact",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "aws-serverless-express": "^3.3.5",
    "body-parser": "^1.17.1",
    "express": "^4.15.2",
    "react": "^16.10.1",
    "react-dom": "^16.10.1"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
  • cd amplify/backend/function/renderReact/src && yarn install
  • 编辑放大/后端/功能/renderReact/src/event.json
{
    "httpMethod": "GET",
    "body": "{\"name\": \"Amplify\"}",
    "path": "/render",
    "resource": "/{proxy+}",
    "queryStringParameters": {}
}
  • cd返回项目根目录,运行功能但出错
$ amplify mock function renderReact
Using service: Lambda, provided by: awscloudformation
? Provide the name of the script file that contains your handler function: index.js
? Provide the name of the handler function to invoke: handler
? Provide the relative path to the event: event.json
Testing function locally
/Users/evan/source/inventoryapp-mobile/amplify/backend/function/renderReact/src/app.js:24
  const reactDom = ReactDOMServer.renderToString(<div>hello world</div>);
                                                 ^

SyntaxError: Invalid or unexpected token
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:947:10)

请注意,我并不是要渲染我的<ShoppingCart />组件,而只是尝试渲染最简单的<div>hello world</div> react组件,但是没有运气。

有帮助吗?谢谢。

0 个答案:

没有答案