お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。
投稿日:
Node.js

主な変更点に関して個人的にざっくりまとめてみる。詳細は公式のリリースノートを確認すること。v18やv16と比べるとアップデートが多い気がする。個人的にはv12, v14並に嬉しいアップデートかも。特に単一バイナリのサポートとARM64版Windowsのサポートが強力だと思います。

権限モデルの追加

--experimental-permissionフラグを付けることでファイル システム操作、子プロセスの生成、ワーカー スレッドの作成など、プログラムの実行中に特定のリソースへのアクセスを制限できる様になった模様。

実験的機能であれば16のときにもあったと思うが、この時との違いは詳しく確認してない。参考程度にv18とlatestとのドキュメントリンクを置いておく。

  • https://nodejs.org/api/permissions.html#process-based-permissions
  • https://nodejs.org/docs/latest-v18.x/api/permissions.html#process-based-permissions

専用スレッドで実行されるカスタムESMローダーフックの追加

多分ESMを別スレッドで読み込むことでヒープ競合が起きなくなるのだと思うが、使ったことがないので詳細は不明。TypeScriptを使っている限り、まだまだCJSを使う機会が多く、ESMへの完全移行は先な気がするので放置で良さそう?誰か詳しい人教えて!

同期的になったimport.meta.resolve()

詳細不明なのでパス。以下の記事が参考になるかも?

https://sosukesuzuki.dev/posts/nodejs-import-meta-resolve/

V8エンジンのアップデート

Chromium 113の一部であるバージョン11.3に更新されたそうです。前回は 11.2 だったようですが、いつのバージョンに入ってたのかは未確認。

テストランナーが安定版になった

Test runnerがStableになり本番環境で使えるレベルとなった。Jestより貧弱な気しかしないが一度は試してみたいところです。

https://nodejs.org/api/test.html

Ada 2.0の導入

URI解析のパフォーマンスが向上したほか、URLホスト名解析が楽になったっぽい?

単一実行バイナリの生成に対応

実験的な機能ですが単一実行バイナリの生成がサポートされた。リリースノートを読む限りNode.jsランタイムをバンドルすることで実現してそうなので、Electronみたいに巨大なバイナリができそうな気がする。興味深いので是非試してみたい機能。

https://nodejs.org/api/single-executable-applications.html

Web暗号化APIの互換性向上

恐らく主要なブラウザに実装されているWebCrypt実装を模倣したものが追加された?

https://github.com/nodejs/node/pull/46067

ARM64版Windowsのサポート

Node.jsの全機能がARM64版Windowsで動作するようになったとのこと。Surface Pro Xとかでも動くようになるものと思われる。単一実行バイナリの作成と合わせて嬉しい機能です。

WebAssembly System Interfaceインスタンス作成時にバージョン指定を必須に

new WASI()でバージョン指定が必須になりました。

https://nodejs.org/api/wasi.html
https://github.com/nodejs/node/pull/47391

url.parse()に無効なポート番号を持つURLを渡すと警告を出すように

次のようなURLを渡すと実行時に警告が出るようになりました。

url.parse('https://evil.com:.example.com');
url.parse('git+ssh://git@github.com:npm/npm');

https://github.com/nodejs/node/pull/45526

LTSスケジュール

20系がLTSに入るのは2023-10-24からです。

https://github.com/nodejs/release#release-schedule

投稿日:
Node.js::Prettier言語::Markdown

Prettier の次期 Major release である v3 がそろそろ出そうなので、今回含まれる大きな変更の一つについての記事です。

内容としてはMarkdown文書の全角文字と半角英数の間にスペースが挿入されなくなります。個人的にこれは相当賛否が分かれると思うので、v3が出た後の対処方法も併せて書いておきます。

変更点

以下は漢字Alphabetsひらがな12345カタカナ67890という文字列が渡された時の変化例です。

v3 より前 v3 以降
漢字 Alphabets ひらがな 12345 カタカナ 67890 漢字Alphabetsひらがな12345カタカナ67890

多分スペースが空いたときのほうが好みといった人が一定数居ると思います。個人的には検索性が破滅的に低下するためこの機能には否定的でしたが、今回のアップデートで遂にスペースが入らなくなったので、割と喜んでいます。ぶっちゃけこのブログの過去記事ににある余計なスペースも現在全て除去する作業をしてるくらいです。

発端としては次のIssueにあり、これをずっと追っていた人もきっといると思います。私もそのうちの一人です。

この問題は次のPullRequestで対応され、現在v3 用のブランチに取り込まれています。

  • [Markdown[next branch]: Do not insert spaces between Chinese/Japanese & latin letters #11597](https://github.com/prettier/prettier/pull/11597)

この機能を試したい場合、以下のようにインストールすることで試すことが出来ます。

npm i -D https://github.com/prettier/prettier.git#next

なお、PullRequestにある通り既にあるものには影響しないので、既にあるスペースを詰めることは出来ません。

これまで通りスペースを入れたい場合

引き続き漢字Alphabetsひらがな12345カタカナ67890漢字 Alphabets ひらがな 12345 カタカナ 67890にしたいケース

前述のPullRequestの中でも言及されていますが、textlintを利用することで対応できます。ただPrettierと併用するのは難しいと思います。

導入方法

textlintにtextlint-rule-preset-ja-spacingを組み合わせて対応します。

npm i -D textlint textlint-rule-preset-ja-spacing
使用方法

まず.textlintrcを作成し、次の設定を追加します。

{
    "rules": {
        "preset-ja-spacing": {
            "ja-space-between-half-and-full-width": {
                "space": "always"
            }
        }
    }
}

CLIを用いて修正する場合

npx textlint --fix <path>

VSCodeを用いる場合、vscode-textlintをインストールし、settings.jsonに以下の設定を追加することで利用することが出来ます。Prettierと併用する場合、Prettierと競合し、textlintが負けるため、Markdownの整形に関してはtextlintに任せるのが無難だと思います。

{
    "textlint.autoFixOnSave": true
}

一応Custom Local Formattersを使えば近いことは出来なくもないのですが、ファイルへの書き込み同期がズレてるのか上手く動かない気がします。一応以下の設定で動くことには動きますが、あんま期待しないほうがいいかも…。拡張からコマンドを蹴ること自体セキュリティ的に微妙な気がするので、この方法は使わないのが無難な気がします。

{
    "[markdown]": {
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "jkillian.custom-local-formatters"
    },
    "customLocalFormatters.formatters": [
        {
            "command": "npx prettier ${file} | npx textlint --stdin --stdin-filename ${file} --fix --format fixed-result",
            "languages": ["markdown"]
        }
    ]
}

これはPrettierとtextlintを呼ぶ時点で二重処理になって重いので、Markdownのフォーマットはどっちか片方にやらせたほうが良いでしょう。ただtextlintはデフォルトだと表の整形とかいい感じにしてくれないようなのが困りものです。textlintにmarkdownプラグインを入れると改善されるかもしれませんが試してないです。

これまでのスペースを消したい場合

既にある漢字 Alphabets ひらがな 12345 カタカナ 67890漢字Alphabetsひらがな12345カタカナ67890にしたいケース

前項の「これまで通りスペースを入れたい場合」で紹介した環境を導入し、.textlintrcを以下のように作成すればある程度は対応できます。但し完全には除去しきれません。

{
    "rules": {
        "preset-ja-spacing": {
            "ja-space-between-half-and-full-width": {
                "space": "never"
            }
        }
    }
}

この設定によるtextlintの整形結果は以下のとおりです。記号の前後の半角スペースや見出しやリンク文章にある半角スペースは除去しきれないようです。

 ## 123 あああ abc

-ユーザー ID は Slack アプリから
+ユーザー IDはSlackアプリから
 やよいの ○ 色申告
 [Web サイトの example](https://example.com)

余談

多分大抵の人はPrettierをv3にしてからこの事に気が付くと思います。当然です。一々 OSSのアップデートを追っている人は恐らくメンテナか物好きだからです。

現在Prettierのリポジトリでは似たような議論として、デフォルトでインデントにスペースを使っているところをタブに置き換えようという動きがあります。幸いv3では採用に至っていませんが、今後採用される可能性があり、メンテナであるSosuke Suzuki氏もこの事について以下の記事で憂慮されています。

ある日突然インデントのスペースがタブに変われば、苦情が出るのは明白です。設定一つ直すだけとは言え、影響は大きいでしょう。CIで全体にPrettierを掛けていないプロジェクトでは一時的にタブインデントのファイルとスペースインデントのファイルが混在するケースもあると思います。空白文字の差分表示や検出を無効化していると気づかないまま、そのような状態になるケースもあると思います。

個人的にはMarkdownに落とした時にどの環境でも同じように見えるという理由でスペースインデントが好みですが、A11yの観点からタブにせよという考えも理解は出来ます。でもブラウザで.mdファイル見たときとかに見づらいんですよね…。PythonPHPYAML の様に標準がスペースインデントの言語もありますし、個人的には標準はスペースで構わないのではと思ったりもします。(その上で必要に応じてタブを使うという選択肢は出来ると思います。Google JavaScript Style Guideでも、これが標準です。Prettierは代表的なフォーマッタで事実上のコーディング標準であるとも言えるため、社会的責務でそうする必要があるかもしれませんが、個人的な思いとしては標準はスペースのままであってほしいなぁと思います。どうしても標準が変わると、世間はそこに引きずられざれ得ないと思いますから。

多分今回の変更も、上記のuseTab同様に一部で非難が上がる気がしていて、余り大事にならなければいいなぁ…とか考えています。(タブと比べると影響範囲が狭いので、ひょっとしたら今回はあまり何も起きないかもですが…)