Nodejs 新手,请问下 typescript 工程引入/导出 npm 包和 package.json 的问题
Nodejs 新手,请问下 typescript 工程引入/导出 npm 包和 package.json 的问题
简单来说,我这边前端和服务器都用到了一块逻辑代码,然后我图方便把它提出来作为 npm 包,一处更改前后都能使用。但是:
- 前后端都是 typescript
- 前端工程是 es module 发布类网页应用,后端工程是 node 的 commonjs
- 前端不支持 bigint ,后端支持
- 前端查了一下 JSBI 可以 babel 导出时选择替换为 bigint
- 于是我查了一下找到个 hybrid npm 包的 package.json 写法,就是 esm -> import ,cjs -> require 分开填写
- 问题又来了,babel 导出的 bigint 的 .d.ts 和 tsc 导出的 JSBI 的 .d.ts 并不一致,并且如果想两边使用方便,确实前端不能看到 bigint 后端不能看到 JSBI
- 然后我又再起了个 npm 包,把 JSBI 套了一层,在工具类里面处理导出,自己 type 了个 BI 类型,不会暴露出 JSBI 或者 bigint
- 当然逻辑模块引用工具类的 npm 包时又循环到上面的问题了,公共代码引用方式相同,同一个包,如何用的时候导入命令相同,比如都是
import { BIEx, BI } from 'jsbi-extension';
但是在不同“语境”下代表的东西不同?
我不知道我表述清楚没有,最后我的临时解决方案是自己造的这个 jsbi 的套壳起了俩分枝,在公共逻辑模块 build esm/cjs 时分别引用不同的分支,但...感觉各种别扭...请问这种情形的标准解决方案是什么?
我造的 JSBI 坑在这 https://github.com/darklinden/jsbi-extension
后来想了下也只是因为我这是前后端 esm 和 cjs 的不同才只有两个分支...如果是做成通用的...岂不是要 4 个分支?
可以看一下 unbuild 这个打包工具 支持同时打包出 esm 和 cjs2 种包。这篇文章有很详细的说明
https://antfu.me/posts/publish-esm-and-cjs
另外 nodejs 也支持 esm 的 在 package.json 里设置 type 为 module 即可
稍微看了下,好像不大对…
* 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”,
···
emm,刚刚手抖就发出去了…
无论 types 在 exports 内 还是 外, 目前我都没法指定多个 types 指向同一路径并且区别“语境”
一个想法,前端直接在 html 中引入 bigint 的 polyfill
生成至少两套 .d.ts ?可以在输出 cjs/esm 时不输入类型文件 ( tsc -m commonjs/esNext --declaration false ),然后单独输出类型文件( tsc --declaration --emitDeclarationOnly )
要么把关于 bigint 的实现隐藏起来,这样就可以不被外面看到;
如果不能隐藏,必须被外面使用,那么要么给外面封装成一套接口,就如你试图做的 BI ,要么就分别单独生成不同的类型文件,就像 说的
现在是生成了两套,cjs 和 mjs 各一套 js 和 d.ts…而且问题在于.d.ts 也并不相同
如何配置 package.json 以达到外部使用库的 typescript 可以正常使用?
类似宏定义 BI 为如果 bigint 有实现则使用,否则使用 js
由于有 https://www.npmjs.com/package/babel-plugin-transform-bigint ,可以将 bigint 转换成 JSBI 。所以现在我觉得你可以移除你代码中的 bigint 了,而是将 JSBI 作为类似于 corejs 的 polyfill ,由 babel 来处理。
还有就是不太推荐用模块类型来判断环境,因为现在 node 也支持 ESM 了,有些会直接将 node 全部切换到 ESM 。别的模块一般是’moduleName’作为 node 环境导入的模块,'moduleName/browser’作为浏览器环境导入的模块。
我语文就这么差么…
* 我在逻辑模块中使用了 jsbi ,因为前端有些场景无法使用 bigint
* 后端因为是老项目而且很多 commonjs 的写法无法切换到 module ,前端因为使用的游戏引擎的原因无法切换到 commonjs
* 为了后端“懒”,可以使用 bigint 的 node 特性加减乘除,所以在后端导入逻辑模块的时候需要 babel 转化为 bigint ,并且我引入的 BI 类型也是希望中间模块不显示使用 JSBI 和 bigint 中的任意一个,以保证通用性
* 现在能做到的就是把需要 babel 转换的从整个中间模块变为了只有一个 JBSI 的引用块,但是这个引用块在中间块和前端分别引用的时候需要编译替换为不同的版本,并且声明文件也需要替换,我觉得这不是一个正常的引用工作流
1. 我的意思是保留 bigint 的写法,JSBI 使用 babel 插件作为 polyfill 处理,这样就不需要导出 JSBI 的类型了。类似于 corejs 的处理。
2. 开心就好,反正觉得没问题就没问题。
3. 同 1
4. 没有 bigint 的环境用 polyfill 处理,可以保证类型的一致性
感谢回复
* 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 …
作为 Node.js 新手,了解如何在 TypeScript 工程中引入/导出 npm 包以及管理 package.json
文件是非常重要的。以下是一个简要的指南和示例代码,帮助你快速上手。
1. 初始化 TypeScript 项目
首先,确保你已经安装了 Node.js 和 npm。然后,在项目目录下运行以下命令来初始化一个新的 Node.js 项目,并添加 TypeScript 支持:
npm init -y
npm install typescript ts-node @types/node --save-dev
npx tsc --init
2. 安装 npm 包
你可以通过 npm 安装所需的包。例如,安装 express
和它的 TypeScript 类型定义:
npm install express @types/express
3. 引入/导出 npm 包
在你的 TypeScript 文件中,你可以这样引入和使用 npm 包:
// 引入 express 包
import express from 'express';
const app = express();
app.get('/', (req, res) => {
res.send('Hello, World!');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
4. package.json 管理
package.json
文件用于管理项目的依赖、脚本等信息。你可以通过编辑这个文件来添加或删除依赖,或者运行脚本。例如,你可以在 scripts
部分添加一个启动脚本:
"scripts": {
"start": "ts-node src/index.ts"
}
然后,你可以通过 npm run start
命令来启动你的 TypeScript 应用。
希望这些信息对你有帮助!如果有更多问题,欢迎继续提问。