aws усиливает лямбда-функцию ReactDOMServer.renderToString error - PullRequest
0 голосов
/ 02 октября 2019

Я создаю приложение, похожее на Amazon, используя:

  • expo и реагирующе-нативное
  • aws-усиление

Я хочу иметь возможность распечатать корзину с помощью Expo Print API (представьте, что с приложением, нажмите кнопку «Печать», чтобы распечатать все элементы из вашей корзины в PDF). API печати принимает в качестве входных данных строку HTML.

Существует два способа создания HTML-кода для корзины покупок: во-первых, жестко закодируйте его в виде строки JavaScript. Этот подход является болезненным и слишком старомодным.

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

Или используйте какой-либо инструмент для преобразования (гораздо проще написать) реагирующего компонента в HTML - response-dom-server выглядитправильный инструмент. Однако response-dom-server может использоваться только на стороне сервера, а не на стороне клиента, поэтому я пытаюсь использовать лямбда-функцию, которая хорошо интегрируется с aws-ampify.

Вот что я пробовал:

  • добавить функцию усиления
$ 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;
  • редактировать ampify / 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
  • редактировать ampify / backend / function / 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> реагирующий компонент, но не повезло.

Любая помощь? Спасибо.

...