Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mupdf not working with Next.js RouteHandler #90

Open
arwtyxouymz opened this issue Jun 7, 2024 · 13 comments
Open

mupdf not working with Next.js RouteHandler #90

arwtyxouymz opened this issue Jun 7, 2024 · 13 comments
Assignees

Comments

@arwtyxouymz
Copy link

arwtyxouymz commented Jun 7, 2024

Hi there,

I also posted this on Discord and the member suggested me to create the issue here :)
I'm currently trying to use mupdf with Next.js RouteHandler, but I'm facing difficulties making it work. I would appreciate any help.

Overview

I am attempting to use mupdf within Next.js RouteHandler.
The test is very simple: fetch a PDF and convert it to PNG for the response.
I've tried both runtime = edge and runtime = nodejs, but both result in errors.
(I prefer to use edge runtime because my project is related to LLM work).

Next.js: 14.2.3(I tried 13.5.6, but the result was same)
mupdf: 0.2.2

Target file

The api is very simple. Just getting pdf file from /public directory, and load and convert it to png by using mupdf, and return it to client.

import { NextRequest, NextResponse } from "next/server";
import * as mupdf from "mupdf";

export const runtime = "edge";

export async function GET(req: NextRequest) {
  const res = await fetch("http://localhost:3000/dummy.pdf");
  const document = mupdf.Document.openDocument(
    await res.arrayBuffer(),
    "application/pdf"
  );
  const page = document.loadPage(0);
  const pixmap = page.toPixmap(
    mupdf.Matrix.scale(2, 2),
    mupdf.ColorSpace.DeviceRGB,
    false,
    true
  );
  const pngImage = pixmap.asPNG();

  return new NextResponse(pngImage, {
    headers: { "Content-Type": "image/png" },
  });
}

Errors

  • runtime=edge
  
pnpm dev

> [email protected] dev /Users/arwtyxouymz/work/sandbox/mupdf-edge-test
> next dev

  ▲ Next.js 14.2.3
  - Local:        http://localhost:3000

 ✓ Starting...
 ✓ Ready in 2.7s
 ○ Compiling /_not-found ...
 ✓ Compiled /_not-found in 2.9s (464 modules)
 GET /sample.pdf 404 in 3007ms
 ✓ Compiled in 107ms (236 modules)
 ✓ Compiled in 133ms (236 modules)
 ⨯ ./node_modules/.pnpm/[email protected]/node_modules/mupdf/dist/mupdf-wasm.js:100:27
Module not found: Can't resolve 'module'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/.pnpm/[email protected]/node_modules/mupdf/dist/mupdf.js
./app/api/mupdf/route.ts
./node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/build/webpack/loaders/next-edge-app-route-loader/index.js?absolutePagePath=%2FUsers%2Farwtyxouymz%2Fwork%2Fsandbox%2Fmupdf-edge-test%2Fapp%2Fapi%2Fmupdf%2Froute.ts&page=%2Fapi%2Fmupdf%2Froute&appDirLoader=bmV4dC1hcHAtbG9hZGVyP25hbWU9YXBwJTJGYXBpJTJGbXVwZGYlMkZyb3V0ZSZwYWdlPSUyRmFwaSUyRm11cGRmJTJGcm91dGUmYXBwUGF0aHM9JnBhZ2VQYXRoPXByaXZhdGUtbmV4dC1hcHAtZGlyJTJGYXBpJTJGbXVwZGYlMkZyb3V0ZS50cyZhcHBEaXI9JTJGVXNlcnMlMkZhcnd0eXhvdXlteiUyRndvcmslMkZzYW5kYm94JTJGbXVwZGYtZWRnZS10ZXN0JTJGYXBwJnBhZ2VFeHRlbnNpb25zPXRzeCZwYWdlRXh0ZW5zaW9ucz10cyZwYWdlRXh0ZW5zaW9ucz1qc3gmcGFnZUV4dGVuc2lvbnM9anMmcm9vdERpcj0lMkZVc2VycyUyRmFyd3R5eG91eW16JTJGd29yayUyRnNhbmRib3glMkZtdXBkZi1lZGdlLXRlc3QmaXNEZXY9dHJ1ZSZ0c2NvbmZpZ1BhdGg9dHNjb25maWcuanNvbiZiYXNlUGF0aD0mYXNzZXRQcmVmaXg9Jm5leHRDb25maWdPdXRwdXQ9JnByZWZlcnJlZFJlZ2lvbj0mbWlkZGxld2FyZUNvbmZpZz1lMzAlM0Qh&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D!
 ○ Compiling /api/mupdf ...
 ⚠ ./node_modules/.pnpm/[email protected]/node_modules/mupdf/dist/mupdf.js
