Next.jsãNestJS ã§æ°è¦Webã¢ããªã±ã¼ã·ã§ã³éçºããã¦ãã話
ã¢ããã³ãã«ã¬ã³ãã¼2021 ã¨ã³ã¸ã㢠ãã¯ããã¸ã¼
ããã¯ãFORCIA Advent Calendar 2021ã®19æ¥ç®ã®è¨äºã§ãã
ã¯ããã«
第1æ è¡ãã©ãããã©ã¼ã é¨é·ã®æ¦ç°ã§ããããã¾ã§æ¤ç´¢ã¢ããªã±ã¼ã·ã§ã³ã®éçºãã¡ã¤ã³ã«æ å½ãã¦ãã¾ããããæè¿ã¯æ¤ç´¢ã§å©ç¨ããååãã¼ã¿ãä½æãããµã¼ãã¹ã®éçºããã¦ãã¾ãã æ £ã親ããã æ¤ç´¢ã¢ããªã±ã¼ã·ã§ã³ã¨ã¯ç°ãªãã¾ããããã®ãã¦ãã¦ãæ´»ããã¤ã¤ãæ°ãããã¨ã«åãçµãã§ãã¾ããä»åã¯ãã®ãµã¼ãã¹éçºã§å©ç¨ãã¦ããæè¡ã«ã¤ãã¦ãç´¹ä»ãããã¾ãã
ããã³ãã¨ã³ã
Next.js
ãã©ã«ã·ã¢ã§ã¯ã¢ããªã±ã¼ã·ã§ã³éçºã§ç¤¾å 製ã®Webã¢ããªã±ã¼ã·ã§ã³ãã¬ã¼ã ã¯ã¼ã¯ãå©ç¨ãã¦ãã¾ããç¾å¨ã¯3代ç®ã¾ã§ã®Webã¢ããªã±ã¼ã·ã§ã³ãã¬ã¼ã ã¯ã¼ã¯ãåå¨ãã¾ãã3代ç®ã®ãã¬ã¼ã ã¯ã¼ã¯ã¯å é¨ã§Next.jsãå©ç¨ãã¦ãã¾ãããã®ããNext.jsãæ¡ç¨ããã®ã¯èªç¶ãªæµãã§ããã ãã®ç¤¾å 製Webã¢ããªã±ã¼ã·ã§ã³ãã¬ã¼ã ã¯ã¼ã¯éçºã®è©±ã¯ãã¡ãã§ãã ãªããä»åéçºãã¦ããã¢ããªã±ã¼ã·ã§ã³ã¯æ¤ç´¢ã¢ããªã±ã¼ã·ã§ã³ã§ã¯ãªãã主ã«ãã¼ã¿ãç»é²ãã管çç»é¢ç³»ã®ã¢ããªã±ã¼ã·ã§ã³ã¨ãªã£ã¦ãã¾ããé常ã®Spookã®éçºã¨ã¯å¤§ããç°ãªãã¢ããªã±ã¼ã·ã§ã³ã®ãã社å 製ãã¬ã¼ã ã¯ã¼ã¯ã¯å©ç¨ãã¾ããã§ããã
å人çã«ã¯ä»åã®ã¢ããªã±ã¼ã·ã§ã³ã§ã¯Svelteã®æ¡ç¨ããããã¨èãã¾ãããã以ä¸ã®çç±ããè¦éã£ã¦ãã¾ãã
- Reactã§ã®éçºã«æ £ãã¦ããã¨ã³ã¸ãã¢ãå¤ã
- ã¢ããªéçºã®è¦æ¨¡ã大ãããSvelteã§ã©ãã¾ã§ãã¾ã対å¿ã§ãããæªç¥æ°
antd
ãã¶ã¤ã³ã·ã¹ãã ã¨ãã¦antdãæ¡ç¨ãã¦ãã¾ãã
- MUI(æ§Material-UI)ã¨æ¯è¼ãã¦ç®¡çç»é¢åãã®ã³ã³ãã¼ãã³ããå¤ã
- Formé¢é£ã®ã³ã³ãã¼ãã³ããå¼·åã§ãä¸è¦ãªåã¬ã³ããªã³ã°ãçºçããªãããã«ãªã£ã¦ããï¼React hook formãè¯ãè©å¤ãè¯ãèãã¾ãï¼
- ã³ã³ãã¼ãã³ãã ãã§ãªããã¬ã¤ãã©ã¤ã³ããã¶ã¤ã³ãã¿ã¼ã³ã«ã¤ãã¦ã®ããã¥ã¡ã³ããå¤ãå å®ãã¦ãã
ã¨ãã£ãç¹ã§æ¡ç¨ãã¾ããã
ç¾ç¶ãNext.jsã§antdãå©ç¨ãã¦ããã¨ç¹å®ã®ã³ã³ãã¼ãã³ãã使ç¨ããéã«ä»¥ä¸ã®Warningãåºã¾ãã
Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. Toavoid this, useLayoutEffect should only be used in components that renderexclusively on the client. See https://reactjs.org/link/uselayouteffect-ssr for common fixes.
ããã¯antdãå é¨çã«å©ç¨ãã¦ããrc(react-component)ãSSR対å¿ããã¦ããããuseLayoutEffectããã¯ãå©ç¨ãã¦ããããã§ãã 対å¿èªä½ã¯é²ãããã¦ãããè¿ãå°æ¥è§£æ¶ããã¨æããã¾ãã
Storybook
ä»åã®æ¡ä»¶ã§ã¯ãã¨ã³ã¸ãã¢ãã¹ã¿ã¤ãªã³ã°ãå«ãã¦ã³ã³ãã¼ãã³ããéçºãã¦ãããStorybookãå©ç¨ãã¦ãã¾ãã GitLab CIãå©ç¨ãã¦ãmainãã©ã³ããpushããã¿ã¤ãã³ã°ã§StorybookãbuildãçæããhtmlãS3+CloudFrontã«ã¢ãããã常ã«ææ°ã®ã³ã³ãã¼ãã³ããå ¨ã¡ã³ãã¼ã確èªã§ããç¶æ ã«ãã¦ãã¾ãã
Storybookãç¨æãããã¨ã§ã¨ã³ã¸ãã¢ä»¥å¤ã®ããã¸ã§ã¯ãã¡ã³ãã¼ãã©ã®ãããªã³ã³ãã¼ãã³ãããããéçºä¸ã®ãã¶ã¤ã³ãã©ããªã£ã¦ããã確èªã§ããã¨ããã¡ãªãããããã¾ãã
ç¾æç¹ã§ã¯ã³ã³ãã¼ãã³ãã®è¨è¨çãé »ç¹ã«å¤ãããããªéçºåæ段éã®ãããStorybookãå©ç¨ãããã¹ãã¯æ¸ãã¦ãã¾ãããç¶ãã¹ãã¿ã¤ãã³ã°ã§ã¹ãããã·ã§ãããã¹ããå«ãã³ã³ãã¼ãã³ãã®ãã¹ããå®è£ ãã¦ãããã¨èãã¦ãã¾ãã
Apollo client
ãã¼ã¿ãã§ããã®ã©ã¤ãã©ãªã¨ãã¦Apollo clientãæ¡ç¨ãã¦ãã¾ãã GraphQLãå©ç¨ãã¦ãããããã¯ã¨ã³ãã§çæããGraphQLã®schemaã¨GraphQL Code Generatorã®TypeScript React Apolloãã©ã°ã¤ã³ãå©ç¨ãã¦ãhookãèªåçæãã¦ãã¾ãã
ç¶æ 管çã®ã©ã¤ãã©ãªã¨ãã¦recoilã使ãããã¨æã£ã¦ãã¾ãããç¾æç¹ã§ã¯Globalãªç¶æ 管çãå¿ è¦ã«ãªãã±ã¼ã¹ãããã¾ã§ãªããContext APIãuseState hookçã§ååãªå¯è½æ§ãããã¾ãã ãã®ãããã¯éçºãé²ãã¦ããä¸ã§æ¤è¨ã§ããã°ã¨èãã¦ãã¾ãã
ããã¯ã¨ã³ã
NestJS
ããã¯ã¨ã³ãã®ãã¬ã¼ã ã¯ã¼ã¯ã¨ãã¦NestJSãæ¡ç¨ãã¾ããã
- ååä¼ç¤¾ã®ã¨ã³ã¸ãã¢ããã¯Javaã§ã®éçºã«æ £ããã¨ã³ã¸ãã¢ãå¤ã
- 社å ã®ã¨ã³ã¸ãã¢ã¯JavaScript, TypeScriptã§ã®éçºã«æ £ããã¨ã³ã¸ãã¢ãå¤ã
ã¨ããç¶æ ã§ãããå°æ¥çã«ã¯ç¤¾å ã§ã¡ã³ããã³ã¹ãã¦ãããµã¼ãã¹ã«ãªããããéçºè¨èªãJavaã«ãã¦ãã¾ãã¨éç¨æã«å³ãããªãå¯è½æ§ãé«ãã¨èãã¾ããã
Javaã®Spring Frameworkã®ãããªæ¸ãå³ã®NestJSãæ¡ç¨ãããã¨ã§åæ¹ãéçºãéç¨ããããå½¢ã«ã§ããã®ã§ã¯ã¨èãæ¡ç¨ãã¾ããã ãã¡ãã¯Yahoo! JAPAN ããã®ãã¡ãã®Tech Blogãåèã«ããã¦ããã ãã¾ããã
ãã³ã¬ã¼ã¿ãDIãå©ç¨ããéçºã¯ç§å«ã社å ã®ã¨ã³ã¸ãã¢ãæ £ãã¦ããããè¥å¹²ã®åã£ä»ãã«ãããæãã¾ããããæ £ãã¦ããã¨ã¾ãã«é¢å¿ã®åé¢ã«ãããã¡ã¤ã³ã®ãã¸ãã¯ã«éä¸ã§ããããã«æãã¾ããã ã¾ããååä¼ç¤¾ã®ã¨ã³ã¸ãã¢ãããããæ¸ããããã¨ãã声ãããã ããæ¡ç¨ãã¦è¯ãã£ãã¨æãã¾ããã
NestJSã¯GraphQL Serverã¨ãã¦å®è£ ãã¦ãã¦ããã³ã¬ã¼ã¿ãããããæ¸ãå¿ è¦ãããã¾ããcli-pluginãå°å ¥ãããã¨ã«ãããè¨è¿°éã大ããåæ¸ã§ãã¾ããã
GraphQLã«ã¤ãã¦
NestJSã¯GraphQL Serverã¨ãã¦å®è£ ãã¦ãã¾ãã ä»åã®ã¢ããªã±ã¼ã·ã§ã³ã§ã¯é常ã«å¤ãã®ç»é¢ãåå¨ããããã«ä¼´ãAPIã®æ°ãå¤ããªããã¨ãè¦è¾¼ã¾ãã¾ããã
åç §ã§GETã®ã¨ã³ããã¤ã³ãããã¼ã¿ã®è¿½å ã§POSTã®ã¨ã³ããã¤ã³ããç¨æããã¼ã¿ã®æ´æ°ã§ã¯PUT/PATCHã¨ãã£ãã¨ã³ããã¤ã³ããç¨æãã¦...ã¨ãªãã¨èãããã¨ãå¤ããç¹ã«RESTfulãªAPIãè¨è¨ããå ´åã«ã¨ã³ããã¤ã³ãã®è¨è¨ã ãã§ãè¨å¤§ãªæéãããã£ã¦ãã¾ãå¯è½æ§ãããã¾ããã GraphQLã§ã¯ãã¼ã¿åå¾ã¯queryããã¼ã¿ãæä½ããéã¯mutationããã¨ã¯ãã³ãã©ã¡ã½ããåãèããã°æ¸ããããå°å³ã§ã¯ããã¾ããã¨ã³ããã¤ã³ãã«ã¤ãã¦èããæéã¯ããªãç縮ãããæè¦ã§ãã
GraphQLã§ã¯ãããã³ãã¨ã³ãã§ã®åãåãã¯æ¥½ã«ãªãããããã¯ã¨ã³ãã®å®è£ ã¯è¤éã«ãªããã¨ãã£ã話ãä½åº¦ãè³ã«ãããã¨ãããã¾ããéçºãé²ãã¦ã¿ã¦NestJSãããã§ãã¦ããã®ããããã¾ã§è¤éã«ãªã£ã¦ããå°è±¡ã¯ããã¾ããã ç¾æç¹ã§ã¯ãGraphQLã®ããã¯ã¨ã³ãã®å®è£ ã¯é常ã®Web APIã¨ããã¾ã§å¤ãããªãããã«æãã¾ããã
å®éãREST APIã§éçºããããGraphQLã«ãããã¯é常ã«æ©ãã ãã¤ã³ãã§ã¯ããã¾ããããã¼ã ã¡ã³ãã¼ã®ä½¿ã£ã¦ã¿ããããã¾ãï¼ã¨ãã声ãã¡ã«ã«ãª Shops ããã®è¨äºãæ¡ç¨ã®å¾æ¼ãã«ãªãã¾ããã
ã³ã¼ããã¡ã¼ã¹ãï¼ã¹ãã¼ããã¡ã¼ã¹ãï¼
NestJSã§GraphQL Serverãå®è£ ããéã«ã³ã¼ããã¡ã¼ã¹ãã§é²ããããã¹ãã¼ããã¡ã¼ã¹ãã§é²ããããã¨ããç¹ãã²ã¨ã¤æ©ã¾ãããã¤ã³ããã¨æãã¾ãã ä»åã®ããã¸ã§ã¯ãã§ã¯ã³ã¼ããã¡ã¼ã¹ãã®ã¢ããã¼ããåããã¨ã«ãã¾ããã
çç±ã¯ä»¥ä¸ã®ã¨ããã§ãã
- ããã³ãã¨ã³ãã®éçºããã人ããã®ã¾ã¾ããã¯ã¨ã³ãã®APIãå®è£
ããå½¢å¼ã«ãªã£ã¦ãã
- ãã©ã«ã·ã¢ã§ã¯ããã³ãã¨ã³ãã¨ããã¯ã¨ã³ãã§ã¨ã³ã¸ãã¢ãåããã¦ããããã©ã¡ããå®è£ ãã
- ãã®ããã¹ãã¼ããã¼ã¹ã§èªèãåãããå¿ è¦ããªã
- ã¢ãã¬ãæ§æã¨ãªã£ã¦ãããããã³ãã¨ã³ãã¨ããã¯ã¨ã³ãã®ã³ã¼ããåä¸ãªãã¸ããªã§ç®¡çããã¦ãã
ãã¡ãã¯æ¯é±å®æ½ãã¦ããæè¡ãã£ã¹ã«ãã·ã§ã³ã¨ãã社å MTGã®å ´ã§ç¸è«ããã¨ãããä¸è¨ã®ãããªã³ã¡ã³ããããã ããã³ã¼ããã¡ã¼ã¹ãã§é²ãããã¨ã«ãã¾ããã å®éãã³ã¼ããã¡ã¼ã¹ãã§é²ãã¦ã¿ã¦å¿«é©ã«éçºã§ãã¦ããå°è±¡ã§ãã
Prisma
ORMã¨ãã¦Prismaãå©ç¨ãã¦ãã¾ãã é常ã¯Prisma schemaã«ããã¢ããªã³ã°ã§ãã¼ã¿ãã¼ã¹ã®è¨è¨ããã¦ãããã¨æãã¾ããããã©ã«ã·ã¢ã«ã¯ç¬èªã®schemaå®ç¾©ãç¨æãã¦ãã¼ã¿ãã¼ã¹ãæ§ç¯ããä»çµã¿ãããã¾ãã ãã¼ã¿ãã¼ã¹ã®æ§ç¯ã¯ç¬èªã®ä»çµã¿ãå©ç¨ããPrismaã¨ã®é£æºã§ã¯ prisma db pullï¼æ§prisma introspect
ï¼ã³ãã³ããå©ç¨ãã¦prisma.schemaãã¡ã¤ã«ãçæãã¦ãã¾ãã
ãã¼ã¿ãã¼ã¹ããã®ãã¼ã¿ã®åå¾ãåå®å ¨ã«ãªããTypeScriptã§è£å®ãå¹ãç¹ãé常ã«è¯ãéçºä½é¨ãå¾ããã¦ãã¾ãã ä¸æ¹ãç§å«ããã©ã«ã·ã¢ã®ã¨ã³ã¸ãã¢ã¯ããã©ã¼ãã³ã¹é¢ãèæ ®ããSQLãæ¸ããã¨ãå¾æã¨ãã¦ãã¾ãããPrismaã®ãããªORMã§å¹ççã«ãã¼ã¿ãåå¾ãããã¦ãã¦ã¯å°ãªããããå°ããã¤ç¥è¦ã貯ãã¦ãããã°ã¨èãã¦ãã¾ãã
Prismaã¯å¨è¾ºãã¼ã«ãå¼·åã§ãåæéçºæã®ãµã³ãã«ãã¼ã¿ã®ä½æã§ã¯prisma studioãå©ç¨ãã¦ãã¾ãã è³é調éããã¦ãããå¼ãç¶ãæ´»çºãªéçºãé²ãããã¦ãããã¨ãè¦è¾¼ã¾ããç¹ãæ¡ç¨ãå¾æ¼ããã¾ããã
schemaspy
ä»åã®æ¡ä»¶ã§ã¯å¤é¨ãµã¼ãã¹ãããã¼ã¿ãã¼ã¹ã«ã¢ã¯ã»ã¹ããã±ã¼ã¹ãããããããã¼ãã«å®ç¾©æ¸ãç¨æããå¿ è¦ãããã¾ããã schemaå®ç¾©ã¨å¥ã§ãã¼ãã«å®ç¾©æ¸ãä½æããã®ã§ã¯ãªããæ§ç¯ãããã¼ã¿ãã¼ã¹ããschemaspyãå©ç¨ãã¦å®ç¾©æ¸ãçæããããã«ãã¾ããã
ã¾ãããã¼ãã«ãã«ã©ã ã®è«çåã表示ãããã¨ããè¦ä»¶ãããã¾ããã PostgreSQLã§ã¯ãã¼ãã«ãã«ã©ã ã«å¯¾ãã¦ã³ã¡ã³ããä»ä¸ããæ©è½ãããããããã¡ããå©ç¨ãã¾ããã
- ã³ã¡ã³ãã®1è¡ç®ãè«çå
- 2è¡ç®ä»¥éããã¼ãã«ãã«ã©ã ã®ã³ã¡ã³ãæ¬æ
ã¨ãã¦ãschemaspyãforkãã¦æ©è½ã追å ãããã¨ã§æ¥æ¬èªã®è«çåãä¸ç·ã«è¡¨ç¤ºã§ãããã対å¿ãã¾ããã ãã®æ©è½ã追å ãããã®ã®ã½ã¼ã¹ã³ã¼ãã¯ãã¡ãã«å ¬éãã¦ãã¾ãã
çæããããã¼ãã«å®ç¾©æ¸ã¯ä»¥ä¸ã®ããã«ãªãã¾ãã
ãã¡ããStorybookã¨åæ§ã«GitLab CIãå©ç¨ãã¦mainãã©ã³ãã«ãã¼ã¸ãããã¿ã¤ãã³ã°ã§ææ°ã®ãã¼ãã«å®ç¾©æ¸ãbuildãããWebä¸ã§ç¢ºèªã§ããããã«ãã¦ãã¾ãã
Dockerã®å©ç¨ã«ã¤ãã¦
éçºç°å¢ã§ã¯Dockerãå©ç¨ãã¦ãåããã»ã¹ã¯ãã¹ã¦ã³ã³ããã§åä½ããããã«ãªã£ã¦ãã¾ãã ç°å¢æ§ç¯ç¨ã®init scriptãç¨æãã¦ãããæå ã®ç°å¢ã«DockerãDocker Composeãã¤ã³ã¹ãã¼ã«ãã¦ããã°ããã«éçºã«å ¥ããããã«ãªã£ã¦ãã¾ãã
ã¾ããããã¯ã¨ã³ãã®NestJSã§çæããGraphQLã®schemaãã¡ã¤ã«ã¯å¤æ´ããã£ãã¿ã¤ãã³ã°ã§ããã³ãã¨ã³ãã®ã³ã³ããã«åæããã¾ãã ããã¯chokidar-cliãåããã³ã³ãããå¥ã§ç¨æãã¦å®ç¾ãã¦ãã¾ãã ããã«ããããã³ãã¨ã³ãå´ã§åç §ãã¦ãããã£ã¼ã«ããåé¤ããã±ã¼ã¹ãªã©ã¯åã¨ã©ã¼ã¨ãã¦å³ææ¤ç¥ã§ãã¾ãã
docker-compose up
ããã°èªåçæãã¡ã¤ã«ã®é£æºå«ãã¦ããã¹ããã·ã³å´ã§ã¯ç¹ã«ä½ã®ããã»ã¹ãåãããã«éçºã§ããããã«ãã¨ãããã¨ãæèãã¦ãã¾ãã
ãããå¦çã¾ãã
- å¤é¨ãµã¼ãã¹ããé£æºãã¼ã¿ãåå¾ããåãè¾¼ã¿
- å¤é¨ãµã¼ãã¹ã¸ã®é£æºãã¼ã¿ãçæ
ã¨ãã£ããããå¦çãåå¨ãã¾ãããã¡ãã¯SQLãshellã³ãã³ããªã©ãæè»ã«å®è¡ãã社å ç¬èªã®ä»çµã¿ãå©ç¨ãã¦å®è£ ãã¦ãã¾ãã
å®éã«éçºãé²ãã§ãã¦ã®å°è±¡
- ãã¶ã¤ã³ãå«ãã¦ã¨ã³ã¸ãã¢ãå®è£
ãã¦ãã¾ããããã¶ã¤ã³ã®èª¿æ´ã«ããªãã®å®è£
æéãå²ãã¦ãã¾ã£ã¦ãã
- ãã¶ã¤ã³ã®çµé¨ãããã¨ã³ã¸ãã¢ãå°ãªããæ £ãã¦ããªãã¨ããç¹ã大ããã§ã
- GraphQLãä½ãããããªãç¶æ
ããã¹ã¿ã¼ããã¦ãã¾ãããå®éã«ã¯åãªãã¤ã³ã¿ãã§ã¼ã¹ã§ãããWeb APIã¨å¤§ããå¤ãããªãã¨æãã¦ããã¯ä»²è¯ããªãã¦ããæ°ããã¾ã
- GraphQLãåãå·»ãã¨ã³ã·ã¹ãã ãããªãçºéãã¦ããããã®ããããéçºä½é¨ãåä¸ããã¦ããããã«æãã¾ãã
- ãã¼ã¿ãã¼ã¹ã®ãã¼ãã«å®ç¾©ãå¤ãã£ãã¨ãã®ã³ã¼ãã®å¤æ´éãå¤ã...
- ãã®ãããã¯ãªãã¹ãå°ãªããªãããã«ãã¨ããã®ãæèãã¦ã¯ãã¾ããã...éçºåæ段éã§ã¯ã©ããã¦ããã¼ãã«å®ç¾©ã«å¤æ´ãå ¥ããã¨ãå¤ããããã®è¿½å¾ãããã«æ¥½ã«ãããã¯ä»å¾ã®èª²é¡ã§ã
ã¾ã¨ã
ãã©ã«ã·ã¢ã§ã¯æ¤ç´¢Webã¢ããªã±ã¼ã·ã§ã³ã®éçºã§å¹ã£ããã¦ãã¦ãæ´»ããã¤ã¤ãæ°ããæè¡ãåãå ¥ããªããæ¤ç´¢ä»¥å¤ã®Webã¢ããªã±ã¼ã·ã§ã³éçºã«ãåãçµã¿å§ãã¦ãã¾ããæè¡é¸å®ã®éã«ä»åã®è¨äºãå°ãã§ãåèã«ãªãã¾ããã幸ãã§ãã
æ¦ç°ãé½ä¸é
2012å¹´æ°åå
¥ç¤¾
å
æ¥å¨ã®ä¸äºä¸ãããã¾ãããå¨ãç¥ç¤¾ã®æ¹ã«ãå°æ¥ä½ã«ãªãããã®ï¼ãã¨è¨ãããç¥ç¶ç¥æ¯ã®åã§ãå«ã«ãªãããã§ãï¼ãã¨çãã姿ã«æé·ãæãã¾ããã
ãã©ã«ã·ã¢ã§ã¯ãã©ã«ã·ã¢ã«èå³ããæã¡ããã ããæ¹ã«ã社å¡ã¨ã®é¢è«ã®ãæ¡å
ããã¦ãã¾ãã
æ¡ç¨å¿åã®æ¹ãã¾ãã¯ã«ã¸ã¥ã¢ã«ã«ã話ããã¦ã¿ããã¨ããæ¹ã¯ããæ°è»½ã«ä¸è¨ãããé£çµ¡ãã ããã
â» å¼ç¤¾ç¤¾å¡ã«å¯¾ããå¶æ¥è¡çºãªã©ã¯ãæããã¦ããã¾ãããå¸æã«æ²¿ããªãå ´åããããã¾ãã®ã§äºããäºæ¿ãã ããã