nodejs 新手,请问下 typescript 工程引入/导出 npm 包和 package.json 的问题

2022-08-17 06:46:18 +08:00
 darklinden

简单来说,我这边前端和服务器都用到了一块逻辑代码,然后我图方便把它提出来作为 npm 包,一处更改前后都能使用。但是:

我不知道我表述清楚没有,最后我的临时解决方案是自己造的这个 jsbi 的套壳起了俩分枝,在公共逻辑模块 build esm/cjs 时分别引用不同的分支,但...感觉各种别扭...请问这种情形的标准解决方案是什么?

我造的 JSBI 坑在这 https://github.com/darklinden/jsbi-extension 后来想了下也只是因为我这是前后端 esm 和 cjs 的不同才只有两个分支...如果是做成通用的...岂不是要 4 个分支?

4282 次点击
所在节点    Node.js
12 条回复
lyc575757
2022-08-17 07:39:51 +08:00
可以看一下 unbuild 这个打包工具 支持同时打包出 esm 和 cjs2 种包。这篇文章有很详细的说明

https://antfu.me/posts/publish-esm-and-cjs
lyc575757
2022-08-17 07:47:22 +08:00
另外 nodejs 也支持 esm 的 在 package.json 里设置 type 为 module 即可
darklinden
2022-08-17 07:59:19 +08:00
@lyc575757 稍微看了下,好像不大对...
* package.json 我设置了的啊,上面可能没有表述清楚,问题在于 .d.ts 文件声明
* 分开编译我也做了的,分别使用了两个 tsconfig.json ,只是导出后我自己写脚本处理的 .cjs 和 .mjs
* 目前是 4 个包不是两个,(cjs + esm) x (JSBI + bigint), 其中 bigint 的导出是使用 JSBI 提供的 babel 插件
* 上面的问题就导致会生成至少两套 .d.ts ,而且并不相通
* ··· "exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"types": "./dist/index.d.ts",
}
},
"types": "./dist/index.d.ts",
···
darklinden
2022-08-17 08:01:18 +08:00
@darklinden emm,刚刚手抖就发出去了...
无论 types 在 exports 内 还是 外, 目前我都没法指定多个 types 指向同一路径并且区别“语境”
zhyl
2022-08-17 09:34:03 +08:00
一个想法,前端直接在 html 中引入 bigint 的 polyfill
RomeoHong
2022-08-17 09:44:35 +08:00
生成至少两套 .d.ts ?可以在输出 cjs/esm 时不输入类型文件 ( tsc -m commonjs/esNext --declaration false ),然后单独输出类型文件( tsc --declaration --emitDeclarationOnly )
zhuisui
2022-08-17 10:09:50 +08:00
要么把关于 bigint 的实现隐藏起来,这样就可以不被外面看到;
如果不能隐藏,必须被外面使用,那么要么给外面封装成一套接口,就如你试图做的 BI ,要么就分别单独生成不同的类型文件,就像 @RomeoHong 说的
darklinden
2022-08-17 14:04:30 +08:00
@RomeoHong 现在是生成了两套,cjs 和 mjs 各一套 js 和 d.ts…而且问题在于.d.ts 也并不相同
如何配置 package.json 以达到外部使用库的 typescript 可以正常使用?
类似宏定义 BI 为如果 bigint 有实现则使用,否则使用 js
@zhuisui
duan602728596
2022-08-17 16:41:20 +08:00
由于有 https://www.npmjs.com/package/babel-plugin-transform-bigint ,可以将 bigint 转换成 JSBI 。所以现在我觉得你可以移除你代码中的 bigint 了,而是将 JSBI 作为类似于 corejs 的 polyfill ,由 babel 来处理。

还有就是不太推荐用模块类型来判断环境,因为现在 node 也支持 ESM 了,有些会直接将 node 全部切换到 ESM 。别的模块一般是'moduleName'作为 node 环境导入的模块,'moduleName/browser'作为浏览器环境导入的模块。
darklinden
2022-08-17 22:23:19 +08:00
@duan602728596 我语文就这么差么...
* 我在逻辑模块中使用了 jsbi ,因为前端有些场景无法使用 bigint
* 后端因为是老项目而且很多 commonjs 的写法无法切换到 module ,前端因为使用的游戏引擎的原因无法切换到 commonjs
* 为了后端“懒”,可以使用 bigint 的 node 特性加减乘除,所以在后端导入逻辑模块的时候需要 babel 转化为 bigint ,并且我引入的 BI 类型也是希望中间模块不显示使用 JSBI 和 bigint 中的任意一个,以保证通用性
* 现在能做到的就是把需要 babel 转换的从整个中间模块变为了只有一个 JBSI 的引用块,但是这个引用块在中间块和前端分别引用的时候需要编译替换为不同的版本,并且声明文件也需要替换,我觉得这不是一个正常的引用工作流
duan602728596
2022-08-18 01:19:55 +08:00
@darklinden
1. 我的意思是保留 bigint 的写法,JSBI 使用 babel 插件作为 polyfill 处理,这样就不需要导出 JSBI 的类型了。类似于 corejs 的处理。
2. 开心就好,反正觉得没问题就没问题。
3. 同 1
4. 没有 bigint 的环境用 polyfill 处理,可以保证类型的一致性
darklinden
2022-08-18 06:55:50 +08:00
@duan602728596
感谢回复
* https://github.com/Yaffle/babel-plugin-transform-bigint ``` It will try to detect when an operator is used for bigints, not numbers. This will not work in many cases, so please use JSBI directly only if you know, that the code works only with bigints. ``` 这个 babel 插件的问题和 JSBI to bigint 一样,很多情况下无法有效判别语义...
* 目前看还真是只能套了一层又一层...反正可以跑...
* 现在就像是为了把发动机装拖拉机上,传动拉了根橡皮筋,进油口插了根吸管,拿塑料纸裹了裹,外面贴了个 Hello Kitty ...

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/873343

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX