Skip to content

Commit

Permalink
node.jsのtsサポートに関して再度理解する (#88)
Browse files Browse the repository at this point in the history
* update

* update

* update

* update
  • Loading branch information
yossydev authored Dec 17, 2024
1 parent 08de614 commit 70ebd04
Showing 1 changed file with 94 additions and 0 deletions.
94 changes: 94 additions & 0 deletions app/routes/posts/node-typescript-support.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
title: "node.jsのtsサポートに関して再度理解する"
description: "Node.jsの`--experimental-strip-types`と、`--experimental-transform-types`について再度理解します。"
date: "2024/12/17"
updatedAt: "2024/12/17"
path: "node-typescript-support"
published: true
---

[2024年 ユウトの一人アドベントカレンダー](https://adventar.org/calendars/9980)の17日目の記事です。

## Intro

Node.jsの`--experimental-strip-types`と、`--experimental-transform-types`について再度理解します。

## おさらい

`--experimental-strip-types`を使うことで、TypeScriptファイルを実行できます。

この時は、TypeScriptの構文、EnumやNamespaceを使えません。
例えばEnumを使用すると、以下のようなエラーになります。

```
node:internal/modules/helpers:347
throw new ERR_INVALID_TYPESCRIPT_SYNTAX(error);
^
SyntaxError [ERR_INVALID_TYPESCRIPT_SYNTAX]: x TypeScript enum is not supported in strip-only mode
,-[1:1]
1 | ,-> export enum Foo {
2 | | FOO,
3 | | BAR
4 | `-> }
`----
at parseTypeScript (node:internal/modules/helpers:347:11)
at stripTypeScriptTypes (node:internal/modules/helpers:372:25)
at ModuleLoader.<anonymous> (node:internal/modules/esm/translators:475:16)
at #translate (node:internal/modules/esm/loader:433:12)
at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:480:27) {
code: 'ERR_INVALID_TYPESCRIPT_SYNTAX'
}
```

`TypeScript enum is not supported in strip-only mode`となりますね。

そしてこれを解決するために生まれたのが、`--experimental-transform-types`になります。
このフラグを有効にすることで、TypeScript独自の構文でも実行可能になります。

ちなみにこの時、`--experimental-transform-types`は暗黙的に`--experimental-strip-types`も含んでいるので、おそらく今なら以下のスクリプトだけで十分なはずです。

```
"run": "node --experimental-transform-types index.ts",
```

```js
// > 暗黙的に`--experimental-strip-types`も含んでいる
// src: https://github.com/marco-ippolito/node/blob/e65928c6a10a6ae7983ccd3b3374d079ea3cb233/src/node_options.cc#L792-L798
AddOption("--experimental-transform-types",
"enable transformation of TypeScript-only"
"syntax into JavaScript code",
&EnvironmentOptions::experimental_transform_types,
kAllowedInEnvvar);
Implies("--experimental-transform-types", "--experimental-strip-types");
Implies("--experimental-transform-types", "--enable-source-maps");
```

## Amaroのスタックトレース保持方法

Node.jsではTypeScriptのトランスパイルにAmaroというswc typescript parserのラッパーを使用しています。

そしてこちらの面白いところが、スタックトレースのために、型を除いた分の空白をそのままにしておくそうです。

```ts
const amaro = require('amaro');
const { code } = amaro.transformSync("const foo: string = 'bar';", { mode: "strip-only" });
console.log(code); // "const foo = 'bar';"
```

型排除により詰めた分、元のコードとトランスパイル後のコードの行数は変わってしまうので、デバッグしづらくなるのを防いでいる感じですね。

## tsconfigは見ない

今回のNode.jsのtsサポートでは、tsconfigは読み込まれないようになっています。そのため、実行時の型チェックやエイリアスの設定、targetオプションの変更などはできないようになっています。

> TypeScript features that depend on settings within tsconfig.json, such as paths or converting newer JavaScript syntax to older standards, are intentionally unsupported. To get full TypeScript support, see Full TypeScript support.
ここら辺は公式の[full typescrit support](https://nodejs.org/api/typescript.html#full-typescript-support)を見るとわかります。tsxや、書かれてはないですがts-nodeを使用するようにみたいな感じらしいですね。

## まとめ

筆者としてはtsconfigを読み込まないのはエイリアス以外にも結構辛いポイントは出ると思っているので、それだったらts-nodeでいいんじゃないかなと思っている派です。

ただDenoとかBunの影響を受けて、これだけのユーザー数がいるOSSが、誰もが待ち望んだ機能を入れてくれたのはやっぱりすごいなと思うので、引き続き応援していきたいです。

0 comments on commit 70ebd04

Please sign in to comment.