ããã«ã¡ã¯ãã½ã¦ã¾ã¦ã® Software Engineer ã® hiroppy ã§ãããé£è¼ï¼ãã¡ã«ã«ãª Shopsããã¬ãªã¼ãã³ã¾ã§ã®éçºã®è£å´ã ã®æå¾ã¯ãWeb ããã³ãã¨ã³ãã®ç´¹ä»ããããã¨æãã¾ããã¡ã«ã«ãª Shops ã¯æ¢åã®ã¡ã«ã«ãªã¢ããªã®ä¸ã«ç¬ç«ãã Web ã¢ããªã±ã¼ã·ã§ã³ã¨ãã¦åãã¦ãã¾ããæ¬è¨äºã§ã¯ãã©ã®ãããªã©ã¤ãã©ãªãé¸å®ããã©ã®ããã«ã¢ã¼ããã¯ãã£ãè¨è¨ãã¦ãããã解説ãã¾ãã
ãªã Web ãªã®ãï¼
ã¢ããªã®ä¸ã§åãã¦ããã®ã§ããã°ãWebView ã§ã¯ãªãã¦ãè¯ãã¨æãã人ã¯ããã¨æãã¾ããä»åæ¡ç¨ãã 1 ã¤ã®çç±ã¨ãã¦ã¯ããªãªã¼ã¹ãæè»ãªç¹ãæãããã¾ããiOS/Android ã®ä¸¡æ¹ã«å¯¾ãã¦éçºãµã¤ã¯ã«ãæ©ãããã¨ãå¯è½ã§ãããã¾ãæ©è½è¿½å ããã°ä¿®æ£ã容æã§ããã©ã®ããã« WebView ã§åãã¦ãããã«ã¤ãã¦ã¯ã6 æ¥ç®ã®ã¡ã«ã«ãª Shops ã®ããã® WebView ã®æè¡ãåç
§ãã¦ãã ããã é£ããã£ãç¹ã¯ã¢ããªã®æåã Web ã§è¡¨ç¾ããç¹ã§ããä¾ãã°ãWeb ã® history
ã¨ã¢ããªã§ã¯æåã大ããç°ãªããback/replace ã§åç¾ããå¿
è¦ãããã¾ããã
UI Framework
Tailwind CSS ãªã©ã¨æ¯è¼ãã以ä¸ã®çç±ã§ chakra-ui ãæ¡ç¨ããã¾ããã
- æ¨æºã§ã¢ã¼ãã«ã ãã¼ãã«ãã¹ã±ã«ãã³ãªã©ã® UI ãæ´ã£ã¦ãã
- ãã©ã³ããã¹ãã¼ã¹ã®å¤ãªã©ã®ãã¶ã¤ã³ã«ã¼ã«ãå®ç¾©ããã¦ãã
- ã¢ã¯ã»ã·ããªãã£ãèæ ®ããã¦ãã
- CSS ãç´ ã§æ¸ãå¿ è¦ããªããæ¡å¼µã容æ
- Figma ãæä¾ããã¦ãã
ä¸æ¥ç®ã®è¨äºã®éããã¡ã«ã«ãª Shops ã®ããã¸ã§ã¯ã㯠monorepo ã§ããæ§ã ãªã¨ã³ã¸ãã¢ãã³ã¼ããæ¸ããã¨ãèæ ®ãã¾ãããUI ãæ´ã£ã¦ãã¦ããµã¤ãºãã¹ãã¼ã¹ãªã©ã®ã«ã¼ã«ãåå¨ããReact ã® props 㧠CSS ãè¨è¿°ãã¦ãããã¨ãã§ãã chakra-ui ã¯ãã¼ã å ¨ä½ã®éçºé度ãåä¸ããããã¨ãã§ãã¾ãããã¾ããFigma ãæä¾ããã¦ããç¹ãéè¦ã§ãããããã«ãããã¶ã¤ãã¨ã® UI ã®èªèãåããããããªãã¾ããããã¡ãªããã¨ãã¦ã¯ã bundle size ã大ããç¹ãæãããã¾ããã次æã¡ã¸ã£ã¼ãã¼ã¸ã§ã³ã§å ¥ãäºå®ã®æé©åãªã©ã¾ã ã¾ã æ¹åã®ä½å°ããããèªåãã¡ã§æ¹åã§ããç¹ããä¸æ¡ç¨ã®çç±ã¨ã¯è³ãã¾ããã§ããã
React Framework
以ä¸ã®çç±ã«ãã Next.js ãæ¡ç¨ãã¾ããã
- SSR/SSG ãå¯è½
- webpack ãªã©ã®è¨å®ãã¡ã¤ã«ãé è½ããã¦ãã
å¾è¿°ãã¾ãããCDN ã¨ã®ç¸æ§ã®è¯ãã¯ã¡ã«ã«ãª Shops ã§ã¯å¿ é ã§ãããSSR/SSG ãã§ãããã¬ã¼ã ã¯ã¼ã¯ã§ãªãã¨ããã¾ããã§ãããã¾ããUI ãã¬ã¼ã ã¯ã¼ã¯åæ§ã«èª°ã§ãããã³ãã¨ã³ãã®å®è£ ãã§ããç¶æ ã«ããå¿ è¦ããã£ãã®ã§ãwebpack ãªã©ã®ã¤ã³ãã©ãé è½ããå¿ è¦ããããä½ãæ¸ããªãã¦ãããç¨åº¦æé©åãããç¶æ ã§ãã«ãã§ããã®ã¯çæ³ã§ããããã¦ãOSS ã§ã®ã³ãã¥ããã£ãã¡ã³ããã³ã¹ã®å®å®æ§ãèã㦠Next.js ãæ¡ç¨ããã¾ããã
GraphQL
以ä¸ã®çç±ã«ãã Apollo Client ãæ¡ç¨ãã¾ããã
- React ã¨ã®è¦ªåæ§
- Reactive Variablesã«ããã¹ãã¼ã管ç
- Linkã«ããæè»æ§
- BFF ã§ä½¿ããã¦ãã Nest.js ã®ä¸èº«ã apollo-server ã§ãã
- graphql-codegen ã Apollo ã®å¯¾å¿ããã¦ãã
ã¡ã«ã«ãª Shops ã§ã¯ãBFF ã¨ã®ä¼è©±ã§ã¯ãã¹ã¦ GraphQL ãç¨ãã¦ãããGraphQL Client ã¯å¿ è¦ã§ãããApollo ã¯ãã£ãã·ã¥æ©æ§ãã¨ã¦ãåªç§ã§ããã React ã¨ã®è¦ªåæ§ãé«ãã§ããã¾ããç¶æ 管çã apollo-link-state ãéæ¨å¥¨ã¨ãªã v3 ã§å ¥ã£ã Reactive Variables 㨠React Hooks ã®ç¸æ§ã¯è¯ããã React Context çã§ã¯ãªããApollo ã«çµ±åãããã¨ã¨ãªãã¾ããã
Apollo ã«ã¯ Link ã¨ããæ©è½ãåãã£ã¦ãããã¡ã«ã«ãª Shops ã§ã¯ãããã¯ã¼ã¯ã¬ã¤ã¤ã¼ã«ãå
±éåãè¡ã£ã¦ãã¾ãããã¥ã¼ã¤ã³ã°ãæã£ã Link ã®å®è£
ãè¡ãéä¿¡ã®é åºæ
ä¿ãä¿è¨¼ããèªè¨¼å¦ççãé è½ãå
±éåããã¦ãã¾ãã以ä¸ã®ä¾ã®ããã«ãæåã®ã¢ã¯ã»ã¹ãè¡ãããã¨å
±éå¦çãå®è¡ããããããçµããã¾ã§ã¯ãquery/mutation
ã§çºçãããããã¯ã¼ã¯ã¢ã¯ã»ã¹ã¯ Link 㧠enqueue ããããã®é㯠view 㸠waiting
ã®ç¶æ
ãè¿ãã¹ã±ã«ãã³ã® UI ã¨ãªãã¾ããããã¦ãå
±éå¦çãçµãã次第ãdequeue ãã BFF ã¸ã®ã¢ã¯ã»ã¹ã許å¯ãããä»çµã¿ã§ãã
graphql-codegen ã Apollo ã® hooks ãçæã§ããç¹ã大ããã§ããå
è¿°ã®éã monorepo ãæ¡ç¨ãã¦ããããã åãã¤ã¯ããµã¼ãã¹ã® proto ãã TypeScript ã¸å¤æã BFF ã§ãã®åã使ã GraphQL ã¹ãã¼ããä½æããããã³ãã¨ã³ã㯠.gql
ãæ¸ã graphql-codegen 㧠BFF ã§çæãããã¹ãã¼ããã hooks ãå«ãã çæãã¡ã¤ã«ã React Components ãå©ç¨ããåãä¸æ°é貫ãã¦ããä»çµã¿ã容æã«ä½ããã¨ãã§ãã¾ããã
æå¾ã«ãApollo ã¯ãã¼ã¸ãã¼ã·ã§ã³ã®ã¦ã¼ãã£ãªãã£ããµãã¼ããã¦ãã¾ããRelay ã®ä»æ§ã§ããCursor Connectionsãæä¾ããããµã¼ãã¼å´ãä»æ§ã«å¾ã£ãã¹ãã¼ããè¿ãã°ãã¯ã©ã¤ã¢ã³ãå´ã¯ä»¥ä¸ã®ããã«typePolicyã«å®ç¾©ããã ãã§ç°¡åã«ãã¼ã¸ãã¼ã·ã§ã³ãå®ç¾ã§ãã¾ãã
import { relayStylePagination } from "@apollo/client/utilities";
export const typePolicies = {
Query: {
fields: {
products: relayStylePagination(["status"]),
},
},
};
ãã®ä»ä¸»è¦ã©ã¤ãã©ãª
- form: react-hook-form
- schema validator: yup
- i18n: i18next
- service worker: workbox
- test library: testing-library
- e2e: cypress
ãã£ãã·ã¥æ¦ç¥
ã¡ã«ã«ãª Shops ã¯ã¢ããªä¸ã§åãã¦ãããã¨ããé常㮠Web ãµã¼ãã¹ãããããã©ã¼ãã³ã¹ãæ±ãããã¾ããã¢ãã¤ã«ã®åç·é度ã¯å®å®ããªãããã常ã«ãã£ãã·ã¥ãæèããæ§æã«ãã¾ãããæåã«ä»¥ä¸ã®ã«ã¼ã«ãå®ç¾©ãã SSR ããã¹ããã©ããã誰ã§ãå¤æã§ããããã«ãã¾ããã
- SSR: SEO 対象 => ã客ãã¾ã®æ å ±ã«ä¾åããªãé¨åã§ä¸ã¤ Public ãªãã¼ã¸
- CSR: SEO å¯¾è±¡å¤ => ã客ãã¾ã®æ å ±ã«ä¾åããé¨å ã¾ã㯠Private ãªãã¼ã¸
ããã«ãããNext.js ã§ã¯ã客ãã¾ã®æ
å ±ãä¸åç¥ãå¿
è¦ããªãæ§æã¨ãªãã¾ãããã®ããã«è¨è¨ãããã¨ã«ãããå¹ççãã¤å®å
¨ã« CDN ã«ä¾åãããã¨ãå¯è½ã¨ãªãã¾ãããä¾ãã°ãååã®å¤æ®µã®é¨å㯠HTML ã«æ¢ã«åãè¾¼ã¾ãã¦ããç¶æ
ã§è¡¨ç¤ºãããã客ãã¾ã®æ
å ±ã«ä¾åããé¨åã¯ã¹ã±ã«ãã³ã§ã客ãã¾ã«ãã£ã¼ãããã¯ãè¡ãã¾ããèªèº«ã®ååã®å ´åãããã¯ç·¨éãã
ã¨ãããã¿ã³ã«ãªãã¾ãããã®ãããªã«ã¼ã«ã«ãããã¨ã«ãããCDN ã« HTML/next data json ã®ãã£ãã·ã¥ãããå ´åã¯ãã¡ã¼ã¹ããã¥ã¼ãèªç¶ã¨éããªãã¾ãã
ã¾ããstale-while-revalidateãå¤æ®µæ§æã«ãããã¨ã«ãããã客ãã¾ã«è¿ãå ´æãããã£ãã·ã¥ãè¿ããä¸ã¤æ°é®®ãªæ å ±ãä¿æããè¨è¨ãã¨ã£ã¦ãã¾ãã stale-while-revalidate ã¨ã¯ããã£ãã·ã¥ã stale ããç¶æ ã§ãæå®ããæéå ã§ããã°ããã® stale ãããã£ãã·ã¥ãè¿ããè£å´ã§éåæ㧠origin ã«åãåãããã£ãã·ã¥ãæ´æ°ããä»çµã¿ã§ããworkbox(service-worker) ã«ã http header ã¨å°ãç°ãªãã¾ãã stale-while-revalidate ãåå¨ããããå¤æ®µæ§æã¨ãªãã¾ãã以ä¸ã®å³ã¯ã社å ããã¥ã¡ã³ãç¨ã«æ¸ããè³æã§ãã
workbox ã® stale-while-revalidate ã§ã¯ http header ã¨ã¯ç°ãªããå¿
ãè£ã§åãåãããèµ°ãã¾ãã以ä¸ã¯ãCDN ä¸ã®ãã£ãã·ã¥ã® max-age ãåããã stale-while-revalidate ã§æå®ããæéå
ã§ãã£ãããã stale ãããã£ãã·ã¥ãè¿ãã¦ããããã¼ã§ãããService Worker 㨠CDN
ã®ãã£ãã·ã¥ãæ°é®®ã«ãªã£ã¦ãããã¨ããããã¾ãã
ãã®ããã«ã客ãã¾ã«è¿ãã¨ããããçµæãè¿ãããã®å ´æã§ã®ãã£ãã·ã¥ãå¯è½ãªéã stale ãã¦ããªãç¶æ ãä¿ã¡ã¾ãããã ããService Worker ã§ã¯ HTML ã¯å¸¸ã«ãããã¯ã¼ã¯åªå ã¨ãã¦ãã¾ãã
æ®å¿µãªãããiOS ã® WKWebView ã§ã¯ç¾å¨ Service Worker ããµãã¼ããã¦ãªããããã®å ¨ä½æ§æ㯠Android ã®ã¿ã¨ãªãã¾ããããããFastly èªä½ãé«éãªãã Service Worker ããªãåããããã¯ã¼ã¯é度ã®ä¾åã¯å¢ããå¯è½æ§ãããã¾ããããã¾ã大ããªåé¡ã«ã¯ãªãã¾ããã§ããã以ä¸ã¯ Service Worker ããªãå ´åã® lighthouse ã® performance ã®çµæã§ãã
æå¾ã«ã¡ã«ã«ãª Shops ã§ã¯ãmax-age ãé·ãåããæ§æã«ãã¦ãããããã客ãã¾ããã®ã¢ã¯ã»ã¹ã§ origin ã¸ã®å°éãããã¾ã§å¤ããªãã®ãã¨ãç¹å¾´ã§ããã¡ã«ã«ãª Shops ã®ä¸»è¦ãªãã¤ã¯ããµã¼ãã¹ã¯ãçºçããã¤ãã³ãã Pub/Sub ã«æµãä»çµã¿ã¨ãªã£ã¦ãã¾ãããããç£è¦ãå¤æ´ããã£ãæ å ±ã®ã¿ã CDN ãããã£ãã·ã¥ãã¼ã¸ããæ©æ§ãå®è£ ããããã«ããæå°éã®ãã¼ã¸ã§é·ã max-age ãæã¤ãã¨ãå¯è½ã¨ãã¾ããã
ä¾ãã°ãååã®å¤æ®µãå¤ãã£ãã¨ãããã®ååã¨ãã®ååã販売ãã¦ããã·ã§ããã®ãã£ãã·ã¥ã® 2 ã¤ããã¼ã¸ãã¾ãããããå®ç¾ããããã«ãSurrogate-Key
ã使ããã¹ã¦ã®ãã£ãã·ã¥ãã³ã³ããã¼ã«ãã¾ãã
ãããã¯ããã¼ã¸
Surrogate-Key: product-1111 shop-2222 products
ã·ã§ãããã¼ã¸
Surrogate-Key: shop-2222 shops
ãã®ããã«å
¨ä½ãã¼ã¸ç¨ã®ãã¼ã¨åå¥ç¨ã®ãã¼ãå
¥ãããã¨ã«ããããã£ãã·ã¥ã管çãã¾ããååãå¤æ´ãããã¨ããã®ååã®æ
å ±ã« shop-2222
ãå«ãã§ãããããã·ã§ãããã¼ã¸ã®ãã£ãã·ã¥ãç¹å®ã§ããã·ã§ãããã¼ã¸ããã¼ã¸ãããã¨ãå¯è½ã§ãã
ãã®ãããªã¤ã³ãã©æ§æã«ãããã¨ã«ãããã¡ã«ã«ãª Shops ã§ã¯å¹ççã« CDN ã®ãã£ãã·ã¥ã管çããWeb å ¨ä½ã®ããã©ã¼ãã³ã¹ã®æé©åãè¡ã£ã¦ãã¾ããmonorepo ãæ¡ç¨ãããã¨ã«ãã£ã¦ãé¢å¿äºãããã³ãã¨ã³ãããã¤ã³ãã©ã¾ã§åºãããããªããçµæã¨ãã¦ãã®ãããªæ§æãå®ç¾ãããã¨ãã§ãã¾ããã
ãããã«
ãã®è¨äºã§ã¯ãã¡ã«ã«ãª Shops ã®ããã³ãã¨ã³ãã§ã®ããã¤ãã®ã©ã¤ãã©ãªé¸å®ã¨è¨è¨ã®ä¸é¨ãç´¹ä»ãã¾ããããããã®è¨äºãæ°ããã¹ã¿ã¼ãããæ¹ã ã¸å°ãã§ãæçãªæ å ±ã«ãªãã°å¹¸ãã§ããã¾ã ã¾ã é¢ç½ã話ãããã®ã§ããããªã«ãæ°ã«ãªããã¨ãããã°ãSouzoh Tech Talk #03: Frontendã§ã® QA ã»ãã·ã§ã³ã§ãæ°è»½ã«ãå°ããã ãããããã¾ã§ ã8/10 ã¹ã¿ã¼ããé£è¼ï¼ãã¡ã«ã«ãª Shopsããã¬ãªã¼ãã³ã¾ã§ã®éçºã®è£å´ ãè¦ã¦ãã ãããããã¨ããããã¾ããï¼
ã¡ã«ã«ãª Shops ã§ã¯ã¡ã³ãã¼ãåéä¸ã§ããã¡ã«ã«ãª Shops ã®éçºã«èå³ãæã£ããããã£ã¬ã³ã¸ãã¦ã¿ããã¨ããæ¹ãããã°ããã²ãã¡ããè¦ãã¦ã¿ã¦ãã ãããã¾ãã«ã¸ã¥ã¢ã«ã«è©±ã ãèãã¦ã¿ãããã¨ãã£ãæ¹ã大æè¿ã§ãããã¡ãã®ç³ãè¾¼ã¿ãã©ã¼ã ãããã²ãé£çµ¡ãã ããï¼
ã¾ãã2021/08/18 ãã 2021/09/28 ã«ããã¦ãã½ã¦ã¾ã¦ TECH TALKãã¨ããã¤ãã³ããéå¬ããã¾ãããã¼ããåããæè¡çãªç¥è¦ãå ±æããããã¨ãç®çã¨ããåå¼·ä¼ã§ããèå³ã®ããæ¹ã¯ãã²ãåå ãã ããï¼