如何为节点和反应发布打字稿包

How to publish a typescript package for both node and react

我在 typescript 中有一个身份验证库,我已经发布到 npm 并希望能够将它用于节点项目和反应项目(使用 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”,而其他依赖项已正确分配对象。

有趣的是,当我 install/import 有问题的依赖包时,直接在反应应用程序中正确加载。

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

问题原来是由于上游依赖项在 package.json:[=16 中使用“导出”设置针对不同的模块系统有两个不同的已发布模块=]

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

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

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

When I debug in the debugger I see the value of the imported dependency that is not loaded correctly

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

is set to a path "util_1: /static/media/index.325f9bf6594ebb34640d.cjs" while the other dependencies are correctly assigned with an object.

解决方法: 我需要通过在 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.