解决 pdf.mjs 因 MIME 类型错误导致的模块加载失败问题

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. 明确的模块标识

javascript 复制代码
// 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. 导入语法

javascript 复制代码
// 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. 动态导入

javascript 复制代码
// 动态导入示例
const loadModule = async () => {
  const module = await import('./dynamic-module.mjs');
  module.doSomething();
};

为什么使用 .mjs 扩展名?

优势:

  1. 明确性:一眼就能识别出是 ES6 模块
  2. 兼容性:避免与 CommonJS 模块混淆
  3. 工具支持:构建工具和运行时能够正确识别模块类型
  4. 服务器配置:便于正确设置 MIME 类型

环境支持

支持的运行时:

  1. Node.js (v12+ 完全支持)
  2. 现代浏览器 (Chrome、Firefox、Safari、Edge)
  3. Deno (原生支持)
  4. Bun (原生支持)

Node.js 中的使用:

javascript 复制代码
// package.json 配置
{
  "type": "module", // 或者使用 .mjs 扩展名
  "scripts": {
    "start": "node src/index.mjs"
  }
}

回归正题

常见解决方案:

1. 确认服务器返回的 MIME 类型

在服务端配置里,确保 .mjs 文件返回:

复制代码
Content-Type: application/javascript
  • Nginx 配置:
nginx 复制代码
http {
    types {
        application/javascript  mjs;
    }
}
  • Apache 配置:
apache 复制代码
AddType application/javascript .mjs

2. 如果你不能改服务器配置
  • pdf.mjs 改名为 .js,然后在 HTML 中这样引入:
html 复制代码
<script type="module" src="/path/to/pdf.js"></script>

因为大多数服务器对 .js 都会返回正确的 application/javascript


3. 使用构建工具打包

如果你项目里有 Webpack / Vite / Rollup,把 pdf.mjs 作为依赖打包进去,这样最终生成的都是标准 JS 文件,不会受 MIME 类型影响。


4. 确认引入方式

要用 ES Module 的方式加载:

html 复制代码
<script type="module">
  import * as pdfjsLib from '/path/to/pdf.mjs';
  // ...
</script>

  1. 如果是 uniapp 下使用 npm i pdfjs-dist 安装的 pdfjs,引入方式如下:
javascript 复制代码
import * as pdfjsLib from "pdfjs-dist";
import pdfjsWorker from "pdfjs-dist/build/pdf.worker?url";
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;
  1. 如果是官网下载的zip包,引入方式如下:
javascript 复制代码
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 命令。

  • 从宿主机复制文件到容器
bash 复制代码
docker cp ./hello.txt nginx_container:/hello.txt
  • 从容器复制文件到宿主机:
bash 复制代码
docker cp nginx_container:/hello.txt ./hello.txt
  • 修改后需要重启nginx
bash 复制代码
docker exec nginx_container nginx -s reload

验证

bash 复制代码
curl -I https://your-domain.com/file.mjs

返回

bash 复制代码
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 正常了!😃

相关推荐
两个西柚呀2 天前
es6和commonjs模块化规范的深入理解
前端·javascript·es6
小小鸟0083 天前
JS(ES6+)基础
javascript·es6
代码or搬砖6 天前
ES6新增的新特性以及用法
前端·javascript·es6
Tiam-20169 天前
安装NVM管理多版本node
vue.js·前端框架·node.js·html·es6·angular.js
蜗牛攻城狮10 天前
ES6 Module 导入导出完全指南:语法、原理与最佳实践
前端·ecmascript·es6
lcc18711 天前
ES6 生成器函数
es6
aeoliancrazy12 天前
es6迭代器(Iterator的使用),遇到的问题理解,数组属性相关的一点小细节
前端·javascript·es6
还是大剑师兰特12 天前
ES6 class相关内容详解
es6·原型模式·大剑师
lcc18712 天前
ES6 Symbol
es6
m0_4711996313 天前
【JavaScript】Set 和 Map 核心区别与实战用法(ES6 集合全解析)
前端·javascript·es6