如何设计用于导出的打字稿项目

Posted

技术标签:

【中文标题】如何设计用于导出的打字稿项目【英文标题】:How to design a typescript project for export 【发布时间】:2018-06-21 11:13:45 【问题描述】:

我很抱歉,因为我是 js 生态系统的新手。我在一个使用打字稿的地方工作,这很棒,因为它帮助我摆脱了静态语言的背景。但是我仍然不了解包装/模块系统,尤其是与打字稿定义结合使用。

我正在编写一个模块,其中包含一组描述 Web 服务 API 合同的接口,供客户端库和 API 服务本身使用。如果这是 C#/Java 或其他东西,我会编写我的接口文件,将其打包、发布,然后通过说来使用它

import GetWizardsResponse from StuffInc.Contract.Wizards

这就是我使用打字稿库的方式,所以我写了

export interface GetWizardsResponse 
    wizards: Wizard
    currentPage: number
    count: number

然后在我的ts.config 中我有"declaration": true 所以在tsc 之后我得到Wizards.d.tsWizards.js。当我 npm publish 这个时,我必须通过执行以下操作来消耗它:

import GetWizardsResponse from '@StuffInc/contracts/Wizards'

但是当我环顾四周时,更常见的是看到这样的导入:

import * as Express from 'express'

import Response, NextFunction from 'express'

所以我使用我的包应该是这样的:

import GetWizardsResponse from '@StuffInc/contracts

这样我可以拥有/wizards/goblins/elves,但导入始终来自“来自@StuffInc/contracts”。这就是我所做的(这就是我应该做的对吗?所有的 NPM 包都是这样的)

为此,我认为我需要将所有内容放在一个 index.d.ts 文件中。我是否仍然可以在逻辑单独的文件中编写我的代码,但将其构建到一个定义中,以便其他开发人员的猜测工作更少?

【问题讨论】:

我在使用export default xxx 时没有得到任何提示,但export xxx 工作正常。不知道为什么,估计是bug,反正TS里别用export default 我不太确定您遇到了什么问题,但我不禁注意到您在 .ts 示例中的任何地方都没有使用任何 ;,我肯定会导致大量错误。例如,界面应该看起来像export interface GetWizardsResponse wizards: Wizard, currentPage: number, count: number ,在每个界面之间使用逗号。然后是你的导入,它应该看起来像import GetWizardsResponse from '@StuffInc/contracts/Wizards';,最后使用;。如果您可以更具体地了解您正在做什么并显示Wizards 的代码,我可能会提供帮助。 @Optiq 对不起,是的,你是对的。我只是徒手写了代码。我的真实代码更无聊,所以我特意使用了一些奇特的例子来确保重点放在问题上。虽然 out 项目不使用 ; 并且如果您使用它们,linter 会抱怨。显然它们是可选的。这是我对这种语言感到困惑的众多原因之一,有多种做事方式非常有趣 【参考方案1】:

你已经很接近了,唯一想要获得漂亮名字的东西就是带有export * from '@StuffInc/contracts/Wizards'的index.ts

诀窍是您可以从不同的文件中多次导出某些内容。 像 webpack 这样的模块加载器会知道寻找以您的项目命名的 index.d.ts 或 .d.ts(moment has a moment.d.ts)。

现在 js/ts 中的模块有点复杂,但是随着 es6 模块变得越来越正常,它变得越来越好。还有一些叫做默认导出的东西,它们允许import package from 'package' 语法。像 Moment 这样具有全局命名空间的工具应该使用它,它也允许命名导入。 import moment, Duration from 'moment'。不过,没有多少模块使用默认值,所以你不能像那行一样从那一刻开始导入。你必须这样做import * as moment from 'moment'。如果它们具有声明的命名空间而不是显式的导出/默认值,您将看到这一点。我的观点是,如果可以的话,你想远离 * 导入,你将不得不使用它们来导入一个没有设置它们的节点模块,但是通过显式导入模块捆绑器可以使你的包变得更小,使用诸如摇树之类的技术和代码拆分。

这是对我迄今为止能够弄清楚的内容的快速复习,但我会对模块进行更多研究。

【讨论】:

感谢您提供详细的概述。所以我的目标应该是在我的模块的根目录中有import Wizard from 'myModule' be possible to module clients can be more efficient? Makes sense. To do that I need an index.d.ts`,它以某种方式指向\wizards或其他任何文件? 是的。有一些工具可以生成定义文件,所以如果你使用 webpack,大多数 ts 加载器都有输出定义文件的选项。 tsc 还有一个 --declaration 标志,它将生成 .d.ts 文件。

以上是关于如何设计用于导出的打字稿项目的主要内容,如果未能解决你的问题,请参考以下文章

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

打字稿:SyntaxError:意外的令牌“导出”

从打字稿中的索引文件导出JSON文件

用于服务器端渲染的 create-react-app 打字稿

带有打字稿的角度材料设计

如何在 React Native 项目中将 JS 库导入打字稿