如何在没有“dist”的情况下在 NPM 上发布 TypeScript 模块?

Posted

技术标签:

【中文标题】如何在没有“dist”的情况下在 NPM 上发布 TypeScript 模块?【英文标题】:How to publish TypeScript modules on NPM without "dist" in import? 【发布时间】:2018-09-26 05:51:05 【问题描述】:

我正在尝试在 NPM 上发布一个打字稿库,但发布后我无法找到“好的”路径。

我在这一点上遵循了几个指南,但我没有找到解决方案。

问题:所以,考虑以下结构:

dist
 |- Alls files generated after tsc build
lib
 |- All TS files of library (source)
CHANGELOG.md
LICENSE
package.json
README.md
tsconfig.json

发布后,例如在 Angular 应用程序中,我将输入:

import Component from '<library name>/dist/Component';

我的问题:如何将项目导入配置为 from '&lt;library name&gt;/Component' 而不是 from '&lt;library name&gt;/dist/Component'

谢谢

【问题讨论】:

【参考方案1】:

我刚刚发现了这个问题。果然 2018 年还很遥远,但从那时起,工具已经进化了。我一直在寻找相同的干净结构,为此我提出了一个作为 SO 问题的解决方案(积极寻找批评/反馈)

Creating a usable library on npm... with yarn workspaces

基本上,这个想法与@clem 和@wilcoxmd 的答案非常相似,但以纱线工作区为后盾,以实现“上层”的自动化。

【讨论】:

【参考方案2】:

根据@joe-clay 的建议,我找到了解决方案。

我的新结构如下:

dist
 |- Alls files generated after tsc build
 |- package.json
 |- LICENSE
 |- README.md
src
 |- All TS files of library (source)
CHANGELOG.md
LICENSE
README.md
tsconfig.json

dist 目录在 NPM 上发布,其中包含 NPM 包页面的 README.md 和 LICENSE 文件。

根目录是 Github 上的入口点,包含 README.md、LICENSE 和 CHANGELOG.md 用于 Github 上的开发过程。

tsconfig.json 位于根目录中,因为如果位于 dist 目录中,我找不到正确构建的解决方案。

package.json 中,我添加脚本"build": "cd ../ &amp;&amp; tsc" 以便能够在dist 目录中执行npm run build

采用这种结构,图书馆开发和 NPM 发布工作正常。

我可以从我的应用程序中使用这个导入:

import Component from '<library name>/Component';

再次感谢您。

【讨论】:

【参考方案3】:

我找到了一个非常干净的解决方案,它不需要将你的 package.json 复制到你的 dist 或从 dist 发布。

您可以将项目结构为:

package.json (for entire project)
src
 | secondary-package-name
   |- index.ts
secondary-package-name
 |- package.json (for secondary-module-name)
dist
 |- generated files

您的辅助模块的 package.json 只需要包含


  "name": "package/secondary-package-name",
  "private": true,
  "main": "../dist/secondary-package-name/index.js"


指向您的dist

然后您应该能够像这样引用辅助包中的导出:

import  someFn  from "package/secondary-package-name"

如果它是从该目录中的 index.ts 文件中导出的

您还需要确保您的主 package.json 的 files 字段包括:

"files": [
    "dist",
    "secondary-package-name"
  ],

【讨论】:

谢谢,很有用!这甚至可以自动化:P 对此非常感谢,它运行良好。导入也适用于常规 javascript 项目。 const someFn = require('package/secondary-package-name')【参考方案4】:

这可能与您所寻找的有所不同,但我认为这是更标准的方法。无需尝试从模块中的不同目录导入,只需使用单个 main.ts 文件来收集所有内容以进行导出。假设你的 lib 目录中有这个 main.ts 文件可以重新导出所有内容,你只需将 package.json 配置为指向生成的 JS。

文件夹结构:

dist
 |- main.js
 |- main.d.ts
 |- all other generates files
lib
 |- main.ts
...

package.json:


    ...
    "main": "./dist/main.js",
    "types": "./dist/main.d.ts",
    ...

在本例中,如果您的 main.ts 中有以下内容:

export const testValue = 5;

您可以使用 import testValue from '&lt;library&gt;'; 将其导入依赖于该库的其他代码中

查看typescript docs 了解更多信息。

【讨论】:

感谢您的回答,但我的问题是管理多个具有不同“命名空间”的类。例如,我应该能够从库中进行以下导入:import Class1 from '&lt;library&gt;/Class1'; import Class2 from '&lt;library&gt;/SubModule/Class2';。请问有什么想法吗?谢谢。【参考方案5】:

绝大多数模块捆绑工具都遵循Node's module resolution rules,这实际上表示如果您在库名称后指定路径,它将相对于模块的node_modules 文件夹解析该路径。您不能覆盖它,它是 almost certainly never going to change 出于向后兼容性的原因。

在不要求您的用户配置他们的模块捆绑器的情况下,实现此目的的唯一方法是使用与您希望向用户公开的目录结构相匹配的目录结构发布您的包。您可以使用脚本/NPM 挂钩(例如 prepublishpostpublish)来自动执行此操作。

【讨论】:

感谢您的回答和参考链接,这对我来说更清楚。所以我寻找一种解决方案来只公开dist 文件夹。如果你知道这方面的指南,那是受欢迎的。谢谢。

以上是关于如何在没有“dist”的情况下在 NPM 上发布 TypeScript 模块?的主要内容,如果未能解决你的问题,请参考以下文章

在没有npm的情况下在ASP.NET MVC 5中生成javascript包

Gatsby + Contentful - 如何在不重新启动服务器的情况下在本地重做 GraphQL 查询(npm run dev)?

如何在不第二次运行 npm run build 的情况下更新 Vue js 的 dist 文件夹

如何在没有超时的情况下在 Travis CI 上安装一些东西?

如何在没有真实设备的情况下在 iOS 上测试推送通知?

如何在没有入口的情况下在 AKS 上获取 HTTPS