Mozilla PDF.js V4 開始,它官方分發確實只提供了 ESM 模塊(.mjs),沒有以前的 pdf.js、pdf.worker.js UMD 版本了。
這個問題本質上是 瀏覽器要求以 application/javascript
MIME 類型加載 ES Module,而你引入的 pdf.mjs
文件服務器返回的 Content-Type 不是標準的 JS MIME(通常是 text/html
或者 text/plain
),所以會報:
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html"
先介紹一下.mjs文件
什么是 .mjs 文件?
.mjs(Module JavaScript)是 ECMAScript 模塊的專用文件擴展名,用于明確標識 JavaScript 模塊文件。這是 ES6 模塊系統的標準擴展名。
與普通 .js 文件的主要區別
特性 | .mjs 文件 | 傳統 .js 文件 |
---|---|---|
模塊類型 | ES6 模塊 | 傳統腳本或 CommonJS 模塊 |
嚴格模式 | 默認啟用 | 需要手動啟用 |
頂層 this | undefined | 指向全局對象 |
導入/導出 | 支持 import/export | 需要特定環境支持 |
文件識別 | 明確標識為模塊 | 需要解析內容判斷 |
.mjs 文件的核心特性
1. 明確的模塊標識
// math.mjs
export const add = (a, b) => a + b;
export const multiply = (a, b) => a * b;// 默認導出
export default function calculator() {console.log('Calculator module loaded');
}
2. 導入語法
// app.mjs
import calculator, { add, multiply } from './math.mjs';console.log(add(2, 3)); // 輸出: 5
console.log(multiply(2, 3)); // 輸出: 6
calculator(); // 輸出: Calculator module loaded
3. 動態導入
// 動態導入示例
const loadModule = async () => {const module = await import('./dynamic-module.mjs');module.doSomething();
};
為什么使用 .mjs 擴展名?
優勢:
- 明確性:一眼就能識別出是 ES6 模塊
- 兼容性:避免與 CommonJS 模塊混淆
- 工具支持:構建工具和運行時能夠正確識別模塊類型
- 服務器配置:便于正確設置 MIME 類型
環境支持
支持的運行時:
- Node.js (v12+ 完全支持)
- 現代瀏覽器 (Chrome、Firefox、Safari、Edge)
- Deno (原生支持)
- Bun (原生支持)
Node.js 中的使用:
// package.json 配置
{"type": "module", // 或者使用 .mjs 擴展名"scripts": {"start": "node src/index.mjs"}
}
回歸正題
常見解決方案:
1. 確認服務器返回的 MIME 類型
在服務端配置里,確保 .mjs
文件返回:
Content-Type: application/javascript
- Nginx 配置:
http {types {application/javascript mjs;}
}
- Apache 配置:
AddType application/javascript .mjs
2. 如果你不能改服務器配置
- 把
pdf.mjs
改名為.js
,然后在 HTML 中這樣引入:
<script type="module" src="/path/to/pdf.js"></script>
因為大多數服務器對 .js
都會返回正確的 application/javascript
。
3. 使用構建工具打包
如果你項目里有 Webpack / Vite / Rollup,把 pdf.mjs
作為依賴打包進去,這樣最終生成的都是標準 JS 文件,不會受 MIME 類型影響。
4. 確認引入方式
要用 ES Module 的方式加載:
<script type="module">import * as pdfjsLib from '/path/to/pdf.mjs';// ...
</script>
- 如果是 uniapp 下使用 npm i pdfjs-dist 安裝的 pdfjs,引入方式如下:
import * as pdfjsLib from "pdfjs-dist";
import pdfjsWorker from "pdfjs-dist/build/pdf.worker?url";
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;
- 如果是官網下載的zip包,引入方式如下:
import * as pdfjsLib from "@/static/pdf.mjs";const worker = new Worker(new URL("@/static/pdf.worker.mjs", import.meta.url), { type: "module" });
pdfjsLib.GlobalWorkerOptions.workerPort = worker;
由于我使用的是docker,直接用 cat 命令無法編輯mime.types文件(頁也可以自行安裝 vim 命令)。
這里介紹一下 docker cp 命令。
- 從宿主機復制文件到容器
docker cp ./hello.txt nginx_container:/hello.txt
- 從容器復制文件到宿主機:
docker cp nginx_container:/hello.txt ./hello.txt
- 修改后需要重啟nginx
docker exec nginx_container nginx -s reload
驗證
curl -I https://your-domain.com/file.mjs
返回
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 26 Aug 2025 10:51:28 GMT
Content-Type: application/javascript; charset=utf-8,gbk
Content-Length: 1887718
Connection: keep-alive
Last-Modified: Tue, 26 Aug 2025 03:14:02 GMT
ETag: "68ad267a-1ccde6"
Accept-Ranges: bytes
至此,訪問pdfjs 正常了!😃