The generated code contains 'async/await' because this module is using "topLevelAwait".
However, your target environment does not appear to support 'async/await'.
As a result, the code may not run as expected or may cause runtime errors.

Import trace for requested module:
./node_modules/.pnpm/[email protected]/node_modules/mupdf/dist/mupdf.js
./app/api/mupdf/route.ts
./node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapi%2Fmupdf%2Froute&page=%2Fapi%2Fmupdf%2Froute&appPaths=&pagePath=private-next-app-dir%2Fapi%2Fmupdf%2Froute.ts&appDir=%2FUsers%2Farwtyxouymz%2Fwork%2Fsandbox%2Fmupdf-edge-test%2Fapp&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&rootDir=%2FUsers%2Farwtyxouymz%2Fwork%2Fsandbox%2Fmupdf-edge-test&isDev=true&tsconfigPath=tsconfig.json&basePath=&assetPrefix=&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D!./app/api/mupdf/route.ts?__next_edge_ssr_entry__
 GET /api/mupdf 500 in 1835ms
 ✓ Compiled /_error in 148ms (419 modules)
  • runtime=nodejs
pnpm dev

> [email protected] dev /Users/arwtyxouymz/work/sandbox/mupdf-edge-test
> next dev

  ▲ Next.js 14.2.3
  - Local:        http://localhost:3000

 ✓ Starting...
 ✓ Ready in 1546ms
 ⨯ ./node_modules/.pnpm/[email protected]/node_modules/mupdf/dist/mupdf-wasm.js:114:1
Module not found: Can't resolve './'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/.pnpm/[email protected]/node_modules/mupdf/dist/mupdf.js
./app/api/mupdf/route.ts
 ○ Compiling /_not-found ...
 ⨯ ./node_modules/.pnpm/[email protected]/node_modules/mupdf/dist/mupdf-wasm.js:114:1
Module not found: Can't resolve './'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/.pnpm/[email protected]/node_modules/mupdf/dist/mupdf.js
./app/api/mupdf/route.ts
 ✓ Compiled /_not-found in 100ms (236 modules)
 ○ Compiling /_error ...
 ⨯ ./node_modules/.pnpm/[email protected]/node_modules/mupdf/dist/mupdf-wasm.js:114:1
Module not found: Can't resolve './'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/.pnpm/[email protected]/node_modules/mupdf/dist/mupdf.js
./app/api/mupdf/route.ts
 GET /api/mupdf 500 in 2651m

How to reproduce

I create the minimum reproduce repo.
https://github.com/arwtyxouymz/mupdf-edge-test
You can try it just like this.

Updated: 06/11
I updated my repo to be able to test easily.

$ pnpm dev

# In another session
# Route Handler
## => Not work
$ curl http://localhost:3000/api/mupdf/edge
## => Not work
$ curl http://localhost:3000/api/mupdf/nodejs

# API Routes
## => Not work
$ curl http://localhost:3000/api/pages/mupdf/edge
## => WORK!!
$ curl http://localhost:3000/api/pages/mupdf/nodejs

Thank you for your help and for maintaining this great project!

@jamie-lemon
Copy link
Collaborator

Okay - this is not related to using Next.js or the RouteHandler - we had a previous issue here: #12 - you can also checkout the react-example branch to validate the same errors you are seeing ( see examples/mupdf-react after checking out that branch ) .
We have mupdf.js working in the browser with the node modules, but more with vanilla JS - see examples/annotations-test for how that is done. I don't know if this helps you with your environment though!

We need to figure out how to resolve this "module not found" issue, to be honest I don't comprehend the complexities around it. I will assign some engineers to this Issue who might understand this better.

@arwtyxouymz
Copy link
Author

arwtyxouymz commented Jun 8, 2024

@jamie-lemon Thank you for the response and providing examples.
I found it works with next.js API Routes with nodejs runtime.
I don't understand why API routes with nodejs runtime works even though it doesn't work Route Handler with nodejs runtime.

I updated the https://github.com/arwtyxouymz/mupdf-edge-test and you can try it by:

$ pnpm dev
# This causes error (using Route Handler)
$ curl http://localhost:3000/api/mupdf
# This works (using API Routes with nodejs runtime)
$ curl http://localhost:3000/api/pages/mupdf

I hope this helps your investigation. Thanks.

@mfts
Copy link

mfts commented Jun 8, 2024

@arwtyxouymz @jamie-lemon I solved it by explicitly adding the mupdf wasm files in Next.js config

https://github.com/mfts/papermark/blob/main/next.config.mjs#L14

Maybe that solves your issue

@arwtyxouymz
Copy link
Author

@mfts

Actually, I read your article and tried your solution before creating the issue.
But it didn't work with app router. (You use pages router)
And your mupdf version is v0.1.* but i use v0.2.*.
I tried your repo code with mupdf v0.2 and app router, it didn't work.

@mfts
Copy link

mfts commented Jun 9, 2024

That's a good point. I'll try it with 0.2 and work with it

@jamie-lemon
Copy link
Collaborator

@arwtyxouymz Thanks for the feedback - I can confirm that I can also see it working with your API Routes with nodejs runtime solution.
"I don't understand why API routes with nodejs runtime works even though it doesn't work Route Handler with nodejs runtime."

I also don't understand this :) . All I know is that the library works fine under the node js environment, which explains why the "API routes with nodejs runtime" would work in this case. I have asked @mipo1357 to look into this issue further and hopefully he might have some ideas ( he is more of a React programmer than I am ;) )

@mipo1357
Copy link
Collaborator

Thanks for pointing out the problem. I am attempting to investigate here but am unable to provide a solution. Please give me some more time.

@arwtyxouymz
Copy link
Author

@mipo1357 @jamie-lemon
I could make mupdf work with runtime=nodejs in Route Handler by just adding mupdf to serverComponentsExternalPackages

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    serverComponentsExternalPackages: ['mupdf'],
  },
};

export default nextConfig;

@mfts
Copy link

mfts commented Jul 5, 2024

Thanks @arwtyxouymz for your example repo

I successfully updated mupdf from v0.1.3 to v0.2.2.

I made the following changes:

  • next.config.js: change to /dist/ from /lib/
     experimental: {
      outputFileTracingIncludes: {
        "/api/mupdf/*": ["./node_modules/mupdf/dist/*.wasm"],
      },
  • pages/api/mupdf.ts: import statement
    import * as mupdf from "mupdf";
  • tsconfig.json: change to bundler
    "moduleResolution": "bundler",

next.js 14.2.4
node 20.8.0
typescript 5.5.3

@mipo1357
Copy link
Collaborator

mipo1357 commented Jul 9, 2024

Thanks for the info. I will check these actions!

@Southclaws
Copy link

I'm running into this now, same settings as what @mfts has shared but still getting the following error on build:

Failed to compile.

./node_modules/mupdf/dist/mupdf-wasm.js
Module not found: Can't resolve 'module'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/mupdf/dist/mupdf.js
./src/screens/pitch/usePitchScreen.ts
./src/screens/pitch/PitchScreen.tsx
./src/screens/pitch/PitchScreenModal.tsx
./src/screens/profile/ProfileScreen.tsx

@mfts
Copy link

mfts commented Jul 20, 2024

@Southclaws bundler, next.config is set like mine above?
And you're on mupdf@^0.2.2 ?

@Southclaws
Copy link

I did get this working eventually on 0.2.2 inside a route handler (not a page handler) - though now we've switched to doing this in our Go backend using https://github.com/klippa-app/go-pdfium

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants