PDF.js とは PDF を JavaScript で扱うためのフレームワークです。
選択した PDF ファイルを Javascript 上で png に変換してアップロードする、ということをやりたかったので、このフレームワークを選択しました。
が、セットアップにだいぶ苦労したので、書き留めておきます。
自分の環境
主な構成情報は以下です。
- サーバー側
- Rails (7.0.1)
- react_on_rails (12.5.2)
- webpacker (5.4.3)
- クライアント側
- react@17.0.2
- typescript@4.5.5
- webpack@4.46.0
ただの Javascript で使うだけなら、苦労しないでしょうが、
Typescript と webpacker の環境だとちょっと苦労しました (後述)。
インストール方法
インストールは、Wiki にあるように pdfjs-dist を npm install します。
npm install pdfjs-dist
これは簡単!
ローディング
Typescript から読み込んで使いたいのですが、
ダメだったやつ
npm の例 に従って書いたら、
const pdfjsLib = require("pdfjs-dist/legacy/build/pdf.js");
エラーが出ます
。
Deprecated API usage: No "GlobalWorkerOptions.workerSrc" specified.
うごいたけど Warning でたやつ
workSrc を指定せよ、というメッセージだったので、pdfjs-dist/legacy/build/pdf.worker.entry を workerSrc に指定したら、
import * as pdfjs from 'pdfjs-dist/legacy/build/pdf';
import * as pdfjsWorker from 'pdfjs-dist/legacy/build/pdf.worker.entry';
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;
動きました!
が、コンソールに Warning が出ます
。
Warning: Setting up fake worker.
うまくいったやつ
どうも worker を立てた方がよさそうなので、worker-loader を npm install 。
npm install worker-loader
そして、pdfjs-dist/legacy/build/pdf.worker.js をもとにした worker-loader を立てます。
import * as pdfjs from 'pdfjs-dist/legacy/build/pdf';
const PdfjsWorker = require("worker-loader?esModule=false&filename=[name].[contenthash].js!pdfjs-dist/legacy/build/pdf.worker.js");
pdfjs.GlobalWorkerOptions.workerPort = new PdfjsWorker();
これで Warning が出ることなく、動きました!
。
webpack5 であれば
今回は webpack 4.46 でしたが、webpack 5 であれば、import.meta.url が使えるので、work-loader を使わずにできるようです
(試してないけど)。
import * as pdfjs from 'pdfjs-dist/legacy/build/pdf';
pdfjsLib.GlobalWorkerOptions.workerPort =
new Worker(new URL("pdfjs-dist/legacy/build/pdf.worker.js", import.meta.url));
なんか別の Warning が出てるんだけど。。。
Warning: TT: undefined function: 3
という Warning が出ますが、これは問題なさそう
。
その他 ダメだったやつ
webpack 向けのものを使う
webpack の例 では、以下のように書かれていますが、
import * as pdfjsLib from 'pdfjs-dist/webpack';
TypeError が出ます
。
Uncaught TypeError: root is undefined
どうも webpacker 側の問題みたいです。
回避策が示されていますが、回避策を実施しても、
./node_modules/pdfjs-dist/build/pdf.js 1387:9
Module parse failed: Unexpected character '#' (1387:9)
とエラーになったので諦めました
。
legacy ではないものを使う
legacy (pdfjs-dist/legacy/build/pdf) ではない通常のパスをしたいところですが、
import * as pdfjs from 'pdfjs-dist/build/pdf'
このパスには Typescript がないので、not found になります
。
"export 'getDocument' (imported as 'pdfjs') was not found in 'pdfjs-dist/build/pdf’
参考