Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
cookpad summer internship 2018 - JavaScript
Search
Kazuhito Hokamura
September 18, 2018
Technology
0
9.4k
cookpad summer internship 2018 - JavaScript
Kazuhito Hokamura
September 18, 2018
Tweet
Share
More Decks by Kazuhito Hokamura
See All by Kazuhito Hokamura
TypeScriptとGraphQLで実現する 型安全なAPI実装 / TSKaigi 2024
hokaccha
5
4.4k
Kotlin製のGraphQLサーバーをNode.jsでモジュラモノリス化している話
hokaccha
0
3.5k
GraphQLの負債と向き合うためにやっていること
hokaccha
2
1.4k
ユビーのアーキテクチャに対する取り組み
hokaccha
1
400
RailsエンジニアのためのNext.js入門
hokaccha
7
20k
Cookpad Summer Internship 2021 Web Frontend
hokaccha
0
7.2k
巨大なモノリシック Rails アプリケーションの マイクロサービス化戦略 / 2019 microservices in cookpad
hokaccha
3
3.8k
巨大なRailsアプリケーションを「普通」にするための取り組み
hokaccha
1
960
Web Frontend Improvement in Cookpad
hokaccha
1
1.1k
Other Decks in Technology
See All in Technology
Google Cloud Next 2025 Recap 生成AIモデルとマーケティングでのコンテンツ生成 / Generative AI models and content creation in marketing
kyou3
0
180
LangfuseではじめるAIアプリのLLMトレーシング
codenote
0
150
MCPを理解する
yudai00
14
10k
AIとSREで「今」できること
honmarkhunt
3
720
Cursorを全エンジニアに配布 その先に見据えるAI駆動開発の未来 / 2025-05-13-forkwell-ai-study-1-cursor-at-loglass
itohiro73
2
500
Simplify! 10 ways to reduce complexity in software development
ufried
2
250
MCP でモノが動くとおもしろい/It is interesting when things move with MCP
bitkey
2
490
問 1:以下のコンパイラを証明せよ(予告編) #kernelvm / Kernel VM Study Kansai 11th
ytaka23
3
520
Cursorをチョッパヤインタビューライターにチューニングする方法 / how to tuning cursor for interview write
shuzon
2
210
名単体テスト 禁断の傀儡(モック)
iwamot
PRO
1
230
製造業向けIoTソリューション提案資料.pdf
haruki_uiru
0
250
使えるデータ基盤を作る技術選定の秘訣 / selecting-the-right-data-technology
pei0804
6
1.2k
Featured
See All Featured
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
700
RailsConf 2023
tenderlove
30
1.1k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Fontdeck: Realign not Redesign
paulrobertlloyd
84
5.5k
Bash Introduction
62gerente
613
210k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
30
2.4k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
How STYLIGHT went responsive
nonsquared
100
5.5k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
45
9.5k
How to Ace a Technical Interview
jacobian
276
23k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
Transcript
JavaScript クックパッド サマーインターンシップ 10 Day Tech for service engineers
Agenda 1. JavaScript 2. TypeScript 3. React
https://code.visualstudio.com/
JavaScript
JavaScript •ブラウザで動作するプログラミング言語 •HTMLを動的に変更してインタラクティブなWebサイト を構築するために使われる •最近はNode.jsやReactNativeなどブラウザ以外でも動 作する環境も多くある
https://developer.mozilla.org/ja/
Development/Debug
基本文法
// جຊతʹconstΛ͏ const str = 'x'; const arr = [1,
2, 3]; // ఆٛޙʹ࠶ೖ͕ඞཁͳ߹letΛ͏ let message; if (err) { message = 'error!'; } else { message = 'ok!'; } 変数宣言
const num1 = 100; const num2 = 3.141592; const str1
= 'xxx'; const str2 = "yyy"; const str3 = `foo${str}bar`; const x = null; const bool = true; const re = /foo.+$/i; リテラル
const arr = [1, 2, 3]; arr[0] //=> 1 //
for-ofͰΠςϨʔγϣϯ for (const v of arr) { console.log(v); // 1, 2, 3 } // ֤छϝιουͰΠςϨʔγϣϯ arr.forEach((v) => { console.log(v); }) //=> 1, 2, 3 arr.map((v) => { return v * 2; }); //=> [2, 4, 6] arr.filter((v) => { return v > 1; }); //=> [2, 3] 配列
const obj = { foo: 'bar', fn: () => {
console.log('hello!') } }; obj.foo; //=> 'bar' obj.fn(); //=> hello! obj.a = 'b'; // Shorthand property names const x = 1; const y = 2; const obj2 = { x, y }; // { x: x, y: y } オブジェクト
// function จ function square(x) { return x * x;
} // function ࣜ const square = function(x) { return x * x; }; // Arrow function ࣜ const square = (x) => { return x * x; }; // Ҿ͕1ͭͷͱ͖ () ΛলུՄೳɻ{ } Λলུͨ͠߹୯Ұͷ͕ࣜॻ͚ͯͦͷࣜͷ͕return͞ΕΔ const square = x => x * x; square(5); //=> 25 関数
class Greeter { constructor(name) { this.name = name; } greet()
{ return `Hello ${this.name}!`; } } const g = new Greeter('hokaccha'); g.greet(); //=> 'Hello hokaccha!'; Class
Modules // lib/Greeter.js export default class Greeter { constructor(name) {
this.name = name; } greet() { return `Hello ${name}!`; } } export function hello(name) { return `Hello ${name}!`; }
Modules // app.js // default import import Greeter from './lib/Greeter';
// named import import { hello } from './lib/Greeter'; // mixed import Greeter, { hello } from './lib/Greeter';
非同期処理
同期 // Ծʹwait͕ॲཧΛϒϩοΫͨ͠ͱ͢Δͱ͍ͬͯΔؒʹԿͰ͖ͳ͍ wait(1000); doSomething(); 非同期 // ͕ͪ࣌ؒܦաͨ͠Β࣮ߦ͞ΕΔؔΛొ wait(1000, ()
=> { doSomething(); }); // ܧଓͯ͠ॲཧΛଓ͚ΒΕΔ
非同期処理の実装 •callback •Promise •async/await
callback http.get('/a', response => { // ... });
callback http.get('/a', responseA => { http.get('/b', responseB => { http.get('/c',
responseC => { // ... }); }); });
callback http.get('/a', (err, responseA) => { if (err) { return
handleError(err); } http.get('/b', (err, responseB) => { if (err) { return handleError(err); } http.get('/c', (err, responseC) => { if (err) { return handleError(err); } // ... }); }); });
Promise function get(url) { return new Promise((resolve, reject) => {
http.get(url, (err, response) => { if (err) { reject(err); } else { resolve(response); } }); }); } get('/a').then(response => { // do something }).catch(err => { // error handling });
Promise get('/a') .then(responseA => { return get('/b'); }) .then(responseB =>
{ return get('/c'); }) .then(responseC => { // do something }) .catch(err => { // error handling });
async/await async function req() { const responseA = await get('/a');
const responseB = await get('/b'); const responseC = await get('/c'); return responseC; } async function f() { try { const res = await req(); // do something } catch (err) { // error handling } }
DOM
DOM •HTML文書をプログラムから扱うためのAPI仕様 •JavaScriptの言語仕様とは別に仕様が策定されている
<!DOCTYPE html> <html> <head> <script src="app.js" defer></script> </head> <body> <button
id="button">Click Me!</button> <div id="message"></div> </body> </html>
// HTMLʹॻ͔Ε͍ͯΔ button ཁૉΛऔಘ const button = document.getElementById('button'); // click͞Εͨͱ͖ͷϋϯυϥʔΛొ
button.addEventListener('click', async () => { // HTTP RequestͰAPIΛݺͼग़͢ const response = await fetch('/message'); const body = await response.json(); // #messageͷ༰Λॻ͖͑Δ document.getElementById('message').innerHTML = body.message; });
// HTMLʹॻ͔Ε͍ͯΔ button ཁૉΛऔಘ const button = document.getElementById('button'); // click͞Εͨͱ͖ͷϋϯυϥʔΛొ
button.addEventListener('click', async () => { // HTTP RequestͰAPIΛݺͼग़͢ const response = await fetch('/message'); const body = await response.json(); // #messageͷ༰Λॻ͖͑Δ document.getElementById('message').innerHTML = body.message; }); %0."1*
TypeScript
TypeScript •Microsoftによって開発されているプログラミング言語 •JavaScriptに静的型付けの機能を取り入れたAltJS •JavaScriptのスーパーセット
JavaScript function greeter(person) { return "Hello, " + person; }
const user = "hokaccha"; const message = greeter(user);
TypeScript function greeter(person: string): string { return "Hello, " +
person; } const user = "hokaccha"; const message = greeter(user);
TypeScript function greeter(person: string): string { return "Hello, " +
person; } const user = [1, 2, 3]; const message = greeter(user); //=> error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.
Basic Types let str: string; let num: number; let bool:
boolean; let arr: string[]; let fn: (a: string, b: string) => boolean; type StrOrArr = string | string[]; type StrOrNull = string | null;
Generics class Queue<T> { private data: T[] = []; enqueue(item:
T) { return this.data.push(item); } dequeue(): T { return this.data.shift(); } } const queue = new Queue<number>(); queue.enqueue(10); queue.enqueue('x'); // Error!
Generics interface User { name: string; } async function getUser():
Promise<User> { const response = await fetch('/user'); const body = await response.json(); return body; } async function f() { const user: User = await getUser(); }
Gradual Typing
Gradual Typing •静的片付けを部分的に導入することができる型システム •TypeScriptでは型検査をしないany型により実現される
// Ҿͷܕ͕anyʹͳΔͷͰͲΜͳܕͰ௨Δ function greeter(person) { return "Hello, " + person;
} const user = [1, 2, 3]; const message = greeter(user); //=> ok Gradual Typing
Structural Subtyping
•部分型かどうかを構造が同じかどうかで判定する •静的型におけるダックタイピング Structural Subtyping
interface Person { firstName: string; lastName: string; } class User
{ firstName: string; lastName: string; } const user1: Person = new User(); // ok const user2: Person = { firstName: "Kazuhito", lastName: "Hokamura" }; // ok Structural Subtyping
class User { name: string; } class Product { name:
string; } const user: User = new Product(); // ok const product: Product = new User(); // ok Structural Subtyping
React
JavaScript Frameworks •jQuery •Backbone.js •Angular •Vue.js •React
None
class App extends React.Component { constructor(props) { super(props); this.state =
{ name: '' }; } handleInput(event) { this.setState({ name: event.target.value }); } render() { return <div> <input type="text" onInput={event => this.handleInput(event)} /> <div>Hello, {this.state.name}</div> </div>; } } ReactDOM.render(<App />, document.getElementById('app'));
class Button extends React.Component { render() { return <button onClick={()
=> this.props.onClick()}> <i className={`icon-${this.props.icon}`} /> {this.props.label} </button> } } <Button label="Click Me" icon="caret" onClick={() => alert('Hi!')} /> JSX
None
Lists and Keys class App extends React.Component { render() {
// users: [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }] const items = this.props.users.map(user => { return <li key={user.id}>{user.name}</li>; }); return <div>{items}</div>; } }
interface State { name: string; } interface Props { defaultName:
string; } class App extends React.Component<Props, State> { constructor(props: Props) { super(props); this.state = { name: props.defaultName }; } handleClick() { this.setState({ a: 'b' }); // Error } } <App foo="bar" />; // Error With TypeScript
設計パターン
stateとprops •state: コンポーネント自身が管理している状態 •props: 親コンポーネントから受け取る不変なパラメータ
Presentational Component •データを元にどういうviewを構築するかだけに専念する •状態を持たないStatelessなコンポーネントとして作る •親コンポーネントからもらうpropsのみに依存する
class Greeter extends React.Component<{}, {}> { render() { return <div
className="greeter">Hello, {this.props.name}</div>; } } // ୯ͳΔؔͱͯ͠ఆٛͰ͖Δ function Greeter(props) { return <div className="greeter">Hello, {this.props.name}</div>; } Stateless Component
Container Component •ツリーのルートでstateを持つコンポーネント •子のコンポーネントに状態を渡してツリーを構築する •イベントをハンドリングしてstateの更新をおこなう
class App extends React.Component { constructor(props) { super(props); this.state =
{ name: '' }; } handleInput(event) { this.setState({ name: event.target.value }); } render() { return <div> <input type="text" onInput={event => this.handleInput(event)} /> <Greeter name={this.state.name} /> </div>; } } Container Component
Container Component Stateless Component
1. イベント発生
1. イベント発生 2. 更新通知
1. イベント発生 2. 更新通知 3. state更新
1. イベント発生 2. 更新通知 3. state更新 4. DOM更新
Lifecycle
Component Lifecycle
Fetch data class App extends React.Component { constructor(props) { super(props);
this.state = { name: '' }; } async componentDidMount() { const response = await fetch('/user'); const body = await response.json(); this.setState({ name: body.name }); } render() { // ... } }
Practice
1. Rubyのサーバーから書籍のリストを取得して表示 2. タイトルでインクリメンタルサーチする機能を実装 3. 各フィールドでソートできる機能を実装 4. スタイルをいい感じにする
環境構築 $ npm install -g create-react-app $ create-react-app booklist-front \
--scripts-version=@hokaccha/create-react-app-ts-dev $ cd booklist-front $ yarn start