0

I have an Express server which uses a ESM dependency react-pdf. I also need the file to be .tsx as I'm using TypeScript JSX for rendering.

I have this working locally but I run into issues when trying to deploy to Vercel:

import React from "react";
import express, { Request, Response } from "express";
import ReactPDF, {
  Document,
  Page,
  Text,
  View,
  StyleSheet,
} from "@react-pdf/renderer";

const styles = StyleSheet.create({
  page: {
    flexDirection: "row",
    backgroundColor: "#E4E4E4",
  },
  section: {
    margin: 10,
    padding: 10,
    flexGrow: 1,
  },
});

const MyDocument = () => (
  <Document>
    <Page size="A4" style={styles.page}>
      <View style={styles.section}>
        <Text>Section #1</Text>
      </View>
      <View style={styles.section}>
        <Text>Section #2</Text>
      </View>
    </Page>
  </Document>
);

app.get("/pdf", async (req: Request, res: Response) => {
  const pdfStream = await ReactPDF.renderToStream(<MyDocument />);
  res.setHeader("Content-Type", "application/pdf");
  pdfStream.pipe(res);
});
/var/task/api/pdf.js:1
(function (exports, require, module, __filename, __dirname) { import React from "react";
                                                              ^^^^^^

SyntaxError: Cannot use import statement outside a module
    at new Script (node:vm:117:7)
    at Object.precompile (/opt/rust/bytecode.js:2:426)
    at Module.<anonymous> (/opt/rust/bytecode.js:2:1392)
    at A.l._compile (/opt/rust/bytecode.js:2:3145)
    at Object..js (node:internal/modules/cjs/loader:1895:10)
    at Module.load (node:internal/modules/cjs/loader:1465:32)
    at Function.<anonymous> (node:internal/modules/cjs/loader:1282:12)
    at /opt/rust/nodejs.js:2:12456
    at Function.Rr (/opt/rust/nodejs.js:2:12834)
    at Ae.e.<computed>.Me._load (/opt/rust/nodejs.js:2:12426)
Node.js process exited with exit status: 1. The logs above can help with debugging the issue.

I think the error is due to react-pdf using ESM modules, but from googling it seems Vercel does somewhat support these so I'm not sure what the solution is.

My repo with the issue: https://github.com/maybebansky/pdf-api-demo

4
  • On Vercel, the runtime does not transpile .tsx properly and assumes CJS. Use a Next.js project -> move to pages/api/pdf.tsx. Zero config. Perfect for Vercel. Production-ready. Commented Jun 18 at 7:56
  • I don't want to use NextJS. I only need to make an API not a frontend. Also I may move from Vercel to GCP in a few months. Commented Jun 18 at 8:30
  • You didn't mention any where in the quesiton that you need API. Commented Jun 18 at 8:40
  • Do you have "type": "module" inside your package.json? Commented Jun 19 at 18:42

1 Answer 1

2
+250

If you want to use ESM, Vercel supports both .mjs and .mts files. You can rename your file, for example:

/api/pdf.mts

It's hard to say much without seeing your config file, but you need to allow ESM support in tsconfig.json .

{
  "compilerOptions": {
    "module": "ESNext",
    "target": "ES2020",
    "moduleResolution": "NodeNext",
    "esModuleInterop": true,
    "jsx": "react",
    ...
  }
}

Lastly, I would confirm that your package.json has the correct type set up.

"type": "module"

Good luck!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.