Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
TypeScript の class を使い倒す
Search
Takuya Eguchi (egch)
July 22, 2024
Technology
59
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
TypeScript の class を使い倒す
Takuya Eguchi (egch)
July 22, 2024
More Decks by Takuya Eguchi (egch)
See All by Takuya Eguchi (egch)
Next.js に疲れた私は Vue3 に癒やされた
egch
0
340
Secure な UX のために Content Security Policy について知っておこう
egch
0
74
package.json がすごい
egch
0
150
Nuxt.js のインスタンスライフサイクル総点検
egch
0
420
Webエンジニアのデザイン実装との付き合い方
egch
0
330
20200528 - GCPでもサーバーレスでRubyりたい!
egch
0
140
VeeValidate の"穴"を踏み抜いてしまった
egch
1
930
継続的に楽しくプログラミングするには - 2018/11/3 Rails Girls Sendai
egch
0
120
Other Decks in Technology
See All in Technology
3つのアプローチで目指す チームを強くするAI駆動開発
thkt
0
140
MCPゲートウェイを作って運用してわかったこと — Agent時代の権限管理の現在地
mtpooh
10
3.2k
自分で立ててみるLLMサービス
y_sera15
0
150
Lambda MicroVMsが分からなすぎたので使い所を1から考えてみた
tsukuboshi
2
450
DWH の限界突破! AI エージェント向け爆速リアルタイムデータ基盤 ClickHouse
jozono
1
320
Google Cloud Next Tokyo 26登壇時のスクリプト
recruitengineers
PRO
0
210
スキルを作る、その前に!複数人で使われるスキルを 作るためのプロセス
junkifurukawa
2
360
分析AIエージェントを育てる、動く環境を育てる
codatum
1
670
AgentCoreで実践するハーネスエンジニアリング
yakumo
1
290
Snapshot Testing in Practice: Predictable and Reliable SwiftUI Views
fespinoza
0
160
実体験から学ぶ分析エージェントの開発と運⽤
recruitengineers
PRO
8
1.8k
V8のArray.prototype.flatを最大約20倍速くするまでと、巨大OSSへの大規模コミットの道のり
riyaamemiya
0
110
Featured
See All Featured
BBQ
matthewcrist
90
10k
エンジニアに許された特別な時間の終わり
watany
109
250k
Skip the Path - Find Your Career Trail
mkilby
1
250
The Cost Of JavaScript in 2023
addyosmani
55
10k
So, you think you're a good person
axbom
PRO
2
2.2k
Rails Girls Zürich Keynote
gr2m
96
14k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
WCS-LA-2024
lcolladotor
0
860
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Tell your own story through comics
letsgokoyo
1
1.1k
Thoughts on Productivity
jonyablonski
76
5.4k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
700
Transcript
TypeScript の Class を使い倒す 💪 2024/07/22 Sendai Front-End User Group
自己紹介 江口 拓弥 SFEUG 運営メンバーの1人 2018年に東京から仙台に移住 2019年から複数プロジェクトの新規事業開発やってます 1児の父です👶 akathea_
😢 こんなことありませんか? 1. API の response 型を バックエンドとフロントエンド 両方で定義するのが辛い 2.
フロントエンドでもバックエンドでも 値のバリデーション処理を書くのが辛い
A. GraphQL
おわり
✋ ちょっとまった!
Monorepo はどうだろう? @sick-project @sick-project/dto @sick-project/next @sick-project/nest get-foo.ts post-bar.ts
パッケージ module moduleResolution ESNext Bundler CommonJS NodeNext (target: ES2021から) @sick-project/dto
? ? このアイデアの問題点 型の提供だけならそれでよいが、 NestJS 側で swagger や class-validator 等を使うとき DTO は class として定義が必要 → tsconfig が異なるためどうビルドすればいいのか...
💡 マルチバンドルすればいいのでは?
前回の LT で話した内容を参考に https://speakerdeck.com/akagire/package-dot-json-gasugoi
こんな感じを妄想🤔 @sick-project @sick-project/dto @sick-project/next @sick-project/nest dist get-foo.js post-bar.js src get-foo.ts
post-bar.ts es get-foo.js post-bar.js type get-foo.d.ts post-bar.d.ts
パッケージ module moduleResolution ESNext Bundler CommonJS NodeNext (target: ES2021から) @sick-project/dto
CommonJS NodeNext tsconfig の設定は NestJS に寄せた
package.json と tsconfig.json を環境ごとに用意... @sick-project/dto src es dist package.json tsconfig.json
tsconfig.es.json { "exports": { ".": { "browser": "./es/index.js", "default": "./dist/index.js" } }, "types": "./dist/index.d.ts", "scripts": { "build:backend": "tsc -p tsconfig.json", "build:frontend": "tsc -p tsconfig.es.json" } } { "compilerOptions": { “module”: “CommonJS”, “target”: “ES2021” } } { "compilerOptions": { “module”: “ESNext”, “moduleResolution”: “NodeNext” } } ※tsconfigはだいぶ端折ってます
🎉 import できた! @sick-project/next/fetchFoo.ts import type { GetFoo } from
‘@sick-project/dto’; // 略 const res = await fetch(‘/foo’); const body: GetFoo = await res.body(); @sick-project/nest/foo-controller.ts import type { GetFoo } from ‘@sick-project/dto’; // 略 res.status(200).json<GetFoo>({ message: ‘foo’ });
😢 と、思っていたのか
es 向けビルド結果に decorator が混入 var __decorate = // 定義は略 import
{ ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty } from 'class-validator'; var GetFoo = /** @class */ (function () { function GetFoo () { } __decorate([ ApiProperty({ // description 等... }) IsNotEmpty() ], GetFoo.prototype, “type”, void 0); return GetFoo; }()); export { GetFoo }; この影響でフロントエンド環境に @nestjs/swagger, class-validator を入れないとビルドでエラー(ノ∀` ) →使いもしないのにインスコが必要で バンドルサイズ爆増
Strip Decorator https://www.npmjs.com/package/strip-decorators
ビルド結果 import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty
} from 'class-validator'; var GetFoo = /** @class */ (function () { function GetFoo () { } return GetFoo; }()); export { GetFoo }; 😢 decorator は消えたが、 import 文は消えてない dto の package.json へ “sideEffect”: false を指定で tree shaking されるが、 フロント側に @nestjs/swagger を install してないとビルドが通らない状況は変わらない class-validator をフロントエンドのリクエスト時のバリデーションで利用できなくなる
Strip Decorator の中身を覗いてみると... 👀
🤔 TypeScript Compiler API を使ってた https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API
TypeScript のトランスパイル処理をイジることができる サンプルとして、 • ES6 から d.ts ファイルの生成 • AST
を舐めて自作 linter を作る • moduleResolution のカスタマイズ などの魔改造コードが掲載されている
💡 これ使って 任意の decorator と import だけ 除去できるのでは?
😎 できた https://gist.github.com/akagire/38314038316c37afe115fd1025337af1
カスタムビルドの結果 Swagger に関する decorator だけ消すことができた →これでフロントエンドに @nestjs/swagger が不要になった! var __decorate
= // 定義は略 import { IsNotEmpty } from 'class-validator'; // 残ってる! var GetFoo = /** @class */ (function () { function GetFoo () { } __decorate([ IsNotEmpty() // 残ってる! ], GetFoo.prototype, “type”, void 0); return GetFoo; }()); export { GetFoo };
🤔 ・Compiler API は disclaimer にある通り なので、production で利用するのは心配 ・やりすぎてる感、やや難易度が高い印象 🎉
package.json × TypeScript × Compiler API を 組み合わせることで、互換性のない パッケージ間でも class をいい感じに共有! まとめ Keep in mind that this is not yet a stable API 💡 ・型共有の選択肢として十分ありだと思った ・フロントエンドのバンドルサイズ削減に 使えるかもしれない
おわり