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

4.0.189: Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari14" + 2 overrides) #17245

Closed
jiadesen opened this issue Nov 9, 2023 · 53 comments · Fixed by #18051

Comments

@jiadesen
Copy link

jiadesen commented Nov 9, 2023

Attach (recommended) or Link to PDF file here: any

Configuration:

  • Web browser and its version: Google Chrome 119
  • Operating system and its version: macOS 14.1
  • PDF.js version: 4.0.189
  • Is a browser extension: no
  VITE v4.5.0  ready in 457 ms

  ➜  Local:   http://localhost:5273/pdf/
  ➜  Network: http://192.168.10.13:5273/pdf/
  ➜  press h to show help

✘ [ERROR] Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari14" + 2 overrides)

    node_modules/.pnpm/pdfjs-dist@4.0.189/node_modules/pdfjs-dist/build/pdf.mjs:16837:53:
      16837 │ /******/ __webpack_exports__ = globalThis.pdfjsLib = await __webpack_exports__;
            ╵                                                      ~~~~~

4:46:45 PM [vite] error while updating dependencies:
Error: Build failed with 1 error:
node_modules/.pnpm/pdfjs-dist@4.0.189/node_modules/pdfjs-dist/build/pdf.mjs:16837:53: ERROR: Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari14" + 2 overrides)
    at failureErrorWithLog (/Users/xxx/node_modules/.pnpm/esbuild@0.18.20/node_modules/esbuild/lib/main.js:1649:15)
    at /Users/xxx/node_modules/.pnpm/esbuild@0.18.20/node_modules/esbuild/lib/main.js:1058:25
    at /Users/xxx/node_modules/.pnpm/esbuild@0.18.20/node_modules/esbuild/lib/main.js:1525:9
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
@jiadesen
Copy link
Author

jiadesen commented Nov 9, 2023

Export pdfjsLib as follows:

import * as pdfjsLib from "pdfjs-dist";
import * as pdfWorker from "pdfjs-dist/build/pdf.worker.mjs";

// Setting worker path to worker bundle.
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfWorker;

export { pdfjsLib };

@ghenry
Copy link

ghenry commented Nov 9, 2023

Is this a solution @jiadesen ?

I'm getting them same as you as jut trying out v4 in a new project and getting:

[watch] build started (change: "js/pdf_preview/index.js")
✘ [ERROR] Top-level await is currently not supported with the "iife" output format

    node_modules/pdfjs-dist/build/pdf.mjs:16837:53:
      16837 │ ...ck_exports__ = globalThis.pdfjsLib = await __webpack_exports__;
            ╵                                         ~~~~~

See https://elixirforum.com/t/importing-pdf-mjs-into-app-js/59578 with --target=es2022 that is via esbuild. If I use the default of --target=es2017 I get:

✘ [ERROR] Top-level await is not available in the configured target environment ("es2017")

    node_modules/pdfjs-dist/build/pdf.mjs:16837:53:
      16837 │ ...ck_exports__ = globalThis.pdfjsLib = await __webpack_exports__;

Should work or should we go back to v3?

@ghenry
Copy link

ghenry commented Nov 9, 2023

No, it's just how you're importing it. Have switch to that way to confirm that we have the same issue. We do.

@Snuffleupagus
Copy link
Collaborator

Searching for the error message Top-level await is currently not supported with the "iife" output format with Google points to evanw/esbuild#253, which suggests that this unfortunately is a known limitation of the esbuild bundler.

Looking at the MDN compatibility data all modern browsers/environments support top level await, and has done so for awhile, hence the only suggestion that we can really provide is to (if possible) use another bundler instead.

@jiadesen
Copy link
Author

Solved by adding vite configuration:

optimizeDeps: {
    esbuildOptions: {
        target: "esnext",
    },
},

@hand-dot
Copy link

I also encountered the same error, but I was able to resolve the issue by installing the following vite plugin.
https://www.npmjs.com/package/vite-plugin-top-level-await

@ThisIszas
Copy link

this should be the final answer

{
  build: {
    target: "es2022"
  },
  esbuild: {
    target: "es2022"
  },
  optimizeDeps:{
    esbuildOptions: {
      target: "es2022",
    }
  }
}

@acbellini
Copy link

this should be the final answer

{
  build: {
    target: "es2022"
  },
  esbuild: {
    target: "es2022"
  },
  optimizeDeps:{
    esbuildOptions: {
      target: "es2022",
    }
  }
}

this fixed it for me, thank you!

@Benluc
Copy link

Benluc commented Nov 28, 2023

Is this a solution @jiadesen ?

I'm getting them same as you as jut trying out v4 in a new project and getting:

[watch] build started (change: "js/pdf_preview/index.js")
✘ [ERROR] Top-level await is currently not supported with the "iife" output format

    node_modules/pdfjs-dist/build/pdf.mjs:16837:53:
      16837 │ ...ck_exports__ = globalThis.pdfjsLib = await __webpack_exports__;
            ╵                                         ~~~~~

See https://elixirforum.com/t/importing-pdf-mjs-into-app-js/59578 with --target=es2022 that is via esbuild. If I use the default of --target=es2017 I get:

✘ [ERROR] Top-level await is not available in the configured target environment ("es2017")

    node_modules/pdfjs-dist/build/pdf.mjs:16837:53:
      16837 │ ...ck_exports__ = globalThis.pdfjsLib = await __webpack_exports__;

Should work or should we go back to v3?

I have the same issue here. I am trying to use pdf.js v4 in an elixir/phoenix framework environment where the bundler is esbuild. Should it work or do we have to switch back to v3?

@specialistvlad
Copy link

this should be the final answer

{
  build: {
    target: "es2022"
  },
  esbuild: {
    target: "es2022"
  },
  optimizeDeps:{
    esbuildOptions: {
      target: "es2022",
    }
  }
}

this fixed it for me, thank you!

It works better, compatible with vite-bundle-visualizer

@mturoci
Copy link

mturoci commented Jan 19, 2024

For anyone wanting broader browser support - https://www.npmjs.com/package/vite-plugin-top-level-await.

{
// vite.config
plugins: [
    // ...
    topLevelAwait({
      promiseExportName: '__tla',
      promiseImportName: i => `__tla_${i}`,
    }),
  ],
}

Note: Bundle size will be 30kb larger compared to native es2022.

@farisshomali
Copy link

And if i'm working in Angular project that's been created with Angular CLI (NO VITE CONFIGURATION FILE !), what should i do ?

How to solve this issue with projects that does not based on vite ?

@yuri-apanasik
Copy link

Agree with @farisshomali, angular out-of-the-box uses Webpack, there is possibility to customize its configuration with (experiments: { topLevelAwait: true }), but it means stick to webpack (not good). Trying to use 'esbuild' (planned to be used by Angular out-of-the-box) and pdfjs - build fails ('esbuild' has no intention to support toplevelawait' at all). So, question is can 'top level await' be avoided by 'pdfjs'? It will make it easier to use any bundler.

@yuri-apanasik
Copy link

@Snuffleupagus ↑ ?

@Priestch
Copy link
Contributor

@yuri-apanasik I don't know how you use the pdf.js project, but I think it's possible to avoid use "top level await".

The top level await is used to load the main bundle of pdf.js, it contains all core features any viewer solution will depends on. The pdf.js also has a web bundle, it contains all code the default viewer needs, and of course it depends the main bundle.

The possible way to avoid the top level await is develop a custom gulp task, just build a single bundle which combine the web and main bundles together, then the issue will gone. it's may not be an easy job depending on your knowledge of the pdf.js project.

@yuri-apanasik
Copy link

@Priestch yes, I am new in pdf.js, we just looked for the tool to convert PDF to PNG on the client side and found pdf.js. So, as lazy developers we just took pre-built 'pdfjs-dist' package and faced with bundler issue. For now we are on PoC phase, so as a solution we just downgraded 'pdfjs-dist' to V3. For the production looks like we should go with custom build solution. Thank you for the suggestion!
But at the same time, nowadays it is more common to just 'take and use' and when some package requires complicated setup it looks like something from 90s. Especially when there is no special tooling to apply all configuration with one magical command. It is a joke (partly), but it would be nice if you can provide some examples in the pdfjs docs about custom builds in different cases.

@Priestch
Copy link
Contributor

@yuri-apanasik What do you mean "on the client side"? You used pdf.js in browser or node environment?

If you use it in browser, all you need is comment out two lines code, and run gulp task dist-pre, the result will not contain the top level await.

You can also change the two files to flatten and replace the await __non_webpack_import__ with directly import under some if inNodeJS statement.

libraryAlias["display-node_stream"] = "src/display/node_stream.js";

    // line 305, 306
    // libraryAlias["display-node_stream"] = "src/display/node_stream.js";
    // libraryAlias["display-node_utils"] = "src/display/node_utils.js";

@yuri-apanasik
Copy link

@Priestch I mean in browser, yes. Thank you one more time for the hint! We'll try to make our own pdfjs build. But as you can see it is not only my problem, a lot of developers who want to easily use pre-built package face with this problem. One of the minimal ways to reproduce is:

  • create new Angular app 'ng new app-test-pdfjs-dist'
  • install pdfjs-dist 'npm i pdfjs-dist'
  • add any import 'import { getDocument } from 'pdfjs-dist'' and mention 'getDocument' somehow, so import is not ignored by bundler

Result -> build failed. As you suggested situation can be fixed with custom build, but it makes 'pdfjs' minimal usage example more complicated.
After we fix the issue with custom build we'll probably prepare short blog post, but later, now we are ok with v3 for PoC version.

@jiadesen
Copy link
Author

@Priestch If only in a browser environment, I'd like to know what other code could be annotated and whether this could significantly reduce the size of the build artifact

@Priestch
Copy link
Contributor

@jiadesen it's just quick hack to fix the issue, I think it doesn't reduce the build artifact.

@nicolo-ribaudo
Copy link
Contributor

This seems like a bug in angular, if a default angular app crashes when using a stable JavaScript feature. It's like saying "please don't use classes because Angular has a bug and doesn't support them".

@MikeDabrowski
Copy link

I don't agree this is an issue with Angular. The v3 works for us for now but we had some badly rendered pdfs lately and want an upgrade. The only v3 that worked so far was 3.8.162 due to svg typings issues. We only use basic rendering so never dug deep enough to understand this library. Both builders in angular produce some errors, the common one being this top-level-await. While I understand Angulars position (zone.js etc), I don't know pdf.js enough to understand forcing incompatible builds.

Moreover - there is this legacy build available yet somehow it can't be imported - when building the app it throws not found errors.

We are running out of ideas how to workaround the workaround.

@yuri-apanasik
Copy link

yuri-apanasik commented Feb 1, 2024

@MikeDabrowski if you are using default Angular configuration with Webpack, you can customize it by installing '@angular-builders/custom-webpack' NPM package and changing '@angular-devkit/build-angular' to '@angular-builders/custom-webpack' in angular.json (some more adjustments should be done, just google it). When you can create the following custom webpack config to avoid top-level-await error: module.exports = { experiments: { topLevelAwait: true, }, };.
But as I mentioned earlier that means you somehow stick to webpack and there is no way to switch to 'esbuild' for example. Or, as it was said in the beginning of the issue, if you want 'vite' you need to customize its configuration too.

At the same time @Priestch already suggested the solution with custom 'pdfjs' build.

@nicolo-ribaudo yes, it is NOT angular bug. It is about bundlers, 'esbuild' for example have no intention to support top-level-await at all (evanw/esbuild#253). So, 'pdfjs' in its full version (without commenting out some unnecessary code in case of usage in browser) can't be used with 'esbuild'. 'webpack'/'vite' need custom configuration. So, trying to make an improvement in V4 with es modules (if I got it right) it appeared that developers who used V3 easily now have to spent hours to understand what is wrong with their build using V4...

@MikeDabrowski
Copy link

MikeDabrowski commented Feb 1, 2024

@yuri-apanasik - yep, im just doing it - but v4 changes the location of workers and my app needed them I think. So trying to somehow work that out.

export 'default' (imported as 'pdfjsWorker') was not found in 'pdfjs-dist/build/pdf.worker.mjs' (possible exports: WorkerMessageHandler)

I wouldnt mind that custom build, we could host it. But I dont want to waste time reading how to do it. As you said in one of your comments its like in the 90s -here is kernel, now code build yourself an OS to write play asteroids or sth... Aint nobody got time for that.

Any chance someone posts how to prep whole build?

For reference our usage is for example: - I am not even sure if we need the workers

if (!GlobalWorkerOptions.workerSrc) {
      GlobalWorkerOptions.workerSrc = pdfjsWorker;
    }
    return new Response(file)
      .arrayBuffer()
      .then(
        async (data: BinaryData) =>
          getDocument({ data, verbosity: 0 } as DocumentInitParameters)
            ?.promise,
      )
      .then(async (doc) => {
        const numPages = doc.numPages;
        await doc.destroy();
        return numPages > attachmentPageLimit;
      })
      .catch((e) => {
        if (e.name !== 'PasswordException') {
          throw new Error(e);
        } else {
          throw new JsPdfLibError(this.corruptOrPwdProtectedMessage, e);
        }
      });

@yuri-apanasik
Copy link

@Priestch Just for information... I've tried to make custom pdfjs build, there were some troubles: for example, 'node-canvas' have no arm64 build, so had to solve this issue for M1. Finally pdfjs was ok, but unfortunately when I copied result files into the project and build (actually build was also successful) I faced with error in runtime (some class used before its declaration).
I think it is not 'pdfjs' problem, more likely it is webpack glitches, but with the team we decided not to spend more time on this and stay with 'pdfjs' V3.
I don't believe it is only some people from this issue who faced with 'top level await' incompatibility and didn't upgrade to V4 because of that. So, probably, you can at least discuss in your team this question and measure the necessity of using 'top level await' feature.

@MikeDabrowski
Copy link

Can we get this issue reopened ? This has not been resolved yet.

@yuri-apanasik That is exactly what I was afraid of - more issues when making custom build.

The reason we wanted to update to v4 is that we had one incident with pdf badly rendered - some border was misplaced. Could not reproduce it unfortunately, so now we are waiting and keeping an eye for such errors.

@JHarrisGTI
Copy link

@Snuffleupagus My company is also interested. I emailed you a few days ago but I'm not sure if it went through. Hopefully it didn't get stuck in a spam folder.

@Snuffleupagus
Copy link
Collaborator

@Snuffleupagus My company is also interested. I emailed you a few days ago but I'm not sure if it went through. Hopefully it didn't get stuck in a spam folder.

@JHarrisGTI Thanks, I've replied to the email so let's continue there :-)

@jothbc
Copy link

jothbc commented May 2, 2024

in reactjs using pdfjs-dist (npm) v4.2.67 and vite:

install:

yarn pdfjs-dist;

update vite.config.ts:

  build: {
    target: 'es2022',
  },
  esbuild: {
    target: 'es2022',
  },
  optimizeDeps: {
    esbuildOptions: {
      target: 'es2022',
    },
  },

import:

import * as pdfjsLib from 'pdfjs-dist';

pdfjsLib.GlobalWorkerOptions.workerSrc = '../../node_modules/pdfjs-dist/build/pdf.worker.min.mjs';

my use:

const pdfThumb = await new Promise((resolve, reject) => {
      const fileReader = new FileReader();
      fileReader.onload = async () => {
        try {
          const typedArray = new Uint8Array(fileReader.result as ArrayBuffer);
          const pdf = await pdfjsLib.getDocument(typedArray).promise;
          const page = await pdf.getPage(1);
          const scale = 1.5;
          const viewport = page.getViewport({ scale });
          const canvas = document.createElement('canvas');
          const context = canvas.getContext('2d');
          canvas.width = viewport.width;
          canvas.height = viewport.height;

          const renderContext = {
            canvasContext: context,
            viewport: viewport,
          } as {
            canvasContext: CanvasRenderingContext2D;
            viewport: pdfjsLib.PageViewport;
          };

          await page.render(renderContext).promise;
          const imageUrl = canvas.toDataURL('image/jpeg');
          resolve(imageUrl);
        } catch (err) {
          console.log(err);
          reject('some error');
        }
      };
      fileReader.readAsArrayBuffer(file as FileType);
    });

im my case i only need a thumbnail of pdf...

@Snuffleupagus
Copy link
Collaborator

@JHarrisGTI The PR landed earlier today, and I've tried to reach you (and your colleague) by email; did it get stuck in a spam filter perhaps?

@JHarrisGTI
Copy link

@Snuffleupagus I got your email about the PR yesterday; I believe Adam has emailed you about payment details. I also reached out to our IT department and they say you shouldn't get stuck in the spam filter again. 🙂

@Elecash
Copy link

Elecash commented May 30, 2024

@JHarrisGTI could you throw some light about how to use PDFJS v4.3.136 with Angular?

@Elecash
Copy link

Elecash commented Jun 3, 2024

I've been able to make it work but I have to set the worker in an external cdn or I have to copy/paste the worker file to /assets.

import * as PDFJS from 'pdfjs-dist';

Promise.all([
            // @ts-ignore: only accepted in commonJs or esNext
            import(/* webpackChunkName: "PDFJS" */ 'pdfjs-dist/build/pdf.min.mjs')
        ]).then(() => {
            PDFJS.GlobalWorkerOptions.workerSrc = 'assets/pdf.worker.min.mjs';
            // Alternatively, load from externalcdn
            // PDFJS.GlobalWorkerOptions.workerSrc = '//unpkg.com/pdfjs-dist@4.3.136/build/pdf.worker.min.mjs';
        });

@JHarrisGTI
Copy link

@Elecash Here are some notes I've pulled together from my git commit history over the last few days.

Switch to the legacy build

Since 4.1.392, pdf.js uses Promise.withResolvers; I haven't been able to get that working with any of Angular's build systems. So to get pdf.js 4.3.136 working in Angular, the main thing I've needed to do has been to switch to the legacy build. To do this, replace:

import { whatever } from 'pdfjs-dist'`

with:

import { whatever } from 'pdfjs-dist/legacy/build/pdf.mjs'

That's fixed most of my problems. The builder I'm using is @angular-devkit/build-angular:browser (that goes in angular.json under architect -> build -> builder and architect -> serve -> builder). (With the removal of top-level await I no longer need the custom-webpack builder I'd previously been using. This is great--it brings me closer to the Angular mainstream.)

Worker threads

In cases where I need the performance of a separate worker thread, I add this to the architect -> build -> options -> assets array of angular.json:

{
  "glob": "pdf.worker.min.mjs",
  "input": "./node_modules/pdfjs-dist/legacy/build",
  "output": "./assets"
}

This copies pdf.worker.min.mjs from the node_modules folder into the assets folder of my compiled app. Then, in the place I need the worker:

import * as pdfJsLib from 'pdfjs-dist/legacy/build/pdf.mjs';
pdfJsLib.GlobalWorkerOptions.workerSrc = 'assets/pdf.worker.min.mjs';

const pdf = await pdfJsLib.getDocument({ url }).promise;

Text layers

The renderTextLayer function is deprecated now. Replace:

renderTextLayer({ textContentSource, viewport, container });

with:

new TextLayer({ textContentSource, viewport, container}).render();

And if you're using this library's CSS, the new version sets the z-index of .textLayer to 0. You may want to override that to 1, or whatever fits the rest of your app.

Testing with Jest

I test my app with Jest. Things I did this patch:

  • To prevent "Error: Failed to get canvas 2D context. PDF rendering aborted", npm install jest-canvas-mock
    • In the "jest" object of package.json, add "setupFiles": ["jest-canvas-mock"] and "globalSetup": "jest-preset-angular/global-setup"
  • The strategy described in "Worker threads" above doesn't work in Jest--the tests crash. Wrap the getDocument() call in a try/catch block to get around this.

@Elecash
Copy link

Elecash commented Jun 10, 2024

@JHarrisGTI this is very similar to what I did, but thanks for sharing!

@MikeDabrowski
Copy link

image Can we do something about this?

@Snuffleupagus
Copy link
Collaborator

image Can we do something about this?

First of all, as a general rule, please always provide log output, error messages, and code as text since it's impossible to e.g. copy and search in an image which makes things more cumbersome.
Secondly, what you're asking about seems pretty orthogonal to this issue which was about top level await (and that's been fixed).

@MikeDabrowski If we attempt to work-around your issue, in the way the error message suggests, are you willing to sponsor me for writing the patch?

@MikeDabrowski
Copy link

MikeDabrowski commented Jun 14, 2024

@Snuffleupagus I meant 'we' as we the end users of this library. Sorry for the screenshot, here's the text

Application bundle generation complete. [1.561 seconds]
Watch mode enabled. Watching for file changes...
NOTE: Raw file sizes do not reflect development server per-request transformations.
  ➜  Local:   http://localhost:4200/
  ➜  press h + enter to show help
4:00:05 PM [vite] warning: 
/Users/mike/IdeaProjects/my-project/.angular/cache/18.0.3/vite/deps/pdfjs-dist_legacy_build_pdf__mjs.js
15695|          const worker = yield import(
15696|            /*webpackIgnore: true*/
15697|            this.workerSrc
   |            ^^^^^^^^^^^^^^
15698|          );
15699|          return worker.WorkerMessageHandler;
The above dynamic import cannot be analyzed by Vite.
See https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations for supported dynamic import formats. If this is intended to be left as-is, you can use the /* @vite-ignore */ comment inside the import() call to suppress this warning.
  Plugin: vite:import-analysis
  File: /Users/mike/IdeaProjects/my-project/.angular/cache/18.0.3/vite/deps/pdfjs-dist_legacy_build_pdf__mjs.js?v=c9270bac
No output file changes.

Are you certain that this warning was not caused by the work that was recently carried out here to enable the library in latest Angular?

Maybe I am the only one affected and maybe only my setup is broken.

@Viet47
Copy link

Viet47 commented Jun 17, 2024

Same problem, Esbuild of angular doesn't support dynamic-import of webpack

@JHarrisGTI
Copy link

JHarrisGTI commented Jun 17, 2024

I see the same problem @MikeDabrowski reports when I try to use browser-esbuild, Angular's new Vite-based build system, so for now I am avoiding that system and sticking with the browser build system. That's not much help to people who are starting new Angular apps, which use browser-esbuild by default.

Unrelated to Angular, to make the new version work in my NestJS backend, here's what I changed in tsconfig.json:

{
  "compilerOptions": {
    "module": "Node16",
    "moduleResolution": "Node16",
  }
}

@malek-itani
Copy link

malek-itani commented Jul 9, 2024

this worked for me, using angular@18 & pdfjs-dist@4

package.json

  "dependencies": {
    "@angular/animations": "^18.0.0",
    "@angular/common": "^18.0.0",
    "@angular/compiler": "^18.0.0",
    "@angular/core": "^18.0.0",
    "@angular/forms": "^18.0.0",
    "@angular/platform-browser": "^18.0.0",
    "@angular/router": "^18.0.0",
    "pdfjs-dist": "^4.4.168",
    "rxjs": "^7.8.1",
    "tslib": "^2.5.0",
    "zone.js": "~0.14.0"
  },

PDF Render Component

import { Component, ElementRef, ViewChild } from '@angular/core';
import * as pdfjsLib from 'pdfjs-dist/legacy/build/pdf.mjs';
import 'pdfjs-dist/webpack';
import { PDF_BASE64 } from '../utils/pdf-base64';

@Component({
  selector: 'app-pdf-render',
  standalone: true,
  template: `
    <p>My PDF:</p>
    <p>
      <canvas #myCanvas></canvas>
    </p>
  `,
})
export class PDFrender {
  @ViewChild('myCanvas', { static: false }) canvas!: ElementRef;

  constructor() {
    // you can use direct URL to file
    var url =
      'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/examples/learning/helloworld.pdf';

    // OR you can use PDF as Base64-encoded data
    let pdfData = atob(PDF_BASE64);
    console.log(pdfjsLib.version);
    //
    // The workerSrc property shall be specified.
    //
    pdfjsLib.GlobalWorkerOptions.workerSrc = `//cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjsLib.version}/build/pdf.worker.mjs`;
    //
    // Asynchronous download PDF
    //
    var loadingTask = pdfjsLib.getDocument({ data: pdfData });
    loadingTask.promise.then((pdf) => {
      //
      // Fetch the first page
      //
      pdf.getPage(1).then((page) => {
        var scale = 1.5;
        var viewport = page.getViewport({ scale: scale });

        //
        // Prepare canvas using PDF page dimensions
        //
        var context = this.canvas.nativeElement.getContext('2d');
        this.canvas.nativeElement.height = viewport.height;
        this.canvas.nativeElement.width = viewport.width;

        //
        // Render PDF page into canvas context
        //
        var renderContext = {
          canvasContext: context,
          viewport: viewport,
        };
        page.render(renderContext);
      });
    });
  }
}

thanks to JHarrisGTI for pointing out how to use the legacy import.

@MikeDabrowski
Copy link

MikeDabrowski commented Jul 9, 2024

@JHarrisGTI

pdfJsLib.GlobalWorkerOptions.workerSrc = 'assets/pdf.worker.min.mjs';

I did that too, my deployed assets contain the worker file but the src like that cant use it.

Error: Setting up fake worker failed: "Failed to resolve module specifier 'assets/pdf.worker.min.mjs'"

Have you seen such error?

Even if I put the full url to this file - the error is Failed to fetch dynamically imported module

@JHarrisGTI
Copy link

@MikeDabrowski I have not seen such an error. ☹️ If pdf.worker.min.mjs is in your assets folder, I don't know why pdf.js would be unable to see it. Sorry I can't be more help.

@MikeDabrowski
Copy link

MikeDabrowski commented Jul 10, 2024 via email

@xander90
Copy link

xander90 commented Aug 2, 2024

@JHarrisGTI

pdfJsLib.GlobalWorkerOptions.workerSrc = 'assets/pdf.worker.min.mjs';

I did that too, my deployed assets contain the worker file but the src like that cant use it.

Error: Setting up fake worker failed: "Failed to resolve module specifier 'assets/pdf.worker.min.mjs'"

Have you seen such error?

Even if I put the full url to this file - the error is Failed to fetch dynamically imported module

This worked for me, using angular@18.1.3 & pdfjs-dist@4.5.136
I get vite's warning when ng serve is running

11:21:03 [vite] warning: 
.../.angular/cache/18.1.3/vite/deps/pdfjs-dist.js
11783|        const worker = yield import(
11784|          /*webpackIgnore: true*/
11785|          this.workerSrc
   |          ^^^^^^^^^^^^^^
11786|        );
11787|        return worker.WorkerMessageHandler;
The above dynamic import cannot be analyzed by Vite.
See https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations for supported dynamic import formats. If this is intended to be left as-is, you can use the /* @vite-ignore */ comment inside the import() call to suppress this warning.

  Plugin: vite:import-analysis
  File: .../.angular/cache/18.1.3/vite/deps/pdfjs-dist.js?v=0c2fc72a

but all work fine

import {getDocument, GlobalWorkerOptions, PDFPageProxy} from "pdfjs-dist";

private async tryToGetPdf(pdfFile: File) {
     GlobalWorkerOptions.workerSrc = 'assets/pdf-worker/build/pdf.worker.min.mjs';
     const arrayBuffer = await pdfFile.arrayBuffer();
     const loadingTask = getDocument(arrayBuffer);
     ....
}

@christianhyltoft
Copy link

I still face the excact same issues as described above and in many other threads. My API version and worker version doesnt match, but whenver i would upgrade or downgrade either the worker or the pdfjs-dist then it is still not resolved.

I have tried to follow along on multiple suggestions and tried countless versions but I still cant seem to get it to work.

This is something that I am trying to do in React, NextJs and TypeScript.

Is there a posibility to get someone to help or perhaps pairprogram it with me since i feel like it is a lost cause...?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment