转译pdfjs-dist模块时对象未初始化致VS Code扩展报错
VS Code扩展打包.vsix后pdfjs-dist模块无法正常使用的问题
我开发了一款提取PDF文本的VS Code扩展,开发阶段运行正常,但导出为.vsix后出现异常。排查后发现VS Code作为Electron应用不支持pdfjs-dist的.mjs格式,于是用babel-loader转译该模块,但转译后部分对象未初始化——比如原/node_modules/pdfjs-dist/build/pdf.mjs里的GlobalWorkerOptions初始化代码没有出现在转译后的pdfjs.bundle.js中。
使用转译后的模块时,执行以下代码:
const pdfjsLib = await import('../dist/pdfjs.bundle.js'); pdfjsLib.GlobalWorkerOptions.workerSrc = "pdfjs-dist/build/pdf.worker.mjs"; const pdfData = new Uint8Array(fs.readFileSync(pdfPath)); const pdfDocument = await pdfjsLib.getDocument({ data: pdfData }).promise;
会报TypeError: Cannot set properties of undefined (setting 'workerSrc');注释掉设置workerSrc的代码后,又报TypeError: pdfjsLib.getDocument is not a function。
相关配置代码
包装脚本./src/pdfjsWrapper.js
import 'pdfjs-dist'; export default pdfjs-dist;
webpack.config.js
const path = require('path'); module.exports = { mode: 'development', target: 'node', // for VS Code extensions entry: { pdfjs:'./src/pdfjsWrapper.js' }, output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist'), library: { name: 'pdfjsLib', type: 'umd', // Universal Module Definition }, libraryTarget: 'commonjs2' }, module: { rules: [ { test: /\.m?js$/, exclude: (modulePath) => { // Exclude 'vscode' module if (modulePath.includes('node_modules/vscode')) { return true; } // Exclude 'fs' module if (modulePath.includes('node_modules/fs')) { return true; } // Exclude 'weaviate-ts-client' module if (modulePath.includes('node_modules/weaviate-ts-client')) { return true; } // Include all other modules return false; }, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], compact: false // to have optimised code } } } ] } };
.babelrc
{ "presets": ["@babel/preset-env"] }
解决思路与步骤
- 修正包装脚本的导出逻辑
原包装脚本仅导入pdfjs-dist但未正确导出模块内容,导致转译后无法获取API。修改pdfjsWrapper.js:
import * as pdfjsLib from 'pdfjs-dist'; export default pdfjsLib;
- 调整Webpack配置,确保模块正确导出
- 移除重复的
libraryTarget配置(library.type已指定为umd,无需重复设置) - 为.mjs文件添加路径解析配置,解决ES模块导入匹配问题
- 明确babel的目标环境为当前Node.js版本,避免转译过度:
module.exports = { mode: 'development', target: 'node', entry: { pdfjs:'./src/pdfjsWrapper.js' }, output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist'), library: { name: 'pdfjsLib', type: 'umd', } }, module: { rules: [ { test: /\.m?js$/, resolve: { fullySpecified: false }, exclude: (modulePath) => { return modulePath.includes('node_modules/vscode') || modulePath.includes('node_modules/fs') || modulePath.includes('node_modules/weaviate-ts-client'); }, use: { loader: 'babel-loader', options: { presets: [['@babel/preset-env', { targets: { node: 'current' } }]], compact: false } } } ] } };
- 处理PDF Worker适配问题
VS Code扩展环境下使用Worker需注意:
- 若仅需提取文本,可直接禁用Worker避免加载问题:
const pdfDocument = await pdfjsLib.getDocument({ data: pdfData, disableWorker: true }).promise;
- 若必须使用Worker,需将
pdf.worker.mjs也打包进扩展,然后修改workerSrc指向打包后的本地文件路径。
- 修正模块导入方式
根据扩展的模块系统选择合适的导入方式:
// CommonJS环境 const pdfjsLib = require('../dist/pdfjs.bundle.js'); // ES模块环境 import pdfjsLib from '../dist/pdfjs.bundle.js';
内容的提问来源于stack exchange,提问作者yohoo
相关产品推荐
相关产品推荐

