如何为用打字稿编写的 npm 包指向索引文件

Posted

技术标签:

【中文标题】如何为用打字稿编写的 npm 包指向索引文件【英文标题】:How to point index file for npm package written in typescript 【发布时间】:2020-01-19 09:58:17 【问题描述】:

我有一个用打字稿写的包。主模块位于src,称为Popover.ts。主索引文件称为index.jspackage.json 中的main 字段指向该文件。它有这样的内容:

exports.Popover = require('./src/js/Popover');

然后我尝试在另一个包中包含这个插件。我用 npm 安装了它。问题来了。在 javascript 中一切正常:

const Popover = require('popover');

但是当我尝试将它导入打字稿文件(demo.ts)时它不起作用:

import Popover from 'popover';

首先,phpStorm 用红线突出显示popover,并显示Can not find module 'popover'。其次,当我使用 webpack 构建演示时,我没有收到任何错误,但是构建文件不包含 Popover.ts 的内容。

我不明白为什么会发生这种情况以及如何解决它。

更新:通过在tsconfig.json 中设置"moduleResolution": "node"(感谢@user254694),我设法摆脱了PhpStorm 中的红色突出显示。但是后来我遇到了一个不同的问题:构建失败。 Webpack 产生了这样的错误:

Error: TypeScript emitted no output for 
F:\dev\js\plugins\popover\demo\npm\node_modules\popover\src\js\Popover.ts. 
By default, ts-loader will not compile .ts files in node_modules.

我用谷歌搜索了这个错误并得出了以下解决方案。将allowTsInNodeModules 选项添加到ts-loader

loader: 'ts-loader',
options: 
   allowTsInNodeModules: true

然后我在tsconfig.js中添加了这样的行:

"include": [
    "node_modules/popover/src/**/*",
    "node_modules/popover/index.js",
    "node_modules/popover/typings/**/*"
  ]

虽然这消除了 webpack 错误并成功编译,但我再次得到红色突出显示。

PS:我在typings 目录中生成了声明类型,现在我的package.json 看起来像这样:

"main": "index.js",
"types": "typings/index.d.ts",

仍然想知道如何使它工作。

【问题讨论】:

我假设当你导入它时,它期望 popover.ts 中的结构类似于以下“export const Popover ...rest of function 或其他”,但听起来你需要 commonjs 格式- 你可能想读这个***.com/questions/46677752/… @user254694 查看我的更新 【参考方案1】:

您的包裹还应包含index.d.ts。并且您的 package.json 应该有指向该文件的 types 字段。这将允许从打字稿中的node_modules 导入包。

index.d.ts 由 TypeScript 编译器与 index.js 一起在 --declataion 编译器选项打开时生成。默认情况下它是关闭的,如果你要使用npm发布你的包,你应该将它添加到tsconfig.json文件(或命令行)中。

当我使用 webpack 构建演示时,我没有收到任何错误,但是构建文件不包含 Popover.ts 的内容

这可能是一个单独的问题。如果您实际上没有在您的打字稿文件中使用导入的Popover,the compiler will not generate require call for that module 作为优化,所以Popover.js 不会包含在包中。如果您使用导入的值,它会使用 TypeScript 编译而不会出错,但生成的 javascript 仍然无法正常工作,但直接从 javascript 使用该模块可以工作 - 这很不寻常,需要更多信息才能解决。

【讨论】:

查看我的更新。我添加了生成的类型并将它们添加到 package.json webpack 应该为您的popover 包使用来自node_modules 的已编译.js 文件,就像它对来自node_modules 的所有其他包一样。这些.js 文件应该在popover 包中作为构建步骤单独编译,然后再将其发布到npm 上。你必须弄清楚为什么 webpack 会尝试从 node_modules 加载和编译 typescript 文件——这不是正常的工作方式。 为什么不是正常的方式。我需要它——这就是它需要它的原因。整个问题都围绕着这个问题。我需要popover 包,其中有main 字段作为index.js,但index.js 只是导出导入的Popover.ts。再次阅读我的问题。 我的意思是,require 应该让 webpack 添加已经编译好的.js 文件。当您将popover 作为外部模块使用时,从该模块编译.ts 文件是不正常的。所以,index.js 应该导出编译后的Popover.js,而不是.ts 我没有Popover.js,我只有Popover.ts。这就是诀窍。我的包是用打字稿写的。

以上是关于如何为用打字稿编写的 npm 包指向索引文件的主要内容,如果未能解决你的问题,请参考以下文章

打字稿:如何为图像自动生成 d.ts 文件

在打字稿进口NPM包

如何将打字稿定义文件添加到 npm 包中?

如何为 react-native 本机 ui 组件创建打字稿类型定义?

我应该在部署之前构建一个打字稿 npm 模块吗?

在打字稿库项目中组织 NPM 模块导出的最佳实践?