如何让 TypeScript 以生成工作 Node.JS 代码的方式加载 PDF.js NPM 模块和 @types 绑定?

Posted

技术标签:

【中文标题】如何让 TypeScript 以生成工作 Node.JS 代码的方式加载 PDF.js NPM 模块和 @types 绑定?【英文标题】:How can I get TypeScript to load the PDF.js NPM module and @types bindings in a way that generates working Node.JS code? 【发布时间】:2018-03-26 02:36:18 【问题描述】:

上下文

我正在尝试将 PDF.JS 导入 TypeScript 项目。我正在为pdfjs-dist 使用DefinitelyTyped bindings,通过npm install @types/pdfjs-distnpm install pdfjs-dist 安装。

问题

我似乎无法让 TypeScript 编译我的项目。我正在使用直接从DefiniteTyped 上的测试中复制的源代码。这是我正在尝试编译的简化(仅删除)代码(DefinitelyTyped 的测试代码的精确副本也以同样的方式失败):

import  PDFJSStatic  from 'pdfjs-dist';
var PDFJS: PDFJSStatic;
PDFJS.getDocument('helloworld.pdf').then(console.log);

TypeScript 找到类型声明模块,并认为PDFJSStatic 的导入是有效的。它认为PDFJS 从未被初始化,但如果我在tsconfig 中关闭strict,代码会编译,但它会编译为:

"use strict";
exports.__esModule = true;
var PDFJS;
PDFJS.getDocument('helloworld.pdf').then(console.log);

这显然行不通。它不会将import 语句编译成任何东西。

问题

如何将 PDF.JS 导入 TypeScript 项目并通过 @types/pdfjs-dist 中的声明文件将其编译为工作 Node.JS 代码?

我的尝试

我在import 上尝试了不同的变体,但无济于事。切换到require 似乎也没有帮助。

我已验证 pdjs-dist 依赖项和 @types/pdfjs-dist 依赖项存在、已更新并且可直接从 NodeJS(非 TypeScript 程序)使用。

我在 tsconfig 中尝试了 module 的各种值。他们有时会更改生成的代码,但没有人会更改它以包含所需的导入。

我尝试在import 行上方添加/// <reference path="../node_modules/@types/pdfjs-dist/index.d.ts" />。这并没有改变行为。

环境

tsc 版本 2.4.2,节点 8.5 和 npm 5.3。我的项目根目录中有以下tsconfig.json


    "compilerOptions": 
        "allowJs":true,
        "rootDir": ".",
        "outDir": "dist",
        "moduleResolution": "node"
    ,
     "include": [
        "src/**/*"
    ],
    "exclude": [
        "**/*.spec.ts",
        "dist/**/*"
    ]

【问题讨论】:

@Azoson 的回答是一个很好的解决方法,可以解决破碎的打字问题。如果我很快有空闲时间,我会尝试向 PDFJS 库提交一个补丁来解决这个问题。不过,我不是这个库或 TypeScript 的专家,所以这可能很难。 【参考方案1】:

如果你碰巧在使用 React,你可以使用 react-pdf 包,它在后台使用 pdfjs。它也有自己的类型,所以你可以在不需要require 的情况下导入它。

【讨论】:

【参考方案2】:

对于@types/pdfjs-dist 2.1.0 和pdfjs-dist "2.1.266",基本问题似乎还没有完全解决,但我发现their own test 的方法有效:

import  getDocument, PDFDocumentProxy, PDFPromise, Util  from 'pdfjs-dist';

(但它并不漂亮,因为它会污染你的命名空间。)

【讨论】:

【参考方案3】:

这对我有用,无需使用require

import * as pdfjslib from "pdfjs-dist";
const PDFJS = (<any>pdfjslib) as PDFJSStatic;

您只需将模块强制转换为 any 以消除类型错误。

@types/pdfjs-dist 中的类型肯定不正确,但这应该是一个快速的解决方法。 :)

【讨论】:

【参考方案4】:

也许你可以使用require函数。

添加@types/node 包,并在源代码顶部写require('pdfjs-dist')。 所以,你可以像下面这样修改你的代码。

现在,这段代码可以工作了。

import  PDFJSStatic  from 'pdfjs-dist';
const PDFJS: PDFJSStatic = require('pdfjs-dist');
PDFJS.getDocument('helloworld.pdf').then(console.log);

我认为@types/pdfjs-dist在实现上存在问题。

【讨论】:

现在,这个方法行不通了。请看@types/nodegithub.com/DefinitelyTyped/DefinitelyTyped/commit/…的这个变化 现在,这段代码可以工作了。从'pdfjs-dist'导入 PDFJSStatic;常量 PDFJS: PDFJSStatic = require('pdfjs-dist'); PDFJS.getDocument('helloworld.pdf').then(console.log);我认为@types/pdfjs-dist在实现上存在问题。【参考方案5】:

我也尝试了不同的方法。对我来说,最易读的是这个:

import * as pdfjslib from 'pdfjs-dist';
let PDFJS = pdfjslib.PDFJS;
PDFJS.disableTextLayer = true;
PDFJS.disableWorker = true;

【讨论】:

这不起作用。我得到cannot use namespace 'pdfjslib' as a value.

以上是关于如何让 TypeScript 以生成工作 Node.JS 代码的方式加载 PDF.js NPM 模块和 @types 绑定?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Webpack 和 Typescript 使用外部 node_module 文件夹?

如何使用 Node 和 TypeScript 获取异步堆栈跟踪?

Node + TypeScript:“this”隐含类型“any”

生成 SSL 密钥以使用 node.js

TypeScript导入路径别名

试图让 Cypress、TypeScript 和 IstanbulJS 一起工作