shadow-cljs

filipkon 2025-12-08T16:37:05.636769Z

Can someone help me understand how the web-worker works in the release mode? I have the following demo.pdfjs_worker file for loading the worker of the pdfj-dist library with the worker module of shadow-cljs.edn, while the pdf_viewer ns sets the workerSrc with the generated worker.js file. This works in dev mode, but in the release mode I get the following error when trying to render the pdf-viewer and the worker has not started.

pdfjs-worker.js:1 Uncaught ReferenceError: importScripts is not defined
    at pdfjs-worker.js:1:1
According to the documentation, "Worker generation happens in both development and release modes" so I'm not sure what I'm doing wrong here. Tested with shadow-cljs: "3.2.1"/"3.3.3" and "pdfjs-dist": "2.16.105" • shadow-cljs.edn
{:app
  {:target  :browser
   :modules  {:shared       {:entries []}
              :main         {:init-fn    demo.core/init
                             :depends-on #{:shared}}
              :pdfjs-worker {:entries    [demo.pdfjs-worker]
                             :depends-on #{:shared}
                             :web-worker true}}
• demo.pdfjs_worker (`pdfjs-worker` worder module)
(ns demo.pdfjs-worker
  (:require ["pdfjs-dist/lib/core/worker.js"]))
• pdf_viewer.cljs (`main` module)
(ns demo.pdf-viewer
  (:require ["pdfjs-dist/legacy/build/pdf.min.js" :as pdfjs]))

(set! (.. pdfjs -GlobalWorkerOptions -workerSrc) "./js/compiled/pdfjs-worker.js")

(defn pdf-preview-component [_] ...)

thheller 2025-12-09T06:49:28.469059Z

looks fine to me. importScripts is a built-in for workers, so it should definitely be available. unless maybe the worker is loaded as a ESM module? haven't looked at pdfjs in a long time

thheller 2025-12-09T06:50:19.425889Z

can you setup a repro so I can check?

thheller 2025-12-09T06:52:51.230609Z

did a quick check and indeed it loads it as a module now

thheller 2025-12-09T06:52:52.947469Z

const worker = new Worker(workerSrc, {
        type: "module"
      });

thheller 2025-12-09T06:53:11.141039Z

so basically you just need to switch your build to use :target :esm

thheller 2025-12-09T06:53:31.315979Z

{:app
 {:target  :esm
  :modules  {:shared       {:entries []}
             :main         {:init-fn    demo.core/init
                            :depends-on #{:shared}}
             :pdfjs-worker {:entries    [demo.pdfjs-worker]
                            :depends-on #{:shared}}}

thheller 2025-12-09T06:53:48.749289Z

and the script tag that includes the main.js in your html needs to add type="module"

thheller 2025-12-09T06:53:53.509109Z

that should be it

filipkon 2025-12-10T14:43:47.981549Z

Thanks for the reply @thheller! I appreciate the time you took to look at this. Unfortunately, I did not manage to get it working using the :esm target as it caused other issues in the application. I did manage to make it work though by bundling the original worker.js file from the pdf-js lib with the rest of the asset files.