0%

2023-ts-with-esm

2023 使用 TypeScript + Node.js ESM 的使用体验.

截至 2023.8

可选方案

  • ts-node
  • tsx / @swc-node/core
  • tsc
  • tsup

ts-node

支持 esm, 需要

  • package.jsontype=module,
  • tsconfig.json{ts-node: {"esm": true}

node v20 还有新问题

https://github.com/TypeStrong/ts-node/issues/1997

其他问题

tsx

  • 支持 tsconfig.paths without config
  • 但是发布有问题, 同 tsc

update when Node.js v20 become Active LTS

ts-node 依旧没有资源投入适配 node v20 module.register API.

  • 对于直接执行 ts file, tsx 是更好的选择.

  • 发布

    • 使用 TypeScript 编写的 cli 工具, 直接发布 TypeScript 源码, 发布需带上 tsconfig, 可以使用类似下面的代码

      1
      2
      3
      4
      5
      6
      7
      8
      9
      // <project-root>/entry.mjs
      import esmUtils from 'esm-utils'
      import path from 'path'

      const { __dirname } = esmUtils(import.meta)
      process.env.ESBK_TSCONFIG_PATH = path.join(__dirname, 'tsconfig.json')

      await import('tsx')
      await import('./src/entry.ts')

      使用 dynamic import function 可以使 ./src/entry.ts 使用上 esm loader 逻辑

    • 作为库, 不应发布 TypeScript. 因为使用库的项目不一定使用 TypeScript, 就算用很可能 tsconfig 不同, 而无法使用项目的 tsconfig 编译库包含的 TypeScript 代码

工具链的更改

vscode code-runner 更改
1
2
3
"code-runner.executorMap": {
"typescript": "tsx" // default ts-node
},

tsc

tsup

体验下来比较爽的方案

  • 基于 esbuild, dev tsup --watch 很快
  • 支持 tsconfig.paths 解析
  • 由于发布 bundle 代码, 不存在运行时解析 tsconfig.paths

目前我的几个 cli 都是基于这个方案改造成了 esm

  • yun-playlist-downloader
  • handy-img
  • …more