【问题标题】:How to publish a typescript package for both node and react如何为节点和反应发布打字稿包
【发布时间】:2021-12-29 04:57:16
【问题描述】:

我在 typescript 中有一个身份验证库,已发布到 npm,并且希望能够将它用于节点项目和 react 项目(使用 create-react-app 创建)。 如果我是正确的,在 npm 上发布的包将在使用 create-react-app 创建的应用程序中工作,因为 create-react-app 中的捆绑会神奇地正确捆绑这些东西,但是当我安装和导入时我在反应我的依赖项之一中发布的库将无法正确加载。 有趣的是,其他依赖项运行良好,只是这个依赖项没有正确加载。在 Node 项目中一切正常,而且问题似乎只发生在 React 上。

当我在调试器中调试时,我看到导入的依赖项的值没有正确加载

Object.defineProperty(exports, "__esModule", { value: true });
exports.JsSigner = void 0;
const util_1 = require("dependency with issue");

设置为路径“util_1: /static/media/index.325f9bf6594ebb34640d.cjs”,而其他依赖项已正确分配对象。

有趣的是,当我安装/导入有问题的依赖包时,它直接在 react 应用程序中正确加载。

我想知道在发布之前是否需要在我的包中设置任何内容以使其适用于 node 和 create-react-app 项目?!或者发布的包应该适用于这两种类型的项目?!

【问题讨论】:

  • 如果您的代码与直接反应无关,并且不调用仅在节点中可用或仅在浏览器中可用的任何内容,那么它应该可以正常工作而无需任何特殊考虑。这个包的package.json 是什么样的?如何声明依赖关系?
  • 您确定该软件包与浏览器环境兼容吗?不是所有的包都是。也许它导入了仅在 node.js 中可用的东西。
  • 我相信它应该是兼容的,因为当我直接在我的 create-react-app 中安装该软件包(@polkadot/util-crypto)时,它工作正常,问题仅在通过我的加载时发生自己发布的包。

标签: node.js reactjs typescript create-react-app npm-publish


【解决方案1】:

问题原来是由于上游依赖使用 package.json 中的“exports”设置为不同的模块系统发布了两个不同的模块:

"exports": {
    ".": {
      "require": "./index.cjs",
      "default": "./index.js"
    }
}

exports 设置是事实上的 package.json 设置,webpack 使用它来决定应该使用哪个导出的模块。

我发布的包是由 typescript 编译来发布 CommonJs 模块的。因此 typescript 将编译我的代码以使用 "require()" 导入依赖模块,因此基于上游依赖项中指定的导出设置,webpack(由 create-react-app 使用)将打包我的 react-app 包中上游依赖项中的 ./index.cjs 文件!这就是我看到的原因:

当我在调试器中调试时,我看到了导入的值 未正确加载的依赖项

Object.defineProperty(exports, "__esModule", { value: true });
exports.JsSigner = void 0; const util_1 = require("dependency with
issue"); 

设置为路径“util_1: /static/media/index.325f9bf6594ebb34640d.cjs" 而另一个 依赖项已正确分配给对象。

解决办法: 我需要通过在我的 package.json

中添加两种格式的构建脚本来设置 typescript 来为我的 lib 构建 cjs 和 ems 模块
scripts": {
    "build": "yarn build:ems && yarn build:cjs",
    "build:cjs": "tsc --module commonjs --outDir dist/cjs",
    "build:ems": "tsc --module esnext --outDir dist/ems",
  },

以上设置以 2 种不同的模块格式构建我的打字稿

  • 在 commonJs 模块中并将输出保存在 dist/cjs 中
  • 在 esnext 模块中并将输出保存在 dist/ems 中

我还需要将导出添加到我的 package.json 以让 webpack 知道应该为哪个模块系统加载哪个模块:

"exports": {
    ".": {
      "require": "./dist/cjs/index.js",
      "default": "./dist/ems/index.js"
    }
  }

上面的导出设置告诉 webpack 在使用 require() 导入我的包时加载 ./dist/cjs/index.js,然后加载 。 /dist/ems/index.js 在其他情况下。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-10
    • 2021-12-05
    • 2019-07-11
    • 2023-04-06
    • 2018-04-10
    • 2018-09-29
    • 2023-03-29
    • 2019-10-26
    相关资源
    最近更新 更多