SlideShare a Scribd company logo
1 of 30
Download to read offline
Na#ve ESM への道
∼ 最終章: Babel / TypeScript Modules との闘い ∼
Node 学園 35 時限目 / 2021-02-24
@teppeis
1
自己紹介
• @teppeis / Teppei Sato
• サイボウズから来ました。
• もちろん We are hiring!!!
• プロダクト開発チーム
• フロントエンドエキスパートチーム
2
Node.js の ES Modules 対応って
どうなったの?
3
前回までのあらすじ
2015 年の ES Modules (ESM) 策定からときは流れ、Node.js での ESM
対応は混迷を極めた1
。
しかし 2018 年 10 月、 Node.js Modules Team は ESM 対応計画 2
を
なんとかまとめあげ、ようやく実装が進んでいった。
そして 2020 年末にはその計画が実装完了し、2021 年は Na8ve ESM
時代が到来するかに見えた。
2
Plan for New Modules Implementa5on · nodejs/modules
1
前回スライドを参照: You Don't Know ES Modules, Teppei Sato (2016)
4
Node.js ESM 実装状況
基本機能は Node v12.20+, v14.13+ で フラグ無し で提供済み3
• Na$ve ESM import / export
• CommonJS interoperability (CJS Interop)
• package.json imports / exports mapping
3
ESM import / export と CJS interop は v15 系で stability: stable, v12, v14 系は次の minor リリースで stable になる
予定。imports / exports mapping は v15 系で stable になったが v12, v14 は未定。
5
2021 年は Na've ESM の時代に?
• 前述の通り、Node v12 系以上は ESM を実装済み
• Node v10 は 2021-04-30 に EOL
• つまり、5 月以降は全 Node 環境で Na5ve ESM が利用可能!
• やったー、全部 ESM で書こうぜー
6
h"ps:/
/blog.sindresorhus.com/get-ready-for-esm-aa53530b3f77 7
h"ps:/
/twi"er.com/jus2nfagnani/status/1356012934564958212 8
そんな風に思っていた時期が
私にもありました。
9
鬼門: CJS Interop
10
CJS Interop
CJS から ESM へスムーズな移行を進めるために検討されてきた相
互互換機能
• CJS から ESM をロードできる
• ESM から CJS をロードできる
仕様の複雑さと既存パッケージとの互換性から、ここまで Node
の ESM 対応を遅らせてきた鬼門でもある
11
import ESM from CJS
// esm.mjs
export default "foo";
export const named = "bar";
// cjs.js
const { default: def, named } = await import("./esm.mjs");
//// def: "foo"
//// named: "bar"
• dynamic import を使用
• ESM と同じ使い勝手で、違和感はない
12
import CJS from ESM: named import
// cjs.js
exports.named = "foo";
// esm.mjs
import { named } from "./cjs.js";
//// named: "foo"
• exports のプロパティが named import される
13
import CJS from ESM: default import
// cjs.js
module.exports = "foo";
// esm.mjs
import cjs from "./cjs.js";
//// cjs: "foo"
• module.exports が default import される
14
ところで
Babel と TypeScript はどうだっけ?
15
Babel / TypeScript の ESM → CJS 変換
// Before (ESM in Babel)
export default "foo";
// After (CJS)
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = "foo";
• default export は、exports.default に変換される
• おや?Node.js の CJS Interop と仕様が違うぞ!
16
Babel / TypeScript で CJS にトランスパイルされた
npm パッケージを Na5ve ESM からロードしたいけど
// node_modules/foo/index.ts
export default "foo!";
// main.mjs
import foo from "foo";
//// foo: { default: "foo!" }
default export された値を
期待通りに default import できない!
17
無理矢理書くこともできるが
// node_modules/foo/index.ts
export default "foo!";
// main.mjs
import def from "foo";
const { foo } = def;
//// foo: "foo!"
これなら動くが、import したい全ての npm パッケージについて内
部的に Babel / TS を使っているかを調べて書き分ける必要があり、
書き味も体験も非常に厳しい。
18
Babel Modules ≠ ES Modules
TypeScript Modules ≠ ES Modules
19
ここまでは
Babel / TypeScript ベースの
CJS な npm パッケージを
Na5ve ESM からロードする話
20
TypeScript で
Na-ve ESM を書くのは
もっと厳しい
21
TypeScript で Na-ve ESM を出力したい
公式にはサポートされてないので基本的に厳しい
• .mjs を出力できない
• .mjs を入力できない
• moduleResolution:node が Node の ESM 仕様と異なる
• imports / exports mapping に未対応
22
TypeScript で無理矢理書くこともできるが
// foo.ts
export default "foo!";
// main.ts
import foo from "./foo.js";
import 文で拡張子を省略せず .js を指定し(.ts ではない)、
pacakge.json で type:"module" にすることで、変換後に
Na$ve ESM として無理矢理動かすことは可能。
しかし ts-node など周辺ツールが未対応で jest も動かせない。
23
TypeScript Modules を import 不可能
// node_modules/foo/index.ts
export default "foo!";
// main.ts
import def from "foo";
const { foo } = def;
//// TS2339 Error: Property 'foo' does not exist on type 'String'.
TS が CJS に変換したパッケージに同梱された型定義が Node ESM
仕様と食い違うため、TS Na-ve ESM から default import しようと
すると 型エラーかランタイムエラーのどちらか になる。
24
今後どうなるのか?
25
Babel / TypScript 陣営の動き
• Babel は新オプション importInterop:"node" を検討している4
• TypeScript は最近の動きは見えない
• 2020 年 3 月に新しい moduleResolution フラグを作る方針
というコメント5
があったが、続報なし
5
Design Mee*ng Notes, 3/27/2020 · Issue #37897 · microso=/TypeScript
4
Implement importInterop: "node" op+on for module transforms by nicolo-ribaudo · Pull Request #12838 ·
babel/babel
26
Babel / TypeScript が対応しても
• 既に npm 公開された大量の Babel / TS Modules はトランスパイ
ル済みであり、挙動は変わらない
• 更新のない Babel / TS Modules は Na4ve ESM からは扱いにく
い存在として残り続ける
• npm 界に ESM 対応のアップデートが広がるのを待つしかない
• 時間が解決するのか...
27
Sindre はどうしてるの?
そんなこともあろうかと、既存の TypeScript ベースの npm パッケージにあら
かじめ workaround を仕込んでいた!6
export default got;
module.exports = got;
module.exports.default = got;
module.exports.__esModule = true;
これで TypeScript からも Na-ve ESM からも default import 可能。
ただし dirty hack で副作用もあるのでご利用は計画的に。
6
h$ps:/
/github.com/sindresorhus/got/blob/v11.8.1/source/index.ts#L127-L130
28
ところで、
どうして Na$ve ESM を書きたいんだっけ?
• 皮肉にも、CJS Interop の実装が進んだ結果、CJS でも特に不満
がない状況になりつつある
• ESM のセールスポイントだった tree-shaking も、静的解析の発
展により Webpack や Parcel が CJS にも対応し始めた
• それでも ESM を書くと キマる んだ!
29
まとめ
• Na$ve ESM は Node.js の中だけなら 5 月から自由に使える
• しかし Babel / TypeScript ベースの npm パッケージを default import すると
いろいろハマって厳しい
• この状況は各種ツールと既存 npm パッケージが更新されるまでだいぶ続き
そう
• TypeScript で Na$ve ESM が書けるようになるのはまだまだ先
• しばらくは TypeScript で CJS を書く今の生活が続きそう
30

More Related Content

What's hot

SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)Takuto Wada
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているKoichi Tanaka
 
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところY Watanabe
 
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニングyoku0825
 
リッチなドメインモデル 名前探し
リッチなドメインモデル 名前探しリッチなドメインモデル 名前探し
リッチなドメインモデル 名前探し増田 亨
 
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはがんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはJun-ichi Sakamoto
 
Pythonによる黒魔術入門
Pythonによる黒魔術入門Pythonによる黒魔術入門
Pythonによる黒魔術入門大樹 小倉
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなKentaro Matsui
 
イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)Yoshitaka Kawashima
 
これからSpringを使う開発者が知っておくべきこと
これからSpringを使う開発者が知っておくべきことこれからSpringを使う開発者が知っておくべきこと
これからSpringを使う開発者が知っておくべきこと土岐 孝平
 
SQLアンチパターン~ファントムファイル
SQLアンチパターン~ファントムファイルSQLアンチパターン~ファントムファイル
SQLアンチパターン~ファントムファイルItabashi Masayuki
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方増田 亨
 
PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門泰 増田
 
SQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するかSQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するかShogo Wakayama
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話Koichiro Matsuoka
 
マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!mosa siru
 
MySQL 5.7にやられないためにおぼえておいてほしいこと
MySQL 5.7にやられないためにおぼえておいてほしいことMySQL 5.7にやられないためにおぼえておいてほしいこと
MySQL 5.7にやられないためにおぼえておいてほしいことyoku0825
 

What's hot (20)

SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っている
 
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
 
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング
 
リッチなドメインモデル 名前探し
リッチなドメインモデル 名前探しリッチなドメインモデル 名前探し
リッチなドメインモデル 名前探し
 
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはがんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
 
Pythonによる黒魔術入門
Pythonによる黒魔術入門Pythonによる黒魔術入門
Pythonによる黒魔術入門
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
 
イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)
 
これからSpringを使う開発者が知っておくべきこと
これからSpringを使う開発者が知っておくべきことこれからSpringを使う開発者が知っておくべきこと
これからSpringを使う開発者が知っておくべきこと
 
SQLアンチパターン~ファントムファイル
SQLアンチパターン~ファントムファイルSQLアンチパターン~ファントムファイル
SQLアンチパターン~ファントムファイル
 
WayOfNoTrouble.pptx
WayOfNoTrouble.pptxWayOfNoTrouble.pptx
WayOfNoTrouble.pptx
 
Node js 入門
Node js 入門Node js 入門
Node js 入門
 
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。 【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方
 
PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門
 
SQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するかSQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するか
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
 
マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!
 
MySQL 5.7にやられないためにおぼえておいてほしいこと
MySQL 5.7にやられないためにおぼえておいてほしいことMySQL 5.7にやられないためにおぼえておいてほしいこと
MySQL 5.7にやられないためにおぼえておいてほしいこと
 

Similar to Node.js Native ESM への道 〜最終章: Babel / TypeScript Modules との闘い〜

VSハッカソン TypeScript ハンズオン
VSハッカソン TypeScript ハンズオンVSハッカソン TypeScript ハンズオン
VSハッカソン TypeScript ハンズオンKazuhide Maruyama
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejsTakayoshi Tanaka
 
Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京
Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京
Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京hecomi
 
Nodejuku01 ohtsu
Nodejuku01 ohtsuNodejuku01 ohtsu
Nodejuku01 ohtsuNanha Park
 
OpenGLプログラミング
OpenGLプログラミングOpenGLプログラミング
OpenGLプログラミング幸雄 村上
 
Denoで動くReactフレームワークAleph.jsでポートフォリオサイトをリプレイスした話
Denoで動くReactフレームワークAleph.jsでポートフォリオサイトをリプレイスした話Denoで動くReactフレームワークAleph.jsでポートフォリオサイトをリプレイスした話
Denoで動くReactフレームワークAleph.jsでポートフォリオサイトをリプレイスした話yuosaka
 
つながるJavaとTFS
つながるJavaとTFSつながるJavaとTFS
つながるJavaとTFS__Black
 
Aspnet mvc 6の今を紹介
Aspnet mvc 6の今を紹介Aspnet mvc 6の今を紹介
Aspnet mvc 6の今を紹介Makoto Nishimura
 
鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用について鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用についてmichiosuzuki
 
鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用について鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用についてmichiosuzuki
 
Babelで先取り次世代javascript
Babelで先取り次世代javascriptBabelで先取り次世代javascript
Babelで先取り次世代javascriptTsuyoshi Maeda
 
新しい Visual Studio & .NET と新時代のアーキテクチャ
新しい Visual Studio & .NET と新時代のアーキテクチャ新しい Visual Studio & .NET と新時代のアーキテクチャ
新しい Visual Studio & .NET と新時代のアーキテクチャ慎一 古賀
 
Mozillaのビルドインフラ
MozillaのビルドインフラMozillaのビルドインフラ
MozillaのビルドインフラMakoto Kato
 
Embedded framework and so on
Embedded framework and so onEmbedded framework and so on
Embedded framework and so ontoyship
 
20121217 jawsug-yokohama
20121217 jawsug-yokohama20121217 jawsug-yokohama
20121217 jawsug-yokohamaTetsuya Chiba
 

Similar to Node.js Native ESM への道 〜最終章: Babel / TypeScript Modules との闘い〜 (18)

ES6 in Practice
ES6 in PracticeES6 in Practice
ES6 in Practice
 
VSハッカソン TypeScript ハンズオン
VSハッカソン TypeScript ハンズオンVSハッカソン TypeScript ハンズオン
VSハッカソン TypeScript ハンズオン
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs
 
Clang Modules
Clang ModulesClang Modules
Clang Modules
 
Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京
Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京
Hello, C++ + JavaScript World! - Boost.勉強会 #11 東京
 
Nodejuku01 ohtsu
Nodejuku01 ohtsuNodejuku01 ohtsu
Nodejuku01 ohtsu
 
OpenGLプログラミング
OpenGLプログラミングOpenGLプログラミング
OpenGLプログラミング
 
Denoで動くReactフレームワークAleph.jsでポートフォリオサイトをリプレイスした話
Denoで動くReactフレームワークAleph.jsでポートフォリオサイトをリプレイスした話Denoで動くReactフレームワークAleph.jsでポートフォリオサイトをリプレイスした話
Denoで動くReactフレームワークAleph.jsでポートフォリオサイトをリプレイスした話
 
Net fringejp2016
Net fringejp2016Net fringejp2016
Net fringejp2016
 
つながるJavaとTFS
つながるJavaとTFSつながるJavaとTFS
つながるJavaとTFS
 
Aspnet mvc 6の今を紹介
Aspnet mvc 6の今を紹介Aspnet mvc 6の今を紹介
Aspnet mvc 6の今を紹介
 
鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用について鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用について
 
鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用について鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用について
 
Babelで先取り次世代javascript
Babelで先取り次世代javascriptBabelで先取り次世代javascript
Babelで先取り次世代javascript
 
新しい Visual Studio & .NET と新時代のアーキテクチャ
新しい Visual Studio & .NET と新時代のアーキテクチャ新しい Visual Studio & .NET と新時代のアーキテクチャ
新しい Visual Studio & .NET と新時代のアーキテクチャ
 
Mozillaのビルドインフラ
MozillaのビルドインフラMozillaのビルドインフラ
Mozillaのビルドインフラ
 
Embedded framework and so on
Embedded framework and so onEmbedded framework and so on
Embedded framework and so on
 
20121217 jawsug-yokohama
20121217 jawsug-yokohama20121217 jawsug-yokohama
20121217 jawsug-yokohama
 

More from Teppei Sato

サイボウズの給与交渉戦 - Boss Side -
サイボウズの給与交渉戦 - Boss Side -サイボウズの給与交渉戦 - Boss Side -
サイボウズの給与交渉戦 - Boss Side -Teppei Sato
 
Recent compat-table issues
Recent compat-table issuesRecent compat-table issues
Recent compat-table issuesTeppei Sato
 
kintoneがAWSで目指すDevOpsQAな開発
kintoneがAWSで目指すDevOpsQAな開発kintoneがAWSで目指すDevOpsQAな開発
kintoneがAWSで目指すDevOpsQAな開発Teppei Sato
 
Automated Dependency Updates with Renovate
Automated Dependency Updates with RenovateAutomated Dependency Updates with Renovate
Automated Dependency Updates with RenovateTeppei Sato
 
君はyarn.lockをコミットしているか?
君はyarn.lockをコミットしているか?君はyarn.lockをコミットしているか?
君はyarn.lockをコミットしているか?Teppei Sato
 
サイボウズのフロントエンド開発 現在とこれからの挑戦
サイボウズのフロントエンド開発 現在とこれからの挑戦サイボウズのフロントエンド開発 現在とこれからの挑戦
サイボウズのフロントエンド開発 現在とこれからの挑戦Teppei Sato
 
サイボウズの現在と未来
サイボウズの現在と未来サイボウズの現在と未来
サイボウズの現在と未来Teppei Sato
 
離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ー
離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ー離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ー
離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ーTeppei Sato
 
サイボウズの開発を支えるKAIZEN文化
サイボウズの開発を支えるKAIZEN文化サイボウズの開発を支えるKAIZEN文化
サイボウズの開発を支えるKAIZEN文化Teppei Sato
 
JavaScript Language Update 2016 (LLoT)
JavaScript Language Update 2016 (LLoT)JavaScript Language Update 2016 (LLoT)
JavaScript Language Update 2016 (LLoT)Teppei Sato
 
You Don't Know ES Modules
You Don't Know ES ModulesYou Don't Know ES Modules
You Don't Know ES ModulesTeppei Sato
 
Closure Compiler Updates for ES6
Closure Compiler Updates for ES6Closure Compiler Updates for ES6
Closure Compiler Updates for ES6Teppei Sato
 
Our wish to Flowtype
Our wish to FlowtypeOur wish to Flowtype
Our wish to FlowtypeTeppei Sato
 
Flowtype Introduction
Flowtype IntroductionFlowtype Introduction
Flowtype IntroductionTeppei Sato
 
Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略
Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略
Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略Teppei Sato
 
本当のClosure Compilerをお見せしますよ。
本当のClosure Compilerをお見せしますよ。本当のClosure Compilerをお見せしますよ。
本当のClosure Compilerをお見せしますよ。Teppei Sato
 
JavaScript Unit Test Why? What? How?
JavaScript Unit Test Why? What? How?JavaScript Unit Test Why? What? How?
JavaScript Unit Test Why? What? How?Teppei Sato
 

More from Teppei Sato (20)

サイボウズの給与交渉戦 - Boss Side -
サイボウズの給与交渉戦 - Boss Side -サイボウズの給与交渉戦 - Boss Side -
サイボウズの給与交渉戦 - Boss Side -
 
Recent compat-table issues
Recent compat-table issuesRecent compat-table issues
Recent compat-table issues
 
kintoneがAWSで目指すDevOpsQAな開発
kintoneがAWSで目指すDevOpsQAな開発kintoneがAWSで目指すDevOpsQAな開発
kintoneがAWSで目指すDevOpsQAな開発
 
Automated Dependency Updates with Renovate
Automated Dependency Updates with RenovateAutomated Dependency Updates with Renovate
Automated Dependency Updates with Renovate
 
君はyarn.lockをコミットしているか?
君はyarn.lockをコミットしているか?君はyarn.lockをコミットしているか?
君はyarn.lockをコミットしているか?
 
サイボウズのフロントエンド開発 現在とこれからの挑戦
サイボウズのフロントエンド開発 現在とこれからの挑戦サイボウズのフロントエンド開発 現在とこれからの挑戦
サイボウズのフロントエンド開発 現在とこれからの挑戦
 
サイボウズの現在と未来
サイボウズの現在と未来サイボウズの現在と未来
サイボウズの現在と未来
 
離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ー
離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ー離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ー
離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ー
 
サイボウズの開発を支えるKAIZEN文化
サイボウズの開発を支えるKAIZEN文化サイボウズの開発を支えるKAIZEN文化
サイボウズの開発を支えるKAIZEN文化
 
SPAと覚悟
SPAと覚悟SPAと覚悟
SPAと覚悟
 
JavaScript Language Update 2016 (LLoT)
JavaScript Language Update 2016 (LLoT)JavaScript Language Update 2016 (LLoT)
JavaScript Language Update 2016 (LLoT)
 
You Don't Know ES Modules
You Don't Know ES ModulesYou Don't Know ES Modules
You Don't Know ES Modules
 
Closure Compiler Updates for ES6
Closure Compiler Updates for ES6Closure Compiler Updates for ES6
Closure Compiler Updates for ES6
 
Our wish to Flowtype
Our wish to FlowtypeOur wish to Flowtype
Our wish to Flowtype
 
Effective ES6
Effective ES6Effective ES6
Effective ES6
 
Flowtype Introduction
Flowtype IntroductionFlowtype Introduction
Flowtype Introduction
 
Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略
Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略
Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略
 
本当のClosure Compilerをお見せしますよ。
本当のClosure Compilerをお見せしますよ。本当のClosure Compilerをお見せしますよ。
本当のClosure Compilerをお見せしますよ。
 
DockerがYAVAY!
DockerがYAVAY!DockerがYAVAY!
DockerがYAVAY!
 
JavaScript Unit Test Why? What? How?
JavaScript Unit Test Why? What? How?JavaScript Unit Test Why? What? How?
JavaScript Unit Test Why? What? How?
 

Recently uploaded

プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価sugiuralab
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directoryosamut
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxAtomu Hidaka
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000Shota Ito
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールsugiuralab
 

Recently uploaded (7)

プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツール
 

Node.js Native ESM への道 〜最終章: Babel / TypeScript Modules との闘い〜

  • 1. Na#ve ESM への道 ∼ 最終章: Babel / TypeScript Modules との闘い ∼ Node 学園 35 時限目 / 2021-02-24 @teppeis 1
  • 2. 自己紹介 • @teppeis / Teppei Sato • サイボウズから来ました。 • もちろん We are hiring!!! • プロダクト開発チーム • フロントエンドエキスパートチーム 2
  • 3. Node.js の ES Modules 対応って どうなったの? 3
  • 4. 前回までのあらすじ 2015 年の ES Modules (ESM) 策定からときは流れ、Node.js での ESM 対応は混迷を極めた1 。 しかし 2018 年 10 月、 Node.js Modules Team は ESM 対応計画 2 を なんとかまとめあげ、ようやく実装が進んでいった。 そして 2020 年末にはその計画が実装完了し、2021 年は Na8ve ESM 時代が到来するかに見えた。 2 Plan for New Modules Implementa5on · nodejs/modules 1 前回スライドを参照: You Don't Know ES Modules, Teppei Sato (2016) 4
  • 5. Node.js ESM 実装状況 基本機能は Node v12.20+, v14.13+ で フラグ無し で提供済み3 • Na$ve ESM import / export • CommonJS interoperability (CJS Interop) • package.json imports / exports mapping 3 ESM import / export と CJS interop は v15 系で stability: stable, v12, v14 系は次の minor リリースで stable になる 予定。imports / exports mapping は v15 系で stable になったが v12, v14 は未定。 5
  • 6. 2021 年は Na've ESM の時代に? • 前述の通り、Node v12 系以上は ESM を実装済み • Node v10 は 2021-04-30 に EOL • つまり、5 月以降は全 Node 環境で Na5ve ESM が利用可能! • やったー、全部 ESM で書こうぜー 6
  • 11. CJS Interop CJS から ESM へスムーズな移行を進めるために検討されてきた相 互互換機能 • CJS から ESM をロードできる • ESM から CJS をロードできる 仕様の複雑さと既存パッケージとの互換性から、ここまで Node の ESM 対応を遅らせてきた鬼門でもある 11
  • 12. import ESM from CJS // esm.mjs export default "foo"; export const named = "bar"; // cjs.js const { default: def, named } = await import("./esm.mjs"); //// def: "foo" //// named: "bar" • dynamic import を使用 • ESM と同じ使い勝手で、違和感はない 12
  • 13. import CJS from ESM: named import // cjs.js exports.named = "foo"; // esm.mjs import { named } from "./cjs.js"; //// named: "foo" • exports のプロパティが named import される 13
  • 14. import CJS from ESM: default import // cjs.js module.exports = "foo"; // esm.mjs import cjs from "./cjs.js"; //// cjs: "foo" • module.exports が default import される 14
  • 15. ところで Babel と TypeScript はどうだっけ? 15
  • 16. Babel / TypeScript の ESM → CJS 変換 // Before (ESM in Babel) export default "foo"; // After (CJS) Object.defineProperty(exports, "__esModule", { value: true }); exports.default = "foo"; • default export は、exports.default に変換される • おや?Node.js の CJS Interop と仕様が違うぞ! 16
  • 17. Babel / TypeScript で CJS にトランスパイルされた npm パッケージを Na5ve ESM からロードしたいけど // node_modules/foo/index.ts export default "foo!"; // main.mjs import foo from "foo"; //// foo: { default: "foo!" } default export された値を 期待通りに default import できない! 17
  • 18. 無理矢理書くこともできるが // node_modules/foo/index.ts export default "foo!"; // main.mjs import def from "foo"; const { foo } = def; //// foo: "foo!" これなら動くが、import したい全ての npm パッケージについて内 部的に Babel / TS を使っているかを調べて書き分ける必要があり、 書き味も体験も非常に厳しい。 18
  • 19. Babel Modules ≠ ES Modules TypeScript Modules ≠ ES Modules 19
  • 20. ここまでは Babel / TypeScript ベースの CJS な npm パッケージを Na5ve ESM からロードする話 20
  • 21. TypeScript で Na-ve ESM を書くのは もっと厳しい 21
  • 22. TypeScript で Na-ve ESM を出力したい 公式にはサポートされてないので基本的に厳しい • .mjs を出力できない • .mjs を入力できない • moduleResolution:node が Node の ESM 仕様と異なる • imports / exports mapping に未対応 22
  • 23. TypeScript で無理矢理書くこともできるが // foo.ts export default "foo!"; // main.ts import foo from "./foo.js"; import 文で拡張子を省略せず .js を指定し(.ts ではない)、 pacakge.json で type:"module" にすることで、変換後に Na$ve ESM として無理矢理動かすことは可能。 しかし ts-node など周辺ツールが未対応で jest も動かせない。 23
  • 24. TypeScript Modules を import 不可能 // node_modules/foo/index.ts export default "foo!"; // main.ts import def from "foo"; const { foo } = def; //// TS2339 Error: Property 'foo' does not exist on type 'String'. TS が CJS に変換したパッケージに同梱された型定義が Node ESM 仕様と食い違うため、TS Na-ve ESM から default import しようと すると 型エラーかランタイムエラーのどちらか になる。 24
  • 26. Babel / TypScript 陣営の動き • Babel は新オプション importInterop:"node" を検討している4 • TypeScript は最近の動きは見えない • 2020 年 3 月に新しい moduleResolution フラグを作る方針 というコメント5 があったが、続報なし 5 Design Mee*ng Notes, 3/27/2020 · Issue #37897 · microso=/TypeScript 4 Implement importInterop: "node" op+on for module transforms by nicolo-ribaudo · Pull Request #12838 · babel/babel 26
  • 27. Babel / TypeScript が対応しても • 既に npm 公開された大量の Babel / TS Modules はトランスパイ ル済みであり、挙動は変わらない • 更新のない Babel / TS Modules は Na4ve ESM からは扱いにく い存在として残り続ける • npm 界に ESM 対応のアップデートが広がるのを待つしかない • 時間が解決するのか... 27
  • 28. Sindre はどうしてるの? そんなこともあろうかと、既存の TypeScript ベースの npm パッケージにあら かじめ workaround を仕込んでいた!6 export default got; module.exports = got; module.exports.default = got; module.exports.__esModule = true; これで TypeScript からも Na-ve ESM からも default import 可能。 ただし dirty hack で副作用もあるのでご利用は計画的に。 6 h$ps:/ /github.com/sindresorhus/got/blob/v11.8.1/source/index.ts#L127-L130 28
  • 29. ところで、 どうして Na$ve ESM を書きたいんだっけ? • 皮肉にも、CJS Interop の実装が進んだ結果、CJS でも特に不満 がない状況になりつつある • ESM のセールスポイントだった tree-shaking も、静的解析の発 展により Webpack や Parcel が CJS にも対応し始めた • それでも ESM を書くと キマる んだ! 29
  • 30. まとめ • Na$ve ESM は Node.js の中だけなら 5 月から自由に使える • しかし Babel / TypeScript ベースの npm パッケージを default import すると いろいろハマって厳しい • この状況は各種ツールと既存 npm パッケージが更新されるまでだいぶ続き そう • TypeScript で Na$ve ESM が書けるようになるのはまだまだ先 • しばらくは TypeScript で CJS を書く今の生活が続きそう 30