我正在使用以下方式构建类似于亚马逊的应用程序:
我希望能够使用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.
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;
{
"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
{
"httpMethod": "GET",
"body": "{\"name\": \"Amplify\"}",
"path": "/render",
"resource": "/{proxy+}",
"queryStringParameters": {}
}
$ 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组件,但是没有运气。
有帮助吗?谢谢。