åœç€Ÿã®ã¯ã©ãŠãç§»è¡ãšSREã«ã€ããŠè¬æŒãããŸãã 2019/1/30ã«itsearch+æ§ã§åœç€Ÿã®ã¯ã©ãŠãç§»è¡ãšSREã«ã€ããŠè¬æŒãããŸããã news.mynavi.jp çºè¡šè³æã¯ãã¡ãã§ãããã²ãã芧ãã ããã speakerdeck.com æšå¹Ž11æã«æžãã以äžã®èšäºã®å
容ã«å
·äœçãªäºäŸã亀ãã€ã€ãåœç€Ÿã®SREã®åãçµã¿æ¹ã«ã€ããŠçºè¡šãããŸããã user-first.ikyu.co.jp çºè¡šã«ãæžããŸããéããä»åŸãã³ã³ããæè¡çãæ°ããæè¡ã掻çšãã€ã€ãããžãã¹ã®æé·ãæ¯ããæè¡åºç€éçºãSREãå®è·µããŠãããããšæããŸããWe are hiring!! hrmos.co hrmos.co ããŸã æè¿å匷ã«ãªã£ãSREé¢é£ã®ãªãœãŒã¹ SRE - 次世代Webカンファレンス #nwc_sre - YouTube 3人ã®çµéšè
ãèªãReal World SREããšãŠãåçºçãªå
容ã§å匷ã«ãªããŸããã Seeking SRE æŽæžã§ãããSREã«ã€ããŠéåžžã«å¹
åºããããã¯ãæ±ã£ãŠããŸãã ãã®èšäºã®çè
ã«ã€ã㊠ã·ã¹ãã æ¬éšCTO宀æå±ã® åŸ³æŠ ã§ãã ãµãŒãã¹ã®æè¡åºç€ã®éçºéçšãéçºæ¯æŽãSREãè¡ãªã£ãŠããŸãã
宿æ³äºæ¥æ¬éšã§ããã³ããšã³ãéçºãããŠããå®éœå®®ã§ãã æšæ¥ïŒ2019/1/24ïŒã LODGE ã§éå¬ãããã Bonfire Frontend #3 ã«ç»å£ãããŠããã ããŸããã Bonfire Frontend #3ã®ããŒãã¯ãããã©ãŒãã³ã¹æ¹åãã§ãå瀟ãããã©ãŒãã³ã¹æ¹åãã¿ãæã¡å¯ã£ãŠçºè¡šããäŒã§ããã ç§ã¯ãäžäŒ.comã®ããã³ããšã³ãããã©ãŒãã³ã¹æ¹åããšããã¿ã€ãã«ã§ãããã³ããšã³ãå
šè¬ã®ããã©ãŒãã³ã¹æ¹åã«ã€ããŠã話ãããŸããã slides.com ããã³ããšã³ãã®ããã©ãŒãã³ã¹æ¹åã«ãããŠã¯ãããã¡ã¯ãã¹ã¿ã³ããŒããªèšæž¬ããŒã«ã§ãã Lighthouse ã®äœ¿ãæ¹ã«ç¿çããããšãéèŠã ãšæã£ãŠããŸãã ãŸãã2019幎1æçŸåšãLighthouseãå©çšããèšæž¬ç°å¢ãšããŠæãã¢ã¯ã»ã¹ããããã®ã PageSpeed Insights ã§ãããã ãPageSpeed Insightsã®èšæž¬ã«ã¯åææ¡ä»¶ãè¥å¹²ã®çãããããããã®èŸºã®è©±ã亀ããŠãPageSpeed Insightsã®è©±ãåãã«ããŸããã ãã®åŸã¯äžäŒã§è¡ã£ãŠããããã©ãŒãã³ã¹æ¹åã®å€§ãŸããªæŠç¥ããä»åŸã®ããã³ããšã³ãããã©ãŒãã³ã¹æ¹åã«åããã¢ãŒããã¯ãã£ã®æ§æ³ãªã©ãã話ãããŸããã å
·äœçãªããã©ãŒãã³ã¹æ¹åã®æœçã«ã€ããŠã¯ãå
æã®Ikyu Frontend Meetupã§çºè¡šããäžèšã¹ã©ã€ããããããŠã芧ãã ããã slides.com speakerdeck.com äžäŒã§ã¯ã䜿ããããäºçŽãµãŒãã¹ã®æäŸã®ãããåŒãç¶ãããã©ãŒãã³ã¹æ¹å掻åãé²ããŠãããããšæã£ãŠããŸãã hrmos.co
äžäŒ.comã§Webããã³ããšã³ããéçºããŠããå®éœå®®ã§ãã å
æ¥ãäžäŒ.comããã«ããŒãžã®ã¹ããçãããjQueryãåãé€ããŸãããjQueryãåãé€ããçµç·¯ããã£ãããšãçµæã«ã€ããŠæžããŸãã ã¡ãªã¿ã«ãããã«ããŒãžã«ã¯ä»¥äžã®URLã§ã¢ã¯ã»ã¹ã§ããŸãïŒã¹ããã§éãããPCã®å Žåã¯UAãã¹ããã«åœè£
ããå¿
èŠããããŸãïŒ https://www.ikyu.com/sd/00001290/ ãªãjQueryãåãé€ããã®ãïŒ ã©ããã£ãã®ã äœããã£ãã®ã jQuery.ajax() => fetch ã«çœ®ãæã fetchã®polyfillãæ¡çšããçç± DOMæäœãæšæºAPIã«çœ®ãæã èŠçŽ ã®ååŸ show/hide addClass/removeClass html/text ã¢ãã¡ãŒã·ã§ã³ $.ready() ã€ãã³ããã£ã«ã¿ãªã³ã° jQueryã®äœ¿çšãé²ãç®å° jQueryåé€ã®å¹æ ãŸãšã åç¥ ãªãjQueryãåãé€ããã®ãïŒ JavaScriptãµã€ãºã®åæžã®ããã§ããäžäŒ.comããã«ããŒãžã¯ã以åã¯åèšã§çŽ300KBã®jsãã¡ã€ã«ãèªã¿èŸŒãã§ããŸããïŒ300KBã¯gzipåŸã®è»¢ééãªã®ã§ãå®ãã¡ã€ã«ã¯ãã£ãšå€§ããã§ãïŒã ãããããããjsã¯170KB以å
ã«ãŒã«ãã¯ãåç·é床ã®ããŒã¹ã©ã€ã³ã400Kbpsãšããåæ 1 ã§ããäžäŒ.comã®å¹³åçãŠãŒã¶ã¯ãã£ãšè¯è³ªã®åç· 2 ã䜿ã£ãŠããã®ã§ã170KBãŸã§åãè©°ããããšæã£ãŠããããã§ã¯ãããŸããã ããããjQueryã§å®è£
ãããŠããåŠçã¯ãæè¿ã®DOM APIã䜿ãã°ä»£æ¿å¯èœã§ãããã©ãŠã¶APIã®çµ±äžãé²ã¿ã€ã€ããçŸåšãjQueryã䜿ãçç±ã¯ãªãã®ã§ã¯ïŒããšèããjQueryäŸåãåãé€ããããžã§ã¯ããé²ããŸããã ã©ããã£ãã®ã jQueryã䜿çšããŠããç®æã¯å€ãã£ãããã现ãããã«ãªã¯ãšã¹ããåã£ãŠãéœåºŠmasterã«ããŒãžããŠããæ¹éã§é²ããŸããã çµæçã«ãä¿®æ£ãã«ãªã¯ã¯12åãç·å€æŽè¡æ°ã¯Â±2500è¡çšåºŠã«ãªããŸããã ãŸããã¡ã€ã³ãããžã§ã¯ããšäžŠè¡ããŠé²ããŠãããããå»å¹Žã®8æé ããçæããŠãå®äºã¯å
é±ã§ãããçŽ4ã¶æããã£ãèšç®ã«ãªããŸãã äœããã£ãã®ã ããããã¯ããã£ãããšã现ããæžããŠãããŸãã jQuery.ajax() => fetch ã«çœ®ãæã jQuery.ajax() ãããã©ãŠã¶ã®æšæºAPIã§ãã fetch ã«çœ®ãæããŸãããfetchãå©çšå¯èœãªã®ã¯iOS 10.3以äžãªã®ã§ãpolyfillãå°å
¥ããŸããã github.com â»ã©ã€ãã©ãªããã³ãã«ãããšãå
šãŠã®ãŠãŒã¶ã«polyfillãé
ä¿¡ããããšã«ãªããŸããããã©ãŒãã³ã¹èгç¹ããã¯ã polyfill.io ã§ fetchã䜿ããªãå Žåã®ã¿polyfill ã䜿ãã®ãè¯ããšæããŸãã åºæ¬çã«ã¯ãPromiseã䜿ã£ãŠãããšããã¯ãã®ãŸãŸçœ®ãæããã³ãŒã«ããã¯ã䜿ã£ãŠãããšããã¯PromiseããŒã¹ã«æžãæããŸããã1ã«æã ãåæã®ajaxã䜿ã£ãŠãããšããããã£ãã®ã§ãããã¯éåæã«æžãçŽããŸããã $.ajax( 'https://www.ikyu.com/api/...' , {} ).then(data => data); const data = await fetch( 'https://www.ikyu.com/api/...' ).then(res => res.json()); fetchã®polyfillãæ¡çšããçç± æ¯èŒããã®ã¯XMLHttpRequest(XHR)ãš axios ã§ããã XHRãšæ¯ã¹ããšã Pros fetchã¯PromsieããŒã¹ã§ãé«ã¬ãã«ãªAPIã«ãªã£ãŠãã Cons iOS 10.2以äžã§ã¯polyfillã®èªã¿èŸŒã¿ãå¿
èŠ axiosãšæ¯ã¹ããšã Pros fetchã¯Webã®æšæºAPIã§ããã®ã«å¯ŸããŠãaxiosã¯jQuery.ajax颚ã®ç¬èªAPI polyfillãªã®ã§å°æ¥çã«ã©ã€ãã©ãªã®èªã¿èŸŒã¿ããªããã whatwg-fetchã¯axiosããããµã€ãºãå°ãã axiosãæäŸããŠãããããªé«åºŠãªæ©èœïŒUniversal JSããªã¯ãšã¹ãã®ãã£ã³ã»ã«ãtransform/interceptçïŒã¯ä»ã®ãšããå¿
èŠãªã Cons æ©èœãå°ãªãïŒããšãã°ãã¿ã€ã ã¢ãŠãæ©èœããªãïŒ ãšããæãããªãšæããŸãã fetchã®Consã«ã€ããŠã¯ã XHRãçã§äœ¿ãã®ã¯å¯èªæ§ã®èгç¹ããã¯ããããªã fetchã«è¶³ããªãæ©èœã¯å¿
èŠã«å¿ããŠè£ãããšãã§ãã ãšããçç±ããå®è³ªçã«åé¡ãªããšèããŠãfetchã®polyfillãæ¡çšããŸããã DOMæäœãæšæºAPIã«çœ®ãæã jQueryã§è¡ã£ãŠããDOMæäœããå
šãŠãã©ãŠã¶ã®æšæºAPIã«çœ®ãæããŸããjQuery => DOM APIã®çœ®ãæãã«é¢ããå
æ¬çãªããã¥ã¡ã³ãã¯ä»¥äžãããããã§ãã github.com ããã§ã¯ãä»åã®ãããžã§ã¯ãã§å®éã«äœ¿ã£ã眮ãæãã®ã¿ç޹ä»ããŸãã èŠçŽ ã®ååŸ jQueryã® $() ã¯åäœã®ååŸãšãªã¹ãã®ååŸãééçã«æ±ããããã«ãªã£ãŠããŸãããDOM APIã§ã¯åºå¥ãå¿
èŠã§ãã $(selector); // 1åã ãåã document .querySelector(selector); // èŠçŽ ã®ãªã¹ããåã document .querySelectorAll(selector); // èŠçŽ ã®ãªã¹ããåã£ãŠãäžæ¬æäœããïŒNodeList.forEachã¯iOS 9ã§ã¯äœ¿ããªãã®ã§é
ååããŠããïŒ [ ... document .querySelectorAll(selector) ] .forEach( /**/ ); 泚æãå¿
èŠãªã®ã¯ååšããªãèŠçŽ ãžã®ã¯ãšãªã§ããjQueryã¯ãååšããªãèŠçŽ ã«å¯Ÿããã¯ãšãªãçºè¡ããŠãè¿åŽããããªããžã§ã¯ãã«ã¡ãœãããçºè¡ããŠãããšã©ãŒã«ã¯ãªããŸãããååšãããããªãã£ããããèŠçŽ ã«å¯ŸããåŠçãjQueryã§è¡ã£ãŠããå ŽåãDOM APIãžã®çœ®ãæãã¯äžæéå¿
èŠã§ãã // ãšã©ãŒã«ãªããªã $( 'ãããªèŠçŽ ã¯ãªã' ).show(); // document.querySelector()ã®çµæã¯nullãªã®ã§ãstyleãžã®ã¢ã¯ã»ã¹ã§ãšã©ãŒçºç document .querySelector( 'ãããªèŠçŽ ã¯ãªã' ).style.display = 'block' ; show/hide $el.show(); $el.hide(); $el.toggle(); el.style.display = '' ; el.style.display = 'none' ; if (el.ownerDocument.defaultView.getComputedStyle(el, null ).display === 'none' ) { el.style.display = '' ; } else { el.style.display = 'none' ; } å®éã«äœ¿ãéã¯ã颿°åããã»ããããã§ãããã addClass/removeClass classæäœã¯ classList ã§çœ®ãæãå¯èœã§ããIE 10以äžå¯Ÿå¿ãªã®ã§å®å¿ã $el.addClass( 'class' ); $el.removeClass( 'class' ); $el.hasClass( 'class' ); el.classList.add( 'class' ); el.classList.remove( 'class' ); el.classList.contains( 'class' ); html/text $el.html(html); $el.text(text); el.innerHTML = html; el.textContent = text; ã¢ãã¡ãŒã·ã§ã³ jQueryã®ã¢ãã¡ãŒã·ã§ã³APIã¯æè»œã«äœ¿ããŠé«æ©èœãªã®ã§ãå®å
šãªçœ®ãæãã¯é£ããã§ãã ãŠãŒã¹ã±ãŒã¹ã«åãããŠãCSSã¢ãã¡ãŒã·ã§ã³ã«çœ®ãæããŠããã®ãããã§ãããã ããã«ã€ããŠã https://github.com/nefe/You-Dont-Need-jQuery ãåèã«ãªããŸãã You Don't Need jQueryã«ã¯èŒã£ãŠããªããã¢ãã¡ãŒã·ã§ã³ã䌎ãã¹ã¯ããŒã«ã¯ä»¥äžã®ããã«å®è£
ããŸããã /** * æå®ããèŠçŽ ãŸã§ã¹ã¯ããŒã«ãã * @param {string} selector ã¹ã¯ããŒã«å¯Ÿè±¡ã®HTMLèŠçŽ ã®CSSã»ã¬ã¯ã¿ * @param {number} step ã¹ã¯ããŒã«å¹
(px) * @param {number} timeout ã¹ã¯ããŒã«ãè¡ãéé(ms) */ export function scrollToElement( selector, { step = 100, timeout = 16 } = {} , ) { const target = document .querySelector(selector); if (!target) return ; // ç®çå°ã®Yåº§æš const destY = target.offsetTop; // ç®çå°ãçŸåšäœçœ®ããäžã«ããå Žåã¯äž(è² ã®step)ãäžã«ããå Žåã¯äž(æ£ã®step)ã«ã¹ã¯ããŒã« const stepWithDirection = destY < window .scrollY ? -step : step; const scrollByStep = () => { if (Math.abs( window .scrollY - destY) > step) { // step ãããè·é¢ãéããŠãããšãã¯scrollByã§è¿ã¥ã window .scrollBy(0, stepWithDirection); setTimeout(scrollByStep, timeout); } else { // step 以äžã®è·é¢ãŸã§è¿ã¥ãããscrollToã§ããã¿ãªç§»åãã window .scrollTo(0, destY); } } ; setTimeout(scrollByStep, timeout); } $.ready() $.readyã¯ãã©ãŠã¶ã®å¯Ÿå¿ç¶æ³ã«ããã㊠load ãš DOMContentLoaded ã䜿ãåããŠãããŸãããããã§ã«DOMContentLoadedæªå¯Ÿå¿ãã©ãŠã¶ïŒIE 8以åïŒã¯æ»
ã³ãŠããã®ã§ãDOMContentLoaded ã®ã¿ã§OKã§ãããã $.ready( function () { // åŠç } ); $( function () { // åŠç } ); document .addEventListener( 'DOMContentLoaded' , () => { // åŠç } ) ã€ãã³ããã£ã«ã¿ãªã³ã° jQueryã ãšããdoumenté
äžã®clickã€ãã³ããå
šãŠãã£ãããããã®ã¯ãªãã¯å¯Ÿè±¡ãããã³ã¯ãªãã¯å¯Ÿè±¡ã®èŠªèŠçŽ ãç¹å®ã®å±æ§ããã€å Žåã«ã ããã³ãã©ãå®è¡ããããšããåŠçãã以äžã®ããã«ç°¡åã«æžããŸãã $( document ).on( 'click' , '[data-xxx]' , eventHandler); ãããDOMã®æšæºAPIã§å®è£
ãããšãå°ã
é¢åã§ãã function findParentByAttribute(target, attributeName) { let el = target; while (el.parentNode) { if (el.getAttribute(attributeName)) { return el; } el = el.parentNode; } return null ; } document .addEventListener( 'click' , event => { if (!findParentByAttribute( event .target, 'data-xxx' )) return ; // handle event } ); jQueryã®äœ¿çšãé²ãç®å° jQueryãåãé€ãäœæ¥ããããã¡ã€ã«ã«ã¯ãå
é ã«ä»¥äžã®èšè¿°ã远å ããŠãjQueryã䜿ã£ãŠã¯ãã¡ãªããšããããããã«ããŸããã // ãã®ãã¡ã€ã«ã§ã¯jQuery䜿çšçŠæ¢ïŒ const $ = undefined ; ãã®ã³ãŒãã¯ãããŒã«ã«å€æ°ã® $ ãå®çŸ©ããŠãundefinedã§åæåããŸããããã«ãã£ãŠãã°ããŒãã«ãª $ ã¯ããŒã«ã«ã® $ ã§ã·ã£ããŠãããŸãïŒã°ããŒãã«ãª $ ã¯äžæžããããŸããããã·ã³ãã«ã®æ¢çŽ¢ã§ã¯ããŒã«ã«ã® $ ãåªå
ãããŸãïŒãããã«ã $ ã®å€ã¯undefined ãªã®ã§ã $() ãªã©ã®åŒã³åºããè¡ããšãšã©ãŒãçºçããŸããconstãªã®ã§å代å
¥ãã§ããŸããã ããã§ãã window.$ ã window.jQuery ãjqueryã®importãªã©ãjQueryã«ã¢ã¯ã»ã¹ããææ®µã¯æ®ãããŠããŸããããäžäŒ.coméçºããŒã ã®èŠæš¡ãã¹ãã«ãèãããšããã®æ¹æ³ã§ååãšå€æããŸããã ãªããäžèšã³ãŒãã¯ES ModulesïŒãŸãã¯webpackïŒç°å¢ã§ã®åäœãåæã«ããŠããŸããES Modulesã¯ãã¡ã€ã«æ¯ã®ã¹ã³ãŒããåã£ãŠãããŸãããES Modulesã䜿ã£ãŠããªãå Žåã峿颿°ã§ã¹ã³ãŒããåãããšã§åãããšãã§ããŸãã ( function () { // ãã¡ã€ã«ã®å
é // ãã®ãã¡ã€ã«ã§ã¯jQuery䜿çšçŠæ¢ïŒ const $ = undefined ; ... } )(); // ãã¡ã€ã«ã®æ«å°Ÿ jQueryåé€ã®å¹æ jQueryåé€å jQueryåé€åŸ âã¯ãjQueryåé€ååŸã®PageSpeed Insightsã®ã¹ã³ã¢ã§ããã©ã¡ãã71ç¹ãTime To Interactive/First CPU Idleã¯æ¹åããŠããŸãããSpeedIndexã¯æªåããŠããŸãããã®çšåºŠã®å€åã¯äœã倿ŽããªããŠãèµ·ããã®ã§ãã¹ã³ã¢ãå€ããã»ã©ã®ã€ã³ãã¯ãã¯ãªãã£ããšããããšã§ããã ããã©ãŒãã³ã¹æ¹åã®èгç¹ããã¯ã jQueryåé€ã¯ãã³ã¹ããæªãã£ã ãšããçµè«ã«ãªãããšæããŸãããã¶ããåãæéãå¥ã®ã¿ã¹ã¯ã«äœ¿ãã°ããã£ãšæ¹åã§ããã¯ãâŠã ãªããä»åãã®çµè«ã«éããã®ã¯ãæ¢åã³ãŒãã®jQueryãžã®äŸå床ãé«ãã£ããããšããçç±ããããŸãããµã¯ããšåãé€ãããããªç¶æ
ãªãããã£ãšã³ã¹ãã¯è¯ãã£ããšæããŸãããŸããäžäŒ.comã®ããã«ããŒãžã¹ããçã«ãããŠã¯å¹æããªãã£ããšããããšã§ãããæ¡ä»¶ãç°ãªãã°ãå¥ã®çµæãåŸããããšæããŸãã ãŸãšã ããã©ãŒãã³ã¹ã®èгç¹ããã¯ãããŒãããJSã®éãæžããããšã¯éèŠã§ããäžæ¹ã§ãJSã©ã€ãã©ãª30KBçšåºŠã®åé€ã ãšã誀差ã®ç¯å²çšåºŠã®æ¹å广ããåŸãããªãããšããããšãããããŸããã塵ãç©ããã°å±±ãšãªãã®ã§ãç¡é§ã§ã¯ãªããšæããŸããããã£ãšã³ã¹ãã®è¯ãæ¹åæœçã宿œããŠãããããšããã§ãã åç¥ Bonfire Frontend #3ãã1/24ã«éå¬ãããŸããããŒãã¯ãããã©ãŒãã³ã¹æ¹åãã§ããä»åãYahooã°ã«ãŒãã®ããã¿ã§ïŒïŒïŒã声ããããã ããç»å£ããæ©äŒãããã ããŸãããä»åã®èšäºã®ãããªãäžäŒ.comã§é²ããŠããããã©ãŒãã³ã¹æ¹åã®ã話ããããããšæã£ãŠããã®ã§ãæ¯éãåå ãã ããïŒïŒãã§ã«æºåžã§ããã1/18ã«æœéžãªã®ã§ããŸã éã«åããŸãïŒ yj-meetup.connpass.com http://infrequently.org/2017/10/can-you-afford-it-real-world-web-performance-budgets/ ↩ äžäŒ.comã§ã¯åç·é床ã®ããŒã¹ã©ã€ã³ã1.4Mbpsã§èããŠããŸããLighthouseã®Slow 4Gçžåœã§ãã ↩
ããŒã¿ãµã€ãšã³ã¹éšã»å€§è¥¿ id:ohke ã§ãã äžäŒã®1 to 1ããŒã±ãã£ã³ã°ãæ¯ãããã©ãããã©ãŒã ã«ã€ããŠã話ããããšæããŸãã 1 to 1ããŒã±ãã£ã³ã° äžäŒã®äž»åã§ãã宿æ³äºçŽãµãŒãã¹ã¯ä»å¹Žã§19幎ç®ãã¬ã¹ãã©ã³äºçŽãµãŒãã¹ã13幎ç®ãè¿ããäŒå¡æ°ã800äžäººãè¶
ããŸããã äžäŒã®ãµãŒãã¹ããç¥ããªãã£ãããããç¥ã£ãŠããããšããæçãã§ãŒãºã«å
¥ã£ãŠããŸããšãé客ã«å ããŠã1 to 1ããŒã±ãã£ã³ã°ãããéèŠã«ãªã£ãŠããŠãŸãã äžäŒã®1 to 1ããŒã±ãã£ã³ã°ã§å€§äºã«ããŠããããšã¯3ç¹ã§ãã æœçã«å¿
èŠãªããŒã¿ã¯å
šãŠããŒã¿ãŠã§ã¢ããŠã¹ (DWH) ãžéçŽãã ãªãŒãã¡ãŒã·ã§ã³ããŒã« (å
補ã®Webã¢ããªã±ãŒã·ã§ã³) ã§ã¿ãŒã²ããã®æœåºãã³ã³ãã³ãã®äœæãé
ä¿¡ãäžå
管çãã ãŠãŒã¶ããšã«ã³ã³ãã³ããæé©åãã (ã¬ã³ã¡ã³ã) DWHãšETL 1 to 1ããŒã±ãã£ã³ã°ã§ã¯ããŠãŒã¶ã®éå»ã®è¡åã«åºã¥ããŠæœçã宿œããŠãããŸãã ãã®ãããäºçŽæ
å ± (ãµãŒãã¹ã®ããŒãã«ããŒã¿) ãã¢ã¯ã»ã¹æ
å ± (Google Analyticsãšå
補ã®ãªã¢ã«ã¿ã€ã ãã°åéããŒã« 1 ) ãããã³ããããšçŽä»ããã¹ã¿ããŒã¿ãªã©ã¯ãå
šãŠDWHã«éçŽããŠããŸãã DWHã«ã¯ãSQL Server (RDS) ã䜿ã£ãŠããŸããSQL Server Management StudioãRedashã§SQLãæžãã°ã誰ã§ãéèšã»åæãè¡ããããã«ãªããŸãã DWHãžã®æ¥ã
ã®ETL (æœåºã»å å·¥ã»æ ŒçŽ) ã¯æ¥µããŠéèŠã«ãªããŸãã ETLã倱æã»é
å»¶ãããšãããŒã¿ã«ã¢ã¯ã»ã¹ã§ããªããªãã1 to 1ããŒã±ãã£ã³ã°ã«æ¯éãæ¥ããŠããŸããŸããããŒã±ãã£ã³ã°ã®æè以å€ã«ããDWHã¯ãCEOãã¯ããåäºæ¥éšé·ãé客ããŒã ã»UI/UXããŒã ã®å®ç¹èŠ³æž¬ãæææ±ºå®ã«å©çšããããããããŒã¿ãç¡ãã»ééã£ãŠããããšã«ãã圱é¿ã¯ç倧ã§ãã äžäŒã§ã¯ETLã管çããããŒã«ãšããŠã Apache AIrflow ãå°å
¥ã»éçšããŠããŸãã ã user-first.ikyu.co.jp æ¥æ¬¡ã ãã§çŽ400ã¿ã¹ã¯ (1ã¿ã¹ã¯ã1ã€ã®ããŒãã«ã®ãšã¯ã¹ããŒããªã©ãšå¯Ÿå¿ããŸã) ãããã«é±æ¯ã»ææ¯ãªã©ã®ã¿ã¹ã¯ããããããšãããããå€§èŠæš¡ãªETLãšãªããŸãã DWHãšETLãå¥å
šãªç¶æ
ã«ç¶æãç¶ããããã«ã以äžã®æ¹åã»éçšãè¡ã£ãŠãŸãã 瀟å
ã®åéšçœ²ããäŸé ŒãããDWHãžã®ããŒã¿è¿œå ãèšç®æ¹æ³å€æŽãžã®å¯Ÿå¿ åéšçœ²ã§èªç¶çºççã«æã£ãŠããETLåŠçãAIrflowãžçµ±å äºæ¥æ
åœè
(ããŒã±ã¿ãå¶æ¥) ãå®è¡ããã¯ãšãªã®ãã¥ãŒãã³ã° æ»çã¯ãšãªã®èªåæ€ç¥ã»é€å» ãªãŒãã¡ãŒã·ã§ã³ããŒã« 1 to 1ããŒã±ãã£ã³ã°ã§ã¯ããã®åã®éãããŠãŒã¶äžäººã²ãšãã«å¯ãæ·»ã£ãŠãªããã°ãªããŸããããããäžæ¹ã§ãã¢ãããŒããããŠãŒã¶æ°ãæžãããããªãã®ã§ãå¿
ç¶çã«ãå°æ°ã®ãŠãŒã¶ã«æ·±ãã¿ãŒã²ããããæœçãããããå®è¡ããå¿
èŠããããŸãã 1 to 1ããŒã±ãã£ã³ã°æœçã®å®è¡ã«ããã£ãŠã¯ã倧ãŸãã«ãã¿ãŒã²ããã®æœåºãã³ã³ãã³ãã®äœæãé
ä¿¡ãšãã3段éã®äœæ¥ãè¡ããŸãã åŸæ¥ã¯ä»ç€Ÿã®ããŒã±ãã£ã³ã°ã¡ãŒã«é
ä¿¡ãµãŒãã¹ã䜿ã£ãŠããŸããããæ°å以äžã®æœçã宿œããã«ããã£ãŠã倧ããªå£ã«ã¶ã€ãããŸããã ã¿ãŒã²ãããã³ã³ãã³ãã«åã蟌ãå€ã®æœåºã¯ãããŒã±ã¿ã®æ¥ã
ã®æéçšã«é ŒãããŠãããããã¹ã±ãŒã«ããªã SQLã§æœåºããCSVãã¡ã€ã«ããã¡ã€ã«ãµãŒãã«ã¢ããããŒãããããšããããšãæœçããšã«è¡ã£ãŠããŸãã é
ä¿¡ã¯ä»ç€Ÿã®ãµãŒãã¹ä»»ããšãªã (äžäŒã§ã³ã³ãããŒã«ã§ããªã) ãããäºæ
ç¡ãéçšããããã«ã¯ç¿çãå¿
èŠ ãŸããã¡ãŒã«ã ãã§ã¯ãªãããµã€ãã«æ¥èšªããŠãããŠãŒã¶ã«ãã¢ãããŒãããããã«ã以äžã®æ°ãããã£ãã«ãèŠä»¶ãšããŠçãŸããŠããŸããããããã®ãã£ãã«ããµãŒãã¹ã«å¯ã«çµã¿èŸŒãã§ããŸããšãæœçã®ãã³ã«ããŒã±ã¿ãšäºæ¥éšã®ãšã³ãžãã¢ã»ãã¶ã€ããååãããããªããããã¯ã€ãã¯ã«æœçãå®è¡ã§ããªããªããŸãã ãµã€ãã¡ãã»ãŒãž: ãµã€ãäžã§ã®ãç¥ãããã¯ãŒãã³é
åžã«äœ¿ãããŸã ãããã¢ãã: ãµã€ãã¡ãã»ãŒãžããã蚎æ±åã匷ããã¯ãŒãã³é
åžã«äœ¿ãããŸã ããã§ã ã¿ãŒã²ããã®æœåºã»ã³ã³ãã³ãã®äœæã»é
ä¿¡ãäžå
管çãããªãŒãã¡ãŒã·ã§ã³ããŒã« (Webã¢ããªã±ãŒã·ã§ã³) ãå
補 ããããšã§ãäžã®èª²é¡ã®è§£æ±ºãå³ããŸããã ã¿ãŒã²ãããã³ã³ãã³ãã«åã蟌ãå€ã®æœåºããDWHãžçºè¡ããSQLã§èšè¿°ã§ããããã«ãã 2 ããã¹ããHTMLãç·šéã§ããããã«ããããšã§ãèªç±ã«ãã¶ã€ã³ã倿Žã»ãã¬ãã¥ãŒã§ããããã«ãã é
ä¿¡ã®ãã£ãã« (ã¡ãŒã« or ãµã€ãäžã®ã¡ãã»ãŒãž or ãµã€ãäžã®ãããã¢ãã) ãæ¥æãåªå
床ãªã©ã確èªã»å€æŽã§ããããã«ãã é
ä¿¡ã¯å
šãŠãªãŒãã¡ãŒã·ã§ã³ããŒã«ã§è¡ããããåºæ¬çã«ã¯äºæ¥éšã®ãšã³ãžãã¢ã»ãã¶ã€ããšã³ãã¥ãã±ãŒã·ã§ã³ããå¿
èŠãç¡ã ãªãŒãã¡ãŒã·ã§ã³ããŒã«ã®å°å
¥ãšããã®åŸã®ããŒã±ã¿ã®çްãããªæœçèšèšã«ãã£ãŠãçŸåšã§ã¯æ¯æ¥100è¿ãã®æœçããã®ããŒã«ããå®è¡ãããŠããŸãã æ¥ã
ã®å¹ææž¬å®ã¯ãGoogle Analyticsãªã©ã䜿ã£ãŠåéããRedashã§ããžã¥ã¢ã©ã€ãºããŠãSlackã«éç¥ãããšããã«ãžã¥ã¢ã«ãªæ¹æ³ãæ¡ãããšãå€ãã§ãã ãªãŒãã¡ãŒã·ã§ã³ããŒã«ãã®ãã®ã¯ä»¥äžã®ã¢ããªã±ãŒã·ã§ã³æ§æãšãªã£ãŠããŸãã ãµãŒããµã€ãã¯ãPython + Flask + SQL Alchemy ããã³ããšã³ãã¯ãReact CI/CDã¯ãCircleCI + CodeDeploy ãªãŒãã¡ãŒã·ã§ã³ããŒã«ããã®é
ä¿¡ã¯ããã£ãã«ããšã«ç°ãªãæ©æ§ã§è¡ã£ãŠããŸãã ã¡ãŒã«ã¯ããµãŒãã¹ãšåçã®æ§æãããŒã±ãã£ã³ã°çšã«æ§ããŸãã 3 ãµã€ãã¡ãã»ãŒãžãšãããã¢ããã¯ãRDS (SQL Server) ã«é
ä¿¡ãªã¹ããæž¡ããAPI (Go) çµç±ã§ãµãŒãã¹ããã¢ã¯ã»ã¹ããããšã§å®çŸããŸãã ããããã®é
ä¿¡çµæãDWHãžETLããããšã§ãéå°çã®éèšãå¹ææž¬å®ãè¡ã£ãŠãŸã ã¬ã³ã¡ã³ã ããããªãŒãã¡ãŒã·ã§ã³ããŒã«ã§ç°¡åã«ãŠãŒã¶ãžé
ä¿¡ã§ããããã«ãªã£ããšããŠãããã®ãŠãŒã¶ã«ãšã£ãŠå¬ããæ
å ±ã§ãªããã°ãªããŸããã ããã«ãã¬ã¹ãã©ã³ã®äºçŽãæäŸããŠããäžäŒã«ãšã£ãŠãããã®ãŠãŒã¶ãã©ã®ããã« or ã©ã®ã¬ã¹ãã©ã³ãããããããããšåã°ãããããšããã®ã¯ããµã€ãã§ã®æ€çŽ¢çµæããªããŒã±ãã£ã³ã°æœçã§ã¯éèŠãªããŒãã§ããç¹ã«ããŠãŒã¶ã®çŽè¿ã®è¡åãåæ ã§ããªããªããŒã±ãã£ã³ã°æœç (äŸãã°ãæ°ã¶æåã«å®¿æ³ãããŠãŒã¶ã察象ãšããã¡ãŒã«) ã§ã¯ãèå³ãåŒãã³ã³ãã³ããšãªã£ãŠããªããšãŠãŒã¶ã®å¿ãé¢ãã (èŠããã«ãŠã¶ããšæããã) èŠå ãšãªã£ãŠããŸããŸãã äžäŒã§ã¯ããµã€ãã§ã®æ€çŽ¢çµæããªããŒã±ãã£ã³ã°ã¡ãŒã«ã«è¡šç€ºãããããã«ãã¬ã¹ãã©ã³ã®ãªã¹ãã¯ãåãŠãŒã¶ã®éå»ã®è¡åãåæ ãããã®ãšãªã£ãŠãŸãã ã¬ã³ã¡ã³ã ãšåŒãã§ããŸãã å
·äœçã«ã¯ãããã«ãã¬ã¹ãã©ã³ã§ã®è¡å (äºçŽãã¢ã¯ã»ã¹ãªã©) ãå
ã«ãã¢ã€ãã ããŒã¹ã®å調ãã£ã«ã¿ãªã³ã°ãçšããŠãé¡äŒŒããããã«ãã¬ã¹ãã©ã³ããããããããšããããžãã¯ã«ãªã£ãŠããŸãããããã®ããžãã¯ãDWHäžã®ããŒã¿ã䜿ã£ãŠèšç®ããŠããŸãã ãµã€ãã§ã®æ€çŽ¢çµæã«ãåæ§ã®ããžãã¯ã§ã¬ã³ã¡ã³ãããŠãŸããããªã¢ã«ã¿ã€ã ãªæ
å ±ã䜿ãå¿
èŠãããããšãããã³ããµãŒãã¹ã«çµã¿èŸŒãããã«å
ç¢æ§ãæ±ããããããšãããAPIãšããŠæäŸããŠãŸãã ãã®APIã¯ä»¥äžã®ãããªæ§æãšãªã£ãŠããŸãããããããµãŒãã¹ããå©çšãããã¢ããªã±ãŒã·ã§ã³ã®éçºã»éçšãããŒã¿ãµã€ãšã³ã¹éšã®åœ¹å²ã§ãã å®è£
ã¯Python + Flaskã§ãå
šãŠãªã³ã¡ã¢ãªã«å±éããŠãªã¯ãšã¹ãéœåºŠã§èšç®ããŠãŸã ã€ã³ãã©ã¯ãECS + ElasticBeanstalk CI/CDã¯ãCircleCI 課é¡ã¯å±±ç©ã¿ã§ã ä»åã話ããäžã§ãããŸã ãŸã åãçµããŠããªã課é¡ã¯ãããããããŸãã DWH/ETLããªãŒãã¡ãŒã·ã§ã³ããŒã«ã®å®å®å å¶æ¥æéåã«ããŒã¿ãåºæã£ãŠãªããšãéèšã»åæãæœçã®ç²ŸåºŠãèœã¡ãŠããŸãã®ã§ãETLã®å質ãæ
ä¿ãç¶ããŠãããªããšãããŸãã ãããŸã§çéããŠããªãããŒã±ã¿ãSQLããã¶ã€ã³ãèªç±ã«èšè¿°ã§ããã®ã§ã倧ããªäºæ
ã«ã€ãªãããªãããã«ã·ã¹ãã ã§çްããã«äºé²ããå¿
èŠããããŸã ãæ€èšŒé
ä¿¡ãããèšç®ããã(ä»¶æ°ãã§ãã¯) ã¯ãã®ããã®ä»çµã¿ãšãªã£ãŠãŸã é
ä¿¡ã¿ã€ãã³ã°ã®æé©å ãã®ãŠãŒã¶ã«ã¯æ8:00ããã®ãŠãŒã¶ã«ã¯å€7:00ãªã©ããŠãŒã¶ããšã«ãã£ãã«ã«è§Šããæé垯ãç°ãªã ãã®ãŠãŒã¶ããã£ãã«ã«è§Šããæé垯ãçã£ãŠã¢ãããŒãããã å調ãã£ã«ã¿ãªã³ã°ã«ãã£ãŠå£²ãäžãã®ãªããã«æåããŠããŸãããæŽãªãUXåäžã®ããã«å¥ã®ã¢ãããŒããæš¡çŽ¢äž å調ãã£ã«ã¿ãªã³ã°ã§ã¯ãã©ã€ããŠãŒã¶ã®å Žåã«ã¯æ
å ±ãäžè¶³ããŠãããããã¬ã³ã¡ã³ãã«ãããªãããå°ãããªã£ãŠããŸããŸã (ããããã³ãŒã«ãã¹ã¿ãŒãåé¡) ãããŒãŠãŒã¶ã§ãããŠãŒã¶ã®å奜ãåžžã«äžå®ã§ã¯ç¡ãããŠãŒã¶ã®ã³ã³ããã¹ã (ç®çãäžç·ã«è¡ãäººãæ°åãªã©) ãæ±²ã¿åãå¿
èŠããããŸã 以åã€ã¿ãªã¢æçåºã«è¡ã£ããããšèšã£ãŠãæªæ¥æ°žå«ã€ã¿ãªã¢æçåºã«è¡ããšã¯éããŸãã ãªã¢ã«ã¿ã€ã ã®ãŠãŒã¶è¡åãåæ ããªããããã®æç¹ã§ãã®ãŠãŒã¶ã«ãšã£ãŠæããã£ããããããã« or ã¬ã¹ãã©ã³ãããããã§ããããã«ãªãããšãç®æããŠãŸã äžã«å ããŠãããŒã¿ãµã€ãšã³ã¹éšãšããŠã¯ä»ã«ãæ§ã
ãªèª²é¡ã«åãçµãã§ããŸãã æ¥å¢ããã¬ã¹ãã©ã³ãžã®å¶æ¥æŽ»åãæé©åãã æœè±¡çãªã¯ãŒãã§ãè¯ãæãã«ã¬ã¹ãã©ã³ãæ€çŽ¢ã§ããããã«ãã ã¯ãŒãã³æœçã®æé©å (æçåå²ç¹ã®äºæž¬ãªã©) ãªã©ãªã©ãªã©ãªã©... ããŒã¿ãµã€ãšã³ã¹éšã§ã¯ãããããåãçµã¿ã4人ã§éè¡ããŠããŸã (2018/12çŸåš) ã äžç·ã«åãçµãã§ããã ãã仲éãåã£ãŠãŸã DWHãETLã®æ¹åã«çããïŒ äžäŒã®çµå¶ãæœçã®æ ¹å¹¹ãæãããŒã¿ã®å®å®äŸçµŠã®ããã«ãèªãèšèšã»æ§ç¯ã»éçšã§ããŸãã データプラットフォームエンジニア(正社員) | 株式会社一休 å
補ã¢ããªã±ãŒã·ã§ã³ãã¯ã€ãã¯ã«éçºã»æ¹åãããïŒ ããã³ããšã³ããããã¯ãšã³ããã€ã³ãã©ãCI/CDãèªåã§èããŠéçºã§ããŸãã CEO直轄 アプリケーションエンジニア (正社員) | 株式会社一休 çµ±èšã¢ããªã³ã°ãæ©æ¢°åŠç¿ã§ãã£ãšãã£ããã課é¡ã解決ãããïŒ é«äŸ¡æ Œåž¯ã®ãµãŒãã¹ECãµã€ãã§ãã®ã§ãä»ã®ãµãŒãã¹ãšäžç·ãç»ããããŒãã®åé¡ã«åãçµããŸãã データサイエンティスト (正社員) | 株式会社一休 機械学習エンジニア (正社員) | 株式会社一休 èªãèããæœçã§ãã£ãšãŠãŒã¶ã«æããããµãŒãã¹ãžè²ãŠããïŒ CEOçŽäžã§æœçã®ç«æ¡ã»éè¡ã»æ¹åã«åãçµããŸãã www.wantedly.com 詳ããçµç·¯ã¯ãã¡ã â データ分析基盤、その後 - 一休.com Developers Blog ↩ äžäŒã®ããŒã±ã¿ã¯SQLãæžããŸãã ↩ 詳ããã¯ãã¡ã â 新メール配信基盤への移行 /ikyu-mail-platform - Speaker Deck ↩
ããã«ã¡ã¯ã仿¥ã¯ã€ãã³ãç»å£ã®ãç¥ããã§ãã 1/30(æ°Ž) ã«ãã€ãããããäž»å¬ãããITSearch+ãã®ã€ãã³ãã«åŒç€Ÿãšã³ãžãã¢ã® 埳æŠ( id:s-tokutake ) ãç»å£ããŸãã äžäŒcom on ã¯ã©ãŠã ~ æ¥æé·ãæ¯ããæè¡åºç€ãšSRE ~ ä»åã¯ãæè¡åºç€ãSREããããŒããšã㊠äžäŒ.com / äžäŒã¬ã¹ãã©ã³ã®ã¯ã©ãŠãç§»è¡ ã軞ã«ã以éååŸã§ã€ã³ãã©ãæè¡åºç€ã®ä»äºãã©ã®ããã«å€ãã£ãŠããŠãããããµãŒãã¹ã®æé·ãæ¯ããªããéçºçç£æ§ãã©ãäžããŠããã®ããªã©ãå
·äœçãªäºäŸãããšã«ã話ããäºå®ã§ãã ãç³èŸŒã¿ã¯ãã¡ãããã news.mynavi.jp ãèå³ã®ããæ¹ã¯ãã²ãåå ãã ããã ãŸãã€ãã³ãéå¬åŸã«ãçºè¡šã¹ã©ã€ããããšã«ã¬ããŒããæžããããšæããŸãã®ã§ããã¡ãããæ¥œãã¿ã«ïŒ
ãã®èšäºã¯äžäŒ.com ã¢ããã³ãã«ã¬ã³ããŒã®25æ¥ç®ã®èšäºã§ãã ã¬ã¹ãã©ã³äºæ¥éšãšã³ãžãã¢ã® id:ninjinkun ã§ãã äžäŒ.comåã³äžäŒ.comã¬ã¹ãã©ã³ã¯ãŠãŒã¶ãŒåãã®ã·ã¹ãã ã ãã§ã¯ãªããåºèãäžäŒå
ã®ç®¡çè
åãã®æ¥åã·ã¹ãã ãšããæ§æ Œãæã£ãŠããŸãã æ¥åã·ã¹ãã çµéšã®ç¡ãã£ãèªåãäžäŒã«è»¢è·ããŠæåã«é©ããã®ããDBã«å±¥æŽãä¿æããããã® å±¥æŽããŒãã« ã倧éã«ããããšã§ããã ããããå±¥æŽããŒãã«ã®ååšã«èå³ãšçåãæã¡ã瀟å
å€ã®ãšã³ãžãã¢ãšå±¥æŽããŒãã«ã«ã€ããŠè°è«ããŠããŸããããã®ãšã³ããªã§ã¯ãããã®è°è«ããŸãšããçµæã«ã€ããŠæžããŠãããŸãã å±¥æŽããŒãã«ã®ãã¿ãŒã³ ãŸã以äžã®å³ãã芧ãã ããã 蟌ã¿å
¥ã£ãå³ãã€äºäŸãäžäŒç¹åã§æçž®ã§ãããå·Šäžã®èµ·ç¹ããå§ãŸã£ãŠãå³ã®ãªã¬ã³ãžã®éšåãæçµçãªå®è£
ãã¿ãŒã³ã§ãã å³ã«ãããšããããããŠãã®ãŠãŒã¹ã±ãŒã¹ã§ã¯ä»¥äžã®3ãã¿ãŒã³ã®å®è£
ã«èœãšã蟌ããã®ã§ã¯ãªãããšèããŠããŸãã ããŒãžã§ã³ããŒãã« ãã°ããŒãã« ElasticSearchãBigQueryãªã©ã«æŸã蟌ã ãããªããããŒãžã§ã³ããŒãã«ããããã°ããŒãã«ããªã©ã®åèªãåºãŠããŸããããããã¯èªåããå±¥æŽããŒãã«ãã现ååããããã«äœ¿ã£ãŠããèšèã§ãã以äžã§ããããã«ã€ããŠèª¬æããŸãã 1. ããŒãžã§ã³ããŒãã« ã¢ããªã±ãŒã·ã§ã³ããç¹å®ã®ããŒãžã§ã³ãåç
§ããå¿
èŠãããã®ã§ã以äžã®æ§ã«ããŒãžã§ã³çªå·ãä¿æããããŒãã«ãäœããŸãã å
ããŒã¿ããŒãã« äŸ¡æ Œãå€ããååã®äŸã§ããIDãšææ°ã®ããŒãžã§ã³çªå·ãä¿æããŠããŸãã id version price 1 2 1,000 2 1 2,000 3 3 10,000 ããŒãžã§ã³ããŒãã« ä»ãŸã§ã®äŸ¡æ Œå€åãããŒãžã§ã³æ¯ã«ãã¹ãŠèšé²ãããŠããŸãã id item_id version price 1 1 1 1,100 2 2 1 2,000 3 3 1 11,000 4 3 2 10,500 5 1 2 1,000 6 3 3 10,000 2. ãã°ããŒãã« åºæ¬çã«ã¢ããªã±ãŒã·ã§ã³ããåç
§ããªãåæã§ãããåç
§ããå ŽåãäžèЧã§ç¢ºèªçšã«è¡šç€ºããããããªã®ã§ãããŒãžã§ã³çªå·ãªã©ã¯äžèŠã§ãã å
ããŒã¿ããŒãã« id price 1 1,000 2 2,000 3 10,000 ãã°ããŒãã« å
ããŒã¿ããŒãã«ãšåãã«ã©ã + ãã°çšã®äœææ¥ãæã€ãæŽæ°ããã£ããã®ãã©ãã©ãæŸã蟌ãã§ãããŸããææ°ãã©ããã¯äœææ¥ã§å€æããŸãã id item_id price log_created_at 1 1 1,100 2018-11-10 12:00:00 2 2 2,000 2018-11-10 12:01:00 3 3 11,000 2018-11-10 12:02:00 4 3 10,500 2018-11-15 12:00:00 5 1 1,000 2018-11-18 11:00:00 6 3 10,000 2018-20-10 13:00:00 3. ElasticSearchãBigQueryãªã©ã«æŸã蟌ã ãã¡ãã®ãã¿ãŒã³ã«ã€ããŠã¯äžäŒã§ã¯æ¡çšããŠããªãã®ã§è©³çްããªãã®ã§ããã瀟å€ã®ãšã³ãžãã¢ã«å±¥æŽã«ã€ããŠçžè«ããéã«ããã¡ã§ã¯ããããŠãããããšããäºäŸãšããŠèãããã®ã§ãã ãªãŒãºããã«ãªè§£æ±ºçã ãšæãã®ã§ãã©ããã§æ¡çšããããšèããŠããŸãã ããŒãã«ã®è©³çް ããŒãã«èšèšã®è©³çްã«ã€ããŠãè§ŠããŠãããŸãã å¥ããŒãã« vs ã€ãã¥ãŒã¿ãã« èªåãæåã«å±¥æŽããŒãã«ãèŠãæã«æããã®ã¯ãå±¥æŽãšããŠç¬ç«ããããŒãã«ã¯å¿
èŠãªã®ãïŒããšããçåã§ãããå±¥æŽãšããŠç¬ç«ããããŒãã«ãç¡ããŠããåãããŒãã«ã«å€æŽãå
šãŠæ®ãããã«èšèšããã°ãå¥ããŒãã«ã¯ãªããŠãå±¥æŽã¯äœãããšãã§ããŸããèªåã¯ãããã€ãã¥ãŒã¿ãã«ãã¿ãŒã³ãšåŒãã§ããŸãã ããã®è°è«ã«ã€ããŠã¯ä»¥äžã®ãšã³ããªãåèã«ãªããŸãã èªåãèŠãŠããç¯å²ã§ã¯ãäžèšãšã³ããªã®2ã®ãã¿ãŒã³ãã€ãŸãã€ãã¥ãŒã¿ãã«ã§ã¯ç¡ããå¥ããŒãã«ã«å
ããŒãã«ãšåãã«ã©ã ãäœã£ãŠãèšé²ããã®ãæçµçã«äžçªç©åœãªèœãšãã©ããã«ãªãã±ãŒã¹ãå€ãããã§ãã èªåãèããããããã®ã¡ãªããããã¡ãªããã¯ä»¥äžã®éãã§ãã ã¡ãªãã ãã¡ãªãã ã€ãã¥ãŒã¿ãã« ããŒãã«ã1ã€ã§æžãã§ç¶ºéºã«èŠãã æžã蟌ã¿ãäžåã§æžã select ããéã«max()ã§ææ°ã®è¡ãçµã蟌ãå¿
èŠãããïŒactiveãã©ã°ãªã©ã§è§£æ±ºã¯å¯èœã ããããŒãã«ããã¯ãæããå¿
èŠãçºçãããšæãããïŒ å¥ããŒãã« èŠãç®ã§å±¥æŽã§ããããšããããããã 2ã€ã®ããŒãã«ã«åæã«æžã蟌ãå¿
èŠããã ã€ãã¥ãŒã¿ãã«ãã¿ãŒã³ã«ãã¡ãªããã¯ããã®ã§ãããçµå±ãããããããšå®è£
ã®ããããããå¥ããŒãã«ãã¿ãŒã³ãæ¡çšãããããšãå€ãããã§ãã ããŒã¿ããŒã¹ããªã¬ãŒ vs ã¢ããªã±ãŒã·ã§ã³åŽã§ã³ã㌠å¥ããŒãã«ãšããŠèšèšããå ŽåãããŒã¿ãã³ããŒããå®è£
ã«ã¯ããŒã¿ããŒã¹ããªã¬ãŒãšã¢ããªã±ãŒã·ã§ã³ã³ãŒãïŒèŠãã©ã³ã¶ã¯ã·ã§ã³ïŒã®2ã€ã®éžæè¢ããããŸããã¡ãªãããšãã¡ãªããã¯ä»¥äžã®éãã§ãã ã¡ãªãã ãã¡ãªãã ããªã¬ãŒ DBåŽã§ã³ããŒãèªåçã«èµ°ãããã«æŒããç¡ã ã¢ããªã±ãŒã·ã§ã³ãšããªã¬ãŒã«å®è£
ãåãããŠããŸãã®ã§åŸããåãã远ãã¥ãã ããªã¬ã®ãããã€ãå
ã«ããªããšãšã©ãŒãçºçããã®ã§ããããã€æã«æ°ãé£ãå¿
èŠããã ã³ãŒã ããŒã¿ã®ç®¡çãå
šãŠã³ãŒãã«éäžããã®ã§ãåãã远ãããã ãã¹ããæžãããã ãã©ã³ã¶ã¯ã·ã§ã³ã匵ãå¿ãããšå€§å€ ããŒãžã§ã³ããŒãã«ã®ãã¿ãŒã³ã§ã¯ãããŒãžã§ã³ããŒãã«ã¯ã¢ããªã±ãŒã·ã§ã³ããåç
§ãããã®ã§ãã¢ããªã±ãŒã·ã§ã³ã«å±ããæ©èœã ãšèããããŸãããã®å Žåã¯ã¢ããªã±ãŒã·ã§ã³ã³ãŒãã§å®è£
ããæ¹ãèªç¶ã ãšæããŸãã äžæ¹ã§ãã°ããŒãã«ã®ãã¿ãŒã³ã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã®æ©èœãšããŠæãããããã ã®ãã°ãšããŠæãããã¯è§£éãåããããšããã§ããå®è£
æ¹æ³ãããªã¬ãŒãšã³ãŒããã©ã¡ããéžæè¢ã«å
¥ããšæããŸããèªåã¯ããªã¬ã¯DBåŽã®èšå®ãèŠã«è¡ããªããšæåãææ¡ã§ããªãã®ã§ã極åã¢ããªã±ãŒã·ã§ã³åŽã§å®è£
ããããšæã£ãŠããŸãããã ãçŸå Žã§ã¯åŸããèšŒè·¡ãæ®ããŠæ¬²ãããšèšãããäºãå€ãããã®å Žåã«çæéã§èšŒè·¡ããŒãã«ãå®è£
ããã«ã¯ããªã¬ãéžæãããããšãå€ãã§ãã ãããã« åãã¯éåæãæããŠããå±¥æŽããŒãã«ã§ãããããã¯æç³»åããŒã¿ã®ã¢ããªã³ã°ãªã®ã ãšèããããšã§ãä»ã§ã¯çŽ çŽã«åãå
¥ããããããã«ãªããŸããã ãã®ãšã³ããªã§ãäŒããããããšã®ã»ãšãã©ã¯æåã®å³ã«å
¥ã£ãŠããŸãã®ã§ãããè¯ããããã°ããäžåºŠã芧ãã ããã ããã§æŒããŠãããã¿ãŒã³ãåœç¶ãããšæããŸãã®ã§ããã²çããã®èããæåŒ·ã®å±¥æŽããŒãã«ã«ã€ããŠãæããŠããã ãããšå¬ããã§ãããã¡ã¯ã€ãã³ããœãŒã·ã³ã°ã§å
šéšè§£æ±ºããŠãããïŒãªã©ã®äºäŸãç¥ãããã§ãã
ãã®èšäºã¯äžäŒ.com ã¢ããã³ãã«ã¬ã³ããŒã®24æ¥ç®ã®èšäºã§ãã qiita.com 瀟å
æ
å ±ã·ã¹ãã éšã®å€§å€åïŒ id:rotom ïŒã§ãã äžäŒã«ã¯2018幎8æã«å
¥ç€Ÿããæ
å ±ã·ã¹ãã ãšã³ãžãã¢ãšããŠãIT ãæŽ»çšããæ¥åæ¹åããªãã£ã¹ç°å¢ã®æ§ç¯ãäžå¿ãšãã瀟å
ã®ãæ
ã·ã¹ãæ¥åå
šè¬ãæ
åœããŠããŸãã æ¬ãšã³ããªã§ã¯ã衚ç«ã£ãŠç»å Žããããšã®å°ãªããæ
ã·ã¹ããæ®æ®µäœãããŠããããã玹ä»ããŠãããŸãã æ
ã·ã¹ã®ãä»äº 瀟å
æ
å ±ã·ã¹ãã éšã¯ãã·ã¹ãã æ¬éšãã«æå±ããŠãããçŸåš 6人 ã®ã¡ã³ãã§æ¥åãè¡ã£ãŠããŸãã äžäŒã«ãããæ
ã·ã¹ã¯ä»¥äžã®2ã€ã®åŽé¢ãæã£ãŠããŸãã ã³ãŒãã¬ãŒããšã³ãžãã¢ãªã³ã° ïŒç€Ÿå
ããŒã«ãã·ã¹ãã ã®å°å
¥åã³ç®¡çéçšãbot ãã¹ã¯ãªããéçºã«ããæ¥åã®å¹çåãªã©ã®æ¥åæ¹åã®ä»ããªãã£ã¹ã® IT ã€ã³ãã©ç°å¢ã®æ§ç¯ãæ¹åãªã©ãIT ãæŽ»çšãããã瀟å¡ãããããã©ãŒãã³ã¹ãçºæ®ã§ããç°å¢ãæ§ç¯ãããããããã³ãŒãã¬ãŒããšã³ãžãã¢ãšããŠã®æ¥åãè¡ã ãã«ããã¹ã¯ ïŒå
¥é瀟ã«äŒŽã PC ãiPhoneãiPad ãªã©ã®ã¢ãã€ã«ããã€ã¹ã®èª¿éããããã£ã³ã°ãã©ã€ã»ã³ã¹ã®ç®¡çããæ°å
¥ç€Ÿå¡ãžã® PC ã®ãªãªãšã³ããŒã·ã§ã³ã®ä»ã瀟å¡ããã®PC ã瀟å
ã·ã¹ãã ãIT ããŒã«ã«é¢ããåãåãããããã©ãã«ã·ã¥ãŒãã£ã³ã°ãä¿®çäŸé Œãªã©ã®çæçãªèª²é¡è§£æ±ºãè¡ã IT ãµããŒããè¡ã ããããã®åŽé¢ããèŠãäžäŒã«ãããæ
ã·ã¹ã®åŒ·ã¿ãšåŒ±ã¿ããããŠãããããé²ããŠããããšã«ã€ããŠç޹ä»ããŸãã ã³ãŒãã¬ãŒããšã³ãžãã¢ãªã³ã° 匷㿠äžäŒã§å©çšããŠããã»ãšãã©ã®ç€Ÿå
ããŒã«/ã·ã¹ãã ã§ã¯ãã·ã³ã°ã«ãµã€ã³ãªã³ãã€2段éèªèšŒïŒ2FAïŒãå°å
¥æžã§ããã瀟å¡ã®å©äŸ¿æ§ãšã»ãã¥ãªãã£ãäž¡ç«ãããŠããŸãã ãªãã£ã¹ã§ã¯é«éãªãããã¯ãŒã¯ãæŽåããŠãããå
šåœã®æ¯ç€Ÿã«ãããŠãåäžã® SSID/ãã¹ã¯ãŒãã§ Wi-Fi ãå©çšããããšãã§ããæ±äº¬æ¬ç€Ÿãšåçã®ç°å¢ã§æ¥åãè¡ããããã«æ§ç¯ããŠããŸãã 匱㿠äžäŒ.com ã äžäŒ.com ã¬ã¹ãã©ã³ ãå§ããšããäžäŒã®ãµãŒãã¹ã¯å
šãŠã¯ã©ãŠãïŒAWSïŒäžã§çšŒåããŠããŸãã äžæ¹ã§ãã¬ã¬ã·ãŒãªç€Ÿå
ã·ã¹ãã ãäžéšã®ãã¡ã€ã«ãµãŒãã¯ãªã³ãã¬ãã¹ã§æ§ç¯ãããŠãããã¯ã©ãŠãã«ç§»è¡ãã§ããŠããŸããã çœå®³ãªã©ã§æ±äº¬æ¬ç€Ÿãæ©èœããªããªã£ãéãæ¥åãæ¢ãŸããªãããã瀟å
ã·ã¹ãã ã«ãããŠããè±ãªã³ãã¬ããè¡ãå¿
èŠããããŸãã ããããããããš åè¿°ã®éããçŸç¶è¡ããŠããªã瀟å
ã·ã¹ãã ã®ã¯ã©ãŠãç§»è¡ãé²ããŠããŸãã ãŸããå¶æ¥çŸå Žããã®èŠæã®å€ã LINE WORKS ã®å°å
¥ãã ã·ã¹ãã ã«ããå仿¥åã®å·æ°ãªã©ç€Ÿå
æ¥åãããŒã®æ¹åã«åãçµãã§ãããŸãã line.worksmobile.com ãã«ããã¹ã¯ 匷㿠PC ã®ãããã£ã³ã°ã«äŒŽãåçŽãªã»ããã¢ããäœæ¥ã¯ãããã«ããèªååãããŠããŸãããŸããã¡ãŒãªã³ã°ãªã¹ãã®äœæã PC ãã¢ãã€ã«ããã€ã¹ã® MAC ã¢ãã¬ã¹ç»é²ãªã©ã®çްããäœæ¥ã«ã€ããŠããSlack bot ã«ã¯ãšãªãæããã ãã§è¡ããããã«ãªã£ãŠããŸãã 以åã¯å£é ãé»è©±ãSlack ãšè€æ°ã®çªå£ãããç
©éã ã£ãåãåãã察å¿ã«ã€ããŠã¯ãGoogle ãã©ãŒã ã«ããæçš¿ã«äžæ¬åãã å¿
èŠäºé
ãèšå
¥ããã°å°çšã® Slack ãã£ã³ãã«ãžèªåæçš¿ãããããã«æ¹åãããŠãããæ
ã·ã¹ã¡ã³ããæ©æ¥ã«ç¶æ³ã倿ã察å¿ã§ããããã«ãªã£ãŠããŸãã 匱㿠PC ã®ã»ããã¢ããã«ã€ããŠã¯å€ããèªååãããŠãããã®ã®ãäžéšäººã®æãä»ãå¿
èŠã®ãããã®ããããŸãã çŸç¶ã¯ãããã£ã³ã°äœæ¥ãå€éšãªãœãŒã¹ãžã®ã¢ãŠããœãŒã¹ãè¡ã£ãŠããŸããããã¡ããèªååãé²ããªããã°ãªããŸããã ããããããããš ä»åŸãäºæ¥æ¥æé·ã«äŒŽã瀟å¡å¢å€§ãèŠèŸŒãŸããŸããPC 1å°ã«ãããã»ããã¢ããã®å·¥æ°ãå°ãã§ãæžããçºã®èªååãå¹çåãç¶ç¶çã«é²ããŠãããŸãã 瀟å
ã§æããŠãŒã¶ã®å€ã Windows ã«ãããŠã¯ Windows Autopilot ã®å°å
¥ãèŠéã«å
¥ããŠããŸãã docs.microsoft.com 瀟å
ããŒã«/ã·ã¹ãã ã®çŽ¹ä» äžäŒã§ã¯å€ãã®ããŒã«/ã·ã¹ãã ãæŽ»çšãããŠããŸãããã®äžããããã€ãã玹ä»ããŸãã Slack slack.com äžäŒã§ã¯å
šç€Ÿã§ Slack ãå°å
¥ããŠããããšã³ãžãã¢ããã¶ã€ããŒã«éãããå¶æ¥ãäºåã®ã¡ã³ããšããã£ããäžã§ã³ãã¥ãã±ãŒã·ã§ã³ãåã£ãŠããŸãã åããŒã ã§æ¥åäžã®ãããšããè¡ããã£ã³ãã«ã®ä»ã倿 é£çµ¡ãPC ãæžç±ããªãã£ã¹ååã®è³Œå
¥äŸé Œãååºã®çºæ³šãç·åãæ
ã·ã¹ãžã®åãåãããè¡ãå°çšãã£ã³ãã«ãªã©ãçšæãããŠããŸãã ãŸããå€ãã® Slack bot ã皌åããŠãããæ
ã·ã¹ã«ãããŠã¯ã¡ãŒãªã³ã°ãªã¹ãã®äœæããå
¥é瀟ã«äŒŽãã¢ã«ãŠã³ãã®äœæ/忢ãªã©ã®æ¥å㯠bot ã«ããèªååãããŠããŸãã é害éç¥ãå§ããšããå€ãã®æ
å ±ã Slack ã«é£æºãããä»çµã¿ãšãªã£ãŠããã瀟å
ã€ã³ãã©ãšããŠæ¥ã
å©çšãããŠããŸãã 㜠ããœã ã¯äžäŒã§æãå€ã䜿ãããŠãã Slack bot ã®ã²ãšã€ã§ãã ç€Ÿå¡æ
å ±æ€çŽ¢ãäŒè°å®€äºçŽãããªãã£ã¹ã®åº§åžè¡šãå
ç·çªå·ãWi-Fi ã®ãã¹ã¯ãŒããªã©ãä»ç¥ãããæ
å ±ãããã«æ€çŽ¢ã§ããèŸæžããŒã«ãšãªã£ãŠããŸãã 詳ããã¯ä»¥äžã®ãšã³ããªã§è§£èª¬ãããŠããŸãã user-first.ikyu.co.jp G Suite gsuite.google.com äžäŒã§ã¯å
šç€Ÿã§ G Suite ãå°å
¥ããŠããçºã Gmail ã Google ã«ã¬ã³ããŒãGoogle ãã©ã€ããæ¥åã§å©çšãããŠããŸãã ãŸããå€ãã®ã¹ãã¬ããã·ãŒãã Google Apps Script ã«ããã¹ã¯ãªãããçµãŸããŠããã Slack ãžã®é£æºãæ¥åèªååã«æŽ»çšãããŠããŸãã æ
ã·ã¹ã«ãããŠã¯ãã¹ãã¬ããã·ãŒãã«å
¥åãããäººäºæ
å ±ãããªã¬ãŒãšããã¢ã«ãŠã³ãã¡ã³ããã³ã¹ã®èªååãã æŽæ°ææ¥ã®è¿«ã£ãã©ã€ã»ã³ã¹ãä¿å®å¥çŽã«ã€ããŠãªãã€ã³ããè¡ãã¹ã¯ãªãããªã©ãå®è£
ãæ¥åã®å¹çåã«åãçµãã§ããŸãã Azure Active Directory azure.microsoft.com Slack ã G Suite ãå«ããäžäŒã§å©çšããŠããå€ãã®ç€Ÿå
ããŒã«/ã·ã¹ãã 㯠Azure Active Directory ã«ããã·ã³ã°ã«ãµã€ã³ãªã³ïŒSSOïŒ æ§æãšãªã£ãŠããŸãã 瀟å
ããŒã«/ã·ã¹ãã ããšã«ã¢ã«ãŠã³ãã® ID/ãã¹ã¯ãŒãã®ç®¡çãç°ãªããšã瀟å¡ããã¹ã¯ãŒããå¿ããŠåãåãããçºçããã瀟å¡ã®é¢è·ã«äŒŽãã¢ã«ãŠã³ãã¡ã³ããã³ã¹ã®å·¥æ°ã倧ããããã±ã¢ã¬ãçºçãããšãã£ãåé¡ãæ³å®ãããŸãã äžäŒã§ã¯ PC ã«ãµã€ã³ã€ã³ãã ID/ãã¹ã¯ãŒãã§ã»ãŒå
šãŠã®ç€Ÿå
ããŒã«/ã·ã¹ãã ãå©çšããããšãã§ããŸãã ãŸããé¢è·è
ã«å¯ŸããŠã¯ Azure Active Directory ã®ã¢ã«ãŠã³ãã忢ããããšã§ã瀟å
ããŒã«/ã·ã¹ãã ãžã®ã¢ã¯ã»ã¹ãé²ãããšãã§ããŸãã Microsoft Authenticator Microsoft Authenticator – オンライン アカウントの安全なアクセスと管理 äžäŒã§ã¯ Azure Active Directory ã«ãã SSO ã«å ããMicrosoft Authenticator ã«ããäºæ®µéèªèšŒïŒ2FAïŒãè¡ã£ãŠããŸãã SSO ã¯è€æ°ã® ID/ãã¹ã¯ãŒãã管çããªããŠãè¯ãããšãããŠãŒã¶ã®å©äŸ¿æ§ãé«ãäžæ¹ã§ã1ã€ã® ID/ãã¹ã¯ãŒã ãçãŸãããšãã®ãªã¹ã¯ãé«ããšãè§£éã§ããŸãã ããã§ãäžäŒã§ã¯åèªã®ã¹ããŒããã©ã³ã« 2FA çšã®ã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ããŒã«ããŠé ããŠãããã¢ããªã±ãŒã·ã§ã³åŽããã®æ¿èªãåŸãªãéãã ID/ãã¹ã¯ãŒããç¥ã£ãŠããŠã瀟å
ããŒã«/瀟å
ã·ã¹ãã ã«ã¯ãã°ã€ã³ã§ããªãä»çµã¿ããšã£ãŠããŸãã Vimeo vimeo.com äžäŒã§ã¯æ¯æã®æåã«å
šç€Ÿå¡ãæ±äº¬æ¬ç€Ÿã©ãŠã³ãžã«éããææ¬¡ã®å®çžŸå ±åã瀟å¡å士ã®äº€æµãè¡ãå
±æäŒã»ããŒãã£ãéå¬ããŠããŸãã åæ¯ç€Ÿã®ã¡ã³ããæåã«ã¯æ±äº¬ã«éãŸã£ãŠããŸããããæ¥åéœåãä»ããããã«åå ãã§ããªãã¡ã³ããããŸããã ãŸããæ±äº¬æ¬ç€Ÿã§å®æçã«éå¬ããã瀟å
å匷äŒãã瀟å¡åãã®èª¬æäŒã«ãåæ¯ç€Ÿã®ã¡ã³ãã«åããŠããªã¢ã«ã¿ã€ã ã«å
±æããããšãã匷ãããŒãºããããŸããã ããã§ãæ
ã·ã¹ã§ã¯åç»é
ä¿¡ãã©ãããã©ãŒã ã§ãã Vimeo ãå°å
¥ããæ±äº¬æ¬ç€Ÿã®æ§åãçäžç¶ããããšã«ããŸããã åæ§ã®ãµãŒãã¹ãšããŠã¯ YouTube Live ãæããããŸããããã¹ã¯ãŒãä¿è·æ©èœãæèŒããããã»ãã¥ã¢ã§ãã Vimeo ãéžå®ããŸããã é
ä¿¡æ©æãšããŠã¯ Cerevo 瀟㮠LiveShell.PRO ã賌å
¥ããããšã§ãHD ç»è³ªã®é«å質ãªã¹ããªãŒãã³ã°é
ä¿¡ãå®çŸããŸããã liveshell.cerevo.com Chromebox for meetings gsuite.google.com äžäŒã§ã¯äºæ¥æ¥æé·ã«äŒŽããæ±äº¬ã倧éªãåå€å±ã«ç¶ããæ²çžãçŠå²¡ã京éœã暪æµã𿬡ã
ãšãã©ã³ããªãã£ã¹ãéèšããŠãããŸããã äºæ¥æãå¢ããããšã«ãããæ±äº¬æ¬ç€Ÿãšåæ¯ç€Ÿéã§ãªã¢ã«ã¿ã€ã ã« Web äŒè°ãè¡ããããšããããŒãºãé«ãŸããŸããã Web äŒè°ã·ã¹ãã ã¯å€çš®å€æ§ã«ãããŸãããäžäŒã§ã¯ Chromebox for meetings ãå°å
¥ããŸããã ãã®è£œå㯠Chrome OS ãæèŒãã Chromebox ãšãã PC ã Web äŒè°ïŒHangoutïŒ å°çšã«ã«ã¹ã¿ãã€ãºãããã®ã§ãã éžå®çç±ãšããŠäžäŒã§ã¯ G Suite ãå°å
¥ããŠããããšããå
šç€Ÿå¡ã Hangout ãå©çšã§ããç¶æ
ã«ããããšã Chromebox for meetings 㯠Hangout ã«æ©èœãçµã£ãã·ã³ãã«ãªãŠãŒã¶ã€ã³ã¿ãã§ãŒã¹ã§ããããšããå°å
¥ã決å®ããŸããã IT éšéã®æ
åœè
ã瀟å
ããŒã«/ã·ã¹ãã ãéžå®ããéã¯ã極åå®ã補åãéžãã§ããŸã£ãããèªåãã¡ã® IT ãªãã©ã·ãŒåºæºã§éžãã§ããŸã£ãããšãIT éšéç®ç·ã«ãªã£ãŠããŸãããšããããŸãã ãŠãŒã¶ãã¡ãŒã¹ãã®ã«ã«ãã£ãŒãšããäžäŒã®æ
ã·ã¹ã«ãããŠã¯ãŠãŒã¶ã§ãã瀟å¡ã«ãšã£ãŠäœ¿ãããããããšããç¹ãæéèŠããŠæ©åšéžå®ãè¡ããŸããã å°ãçŸåšã¯ Chromebox for meetings ã¯çç£ãçµäºããŠãããåŸç¶çš®ã® Chrome devices for meetings ã販売ããŠããŸãã æåŸã« æ
ã·ã¹ã®ãšã³ãžãã¢ãè¡ã£ãŠããæ¥åã¯ãäºæ¥éšã§ãããã¯ãéçºãè¡ã£ãŠãããšã³ãžãã¢ãšæ¯ã¹ããšå°å³ãããããŸããã ãããããŠãŒã¶ïŒ= 瀟å¡ïŒãšæãè¿ãè·é¢ã§çŽæ¥ããŒãºããã£ãŒãããã¯ãèãããšã®ã§ãããéåžžã«ããç²æã®ããç«å Žã§ãããšèããŠããŸãã äžäŒã«ãããŠã¯ãå€ãã®æ¥åã瀟å
ããŒã«/ã·ã¹ãã ã bot ã«ããèªååãå¹çåãããŠããŸãããæªã äººã®æãä»ããŠããæ¥åãããŒãå€ãååšããŸãã ãããã瀟å
ã®æ¥å課é¡ã®è§£æ±ºãæ¹åãç¶ç¶çã«è¡ãã瀟å¡ã ãæ¬æ¥ããã¹ãæ¥åã«æéã䜿ããã ç°å¢ãäœãäžããã®ãæ
ã·ã¹ã®ããã·ã§ã³ã§ãã ãããããäžäŒ æ
ã·ã¹ã¯ç€Ÿå
ã®æ¥åæ¹åããµããŒããç¶ããŠãããŸãïŒ ææ¥ã¯ä»å¹ŽæåŸã®ã¢ããã³ãã«ã¬ã³ã㌠id:ninjinkun ã«ãã ã å±¥æŽããŒãã«ã«ã€ã㊠ã ã§ãïŒ
ãã®èšäºã¯ äžäŒ.comã¢ããã³ãã«ã¬ã³ããŒ2018 ã®23æ¥ç®ã§ãã äžäŒ.com ã®éçºåºç€ããã£ãŠããŸã akasakas ã§ãã é·ãã¿ã€ãã«ã§ãããŸããã æ¬æ¥ã®ã話 æ¬çªãªã¯ãšã¹ããéçºç°å¢ã«æããŠããšã©ãŒãæ€ç¥ããä¿®æ£ãããšãããµã€ã¯ã«ã§éçºããããšå質ãäžãã£ãŠãããšããã®ãæè¿å®æããŸãã ãšãã話ã§ãã å³ã«ãããšãããªæãã®ã€ã¡ãŒãžã§ã ãã£ãŠããããš æ¬çªãªã¯ãšã¹ããã°ããæœåº éçºç°å¢ã«å¯ŸããŠããªã¯ãšã¹ããæãã ãã°ã¿ã€ãã ãªãã ã 现ãã ç¹°ãè¿ã ãããç¹°ãè¿ãã°ã ã¡ãããšè©ŠéšèããªããŠããåæã« å質äžãã£ãŠããããã«ãªãã®ããªãšæããŸããã å®å¿ããŠãªãªãŒã¹ãã§ããã®ã¯ãšã³ãžãã¢ã®å¿ççã«éåžžã«ããããšãªã®ããªãšæããŸãã å
·äœçã«ã©ããã£ãŠããã®ãïŒ äžäŒã§ã¯Logentriesã§ã¢ã¯ã»ã¹ãã°ã管çããŠããŸãã Logentriesã®APIãäœ¿ã æ¬çªãªã¯ãšã¹ããååŸ éçºç°å¢ã«ãªã¯ãšã¹ããæãã HTTPã¹ããŒã¿ã¹ã³ãŒããç¢ºèª ãšãããšãããŸã§ãããããšæããŸãã åèå®è£
ã®åã«è«žæ³šæ Logentriesã®APIã¯åŒã³åºãå¶éãããã®ã§ãçšæ³çšéãå®ã£ãŠãæ£ããã䜿ããã ããã 詳ããã¯ãã¡ãã«ãªããŸãã docs.logentries.com åèå®è£
åèå®è£
ããã¡ãã«ãªããŸãã import logging import datetime import requests import time import re import json settings = { 'dev_host' : 'dev.hostname.com' , 'sampling_seconds' : 180 , 'logentries' : { 'endpoint' : 'https://rest.logentries.com/' , 'apikey' : 'logentries api key' , 'logs_query' : 'query/logs' , 'query_api' : 'query' , 'query_statement' : 'where(' \ + ' path = /query_statement(regular_expression)/ ' \ + ')' , 'logs' : [ 'logenrties log set key id' ] } } logging.basicConfig( format = '[%(asctime)s] %(message)s' ) logger = logging.getLogger( 'real-request-to-development' ) logger.setLevel(logging.DEBUG) def calc_query_time (): now = datetime.datetime.now() from_time = datetime.datetime.now() - datetime.timedelta(seconds=(settings[ 'sampling_seconds' ])) return int (time.mktime(from_time.timetuple())) * 1000 , int (time.mktime(now.timetuple())) * 1000 def le_query (from_unixtime, to_unixtime): headers = { 'x-api-key' : settings[ 'logentries' ][ 'apikey' ]} body = { "logs" : settings[ 'logentries' ][ 'logs' ], "leql" : { "during" : { "from" : from_unixtime, "to" : to_unixtime}, "statement" : settings[ 'logentries' ][ 'query_statement' ]} } res = requests.post(f '{settings["logentries"]["endpoint"]}{settings["logentries"]["logs_query"]}' , headers=headers, json=body) return res.json()[ "id" ] def le_longtime_query ( id ): headers = { 'x-api-key' : settings[ 'logentries' ][ 'apikey' ]} res = requests.get(f '{settings["logentries"]["endpoint"]}{settings["logentries"]["query_api"]}/{id}' , headers=headers) return res.json() def get_request_url (json_data): dev_url_list = [] for log_row in json_data[ "events" ]: log_data = re.search( r'{.*}' , log_row[ "message" ]) log_json = json.loads(log_data.group( 0 )) path = log_json[ "path" ] query = log_json[ "query" ] useragent = log_json[ "useragent" ] dev_url = f 'https://{settings["dev_host"]}{path}{query}' dev_url_dict = { "dev_url" : dev_url, "ua" : useragent} dev_url_list.append(dev_url_dict) return dev_url_list def send_request (dev_url_list): for dev_url_dict in dev_url_list: headers = { 'User-Agent' : dev_url_dict[ "ua" ] } dev_response = requests.get(dev_url_dict[ "dev_url" ], headers=headers) if dev_response.status_code >= 500 : logger.error(f 'development url is {dev_url_dict["dev_url"]}' ) logger.error(f 'development response status is {str(dev_response.status_code)}' ) ######################################### def start (): from_unixtime, to_unixtime = calc_query_time() le_query_id = le_query(from_unixtime, to_unixtime) json_data = le_longtime_query(le_query_id) dev_url_list = get_request_url(json_data) send_request(dev_url_list) if __name__ == "__main__" : start() 1ã€ãã€è§£èª¬ããŠãããããšæããŸã æµããšããŠã¯ Logentries API ã§æ€çŽ¢çšã®ã¯ãšãªIDãååŸ&å®éã®ãªã¯ãšã¹ããååŸ å®éã®ãªã¯ãšã¹ãã®ãã¹ããéçºç°å¢çšã®ãã¹ãã«æžãæãã ãªã¯ãšã¹ããæãã&500ãšã©ãŒããã°åºå 2.3ã¯é£ããããšã¯ããŠããªãã®ã§ã説æã¯çç¥ããŸãã Logentries API ã§æ€çŽ¢çšã®ã¯ãšãªIDãååŸ&å®éã®ãªã¯ãšã¹ããååŸ Logentries API ã§æ€çŽ¢çšã®ã¯ãšãªIDãååŸ äžèšã§ãæ€çŽ¢çšã®ã¯ãšãªIDãååŸããŠããŸãã ãã®ã¯ãšãªIDãããŒã¹ã«ããŠãå®éã®ãªã¯ãšã¹ããååŸããŸãã å¿
èŠãªãã©ã¡ãŒã¿ã¯ logs(ã©ãã®ãã°ãïŒããã§ã¯ã¢ã¯ã»ã¹ãã°) statement(ã©ããªæ¡ä»¶ãïŒæ£èŠè¡šçŸã§pathãèšè¿°ããã®ãäžè¬çïŒ) from,to(unixtimeãªã®ã§ãäºåã«from,toãunixtimeã«ããå¿
èŠããã) ã§ãã 詳现ã¯ãã¡ããã芧ãã ããã docs.logentries.com def le_query (from_unixtime, to_unixtime): headers = { 'x-api-key' : settings[ 'logentries' ][ 'apikey' ]} body = { "logs" : settings[ 'logentries' ][ 'logs' ], "leql" : { "during" : { "from" : from_unixtime, "to" : to_unixtime}, "statement" : settings[ 'logentries' ][ 'query_statement' ]} } res = requests.post(f '{settings["logentries"]["endpoint"]}{settings["logentries"]["logs_query"]}' , headers=headers, json=body) return res.json()[ "id" ] å®éã®ãªã¯ãšã¹ããååŸ å
ã»ã©ååŸããã¯ãšãªIDãããŒã¹ãããå®éã®ãªã¯ãšã¹ããååŸããŠããŸãã 詳现ã¯ãã¡ããã芧ãã ããã docs.logentries.com def le_longtime_query ( id ): headers = { 'x-api-key' : settings[ 'logentries' ][ 'apikey' ]} res = requests.get(f '{settings["logentries"]["endpoint"]}{settings["logentries"]["query_api"]}/{id}' , headers=headers) return res.json() å®éã®ãªã¯ãšã¹ããéçºç°å¢ã«æããããšã§ãšã©ãŒãæ€ç¥ãšãããšãããŸã§ã§ããŸãããããããã詊éšãšä¿®æ£ãç¹°ãè¿ãã°ãå質ã¯äžãããå®å¿ããŠãªãªãŒã¹ã§ããããšã«ãªããšæããŸãã ããäžæ©é²ã㊠éçºç°å¢ãæ¬çªçžåœã§ãããšäžèšã®è©Šéšã¯ããã«å¹æãçºæ®ãããããªãšæããŸãã äžäŒã§ã¯æ¬çªDBããå人æ
å ±ã¯ãã¹ã¯ãããã®ãéçºç°å¢çšã®DBãšããŠäœ¿ã£ãŠããŸãã æ¬çªãªã¯ãšã¹ããæ¬çªçžåœDBã«ãªã¯ãšã¹ããæããããšã§ããã粟床ã®é«ã詊éšãã§ããã®ããªãšæããŸãã ããã«ããäžæ©é²ã㊠ãããæ¬çªãªãªãŒã¹åã®Stagingç°å¢ã§ãã®ä»çµã¿ã宿çã«å®è¡ãããšã©ãŒã«ãªã£ãããSlackã§éç¥ãããªãªãŒã¹äºæ
ãææ¢ã§ããããã«ãªãã°ãããã«ãããªãšæããŸãã ãããããŸã äžäŒã§ã¯ãããŸã§ã§ããŠããããè¿ããã¡ã«ãããããªãšæã£ãŠãããšããã§ãã ã€ã¡ãŒãžãšããŠã¯ Nginxã®Mirror moduleãGoReplayãšãã£ãCanaryReleaseã«è¿ãããªãšæããŸãã ãŸãšã 以äžãæ¬çªãªã¯ãšã¹ããéçºç°å¢ã«æããŠããšã©ãŒãæ€ç¥ããä¿®æ£ãããšãããµã€ã¯ã«ã§éçºããããšå質ãäžãã£ãŠãããšããã®ãæè¿å®æããŸãã ãšãã話ã§ããã ææ¥ã¯ id:rotom ããã«ãããäžäŒã«ããããæ
ã·ã¹ãã®åãçµã¿ãã§ãã æ®æ®µããŸãèªãããããšã¯ãªãäžäŒã®æ
ã·ã¹äºæ
ã«ã€ããŠè©³ãã話ãèãããšæããŸãã®ã§ããæ¥œãã¿ã«ã åè CanaryRelease GoReplay Nginx Mirror module Running beta in production
ãã®èšäºã¯äžäŒ.comã¢ããã³ãã«ã¬ã³ããŒ2018ã®22æ¥ç®ã§ãã qiita.com ããŒã¿ããŒã¹ã«å¯ŸããDDLã®é©çšãã¿ãªããã¯ã©ã®ããã«éçšããŠããŸããã äžäŒã§ã¯é·ããæ
åœè
ãæåé©çšãããŠããŸãããããéçºè
å
šå¡ã®äŸé ŒããŸãšããŠã宿çã«DDLé©çšãè¡ãã®ã¯ããªãã®äœæ¥è² è·ã§ãã ããã§ãã¢ããªã±ãŒã·ã§ã³ã®ãœãŒã¹ã³ãŒããšåãããã«GitHubãšCI/CDã®ãã€ãã©ã€ã³ãæ§ç¯ããŠãé©çšãããéçºè
ãèªåã§é©çšã§ããä»çµã¿ãæ§ç¯ããŸããã ãã®èšäºã§ã¯ããã®æŠç¥ã玹ä»ããããšæããŸãã â»åœç€Ÿã¯Microsoft SQL Serverã䜿ã£ãŠããã®ã§ããã®åæã®èšäºã«ãªããŸãã ãããã€ãã㌠CIã«ã¯ Appveyor ããCDã«ã¯AWS CodeDeployãå©çš CodeDeployã¯åŸè¿°ã®éããå€éšã¢ã¯ã»ã¹çšã®ãããã·ãµãŒããå©çš GitHubã«DDLã管çãããªããžããªãäœæ éçºè
ã¯ãã®ãªããžããªã§æ°èŠã«é©çšãããDDLã®Pull Requestãäœæ PRãmasterãã©ã³ãã«é©çšãããšAppveyorçµç±ã§CodeDeployãèµ·åãããã CodeDeploy AgentãåããŠããddl-controllerãã·ã³ã§DDLãå®è¡ããSQL Server ã«é©çš é©çšå±¥æŽãSQL Serverã®ããŒãã«ã§ç®¡çããŠåãDDLã2éé©çšãããªãããã«å¶åŸ¡ é©çšçµæ(å®è¡ãã°)ã¯Amazon S3ã«ã¢ããããŒã Lambdaã§ãã°ã®äžèº«ããã§ãã¯ããŠãé©çšçµæãSlackã«éç¥ å·¥å€«ç¹ã泚æç¹ tsqllint ã§DDLã®æ§æãã§ã㯠ããŒã¿ããŒã¹ã®å®çŸ©å€æŽãªã®ã§ãæ³šææ·±ã宿œããå¿
èŠããããŸãããŸããå®éã«å®çŸ©ãé©çšããŠã¿ãããšã©ãŒã«ãªã£ãããšãªããšææ»ããçºçããŠé¢åã§ãã ããã§ãlinterãå°å
¥ããããšèããŸããã調ã¹ãŠã¿ããšSQL Serverã® T-SQL (Transact-SQL) ã®æ§æããã§ãã¯ã§ãã tsqllint ãšããããŒã«ããããŸããã åäœç¢ºèªããŠã¿ããšããããã¡ããšåäœãããã lintã®ã«ãŒã«ã®ã«ã¹ã¿ãã€ãºãã§ãã ã®ã§ãããæ¡çšããŸããã ãããŠããããå©çšããç°¡åãªNode.jsã®ã¹ã¯ãªãããæžããAppveyoräžã§åãããŠãæ§æãã§ãã¯ãå®è¡ããããã«ããŸããããã§ãã¯ãéããªããã°ãPull RequestãããŒãžã§ããªãããã«ããŸãã â»ã¡ãªã¿ã«ãtsqllint㯠VS Codeã®æ¡åŒµãããããã§ã ãSQL Serverã®ç®¡çãªã©ã§T-SQLã«è§Šããæ©äŒãå€ãæ¹ã«ã¯äŸ¿å©ãããããŸããã linterã§ãã§ãã¯ã§ããªãç¹ã¯ã¬ãã¥ãŒã§ãã§ã㯠ãã¡ã€ã«ã°ã«ãŒãã®æå®ãæ£ãããããªã©linterã®ãã§ãã¯ã ãã§ã¯æ€åºã§ããªãéèŠãªç¹ããããŸãã ãã®ãããªç¹ã«ã€ããŠã¯ Pull Requestã®ãã³ãã¬ãŒã ã«ãã§ãã¯é
ç®ãæžãåºããPull Requestã®äœæè
ãšã¬ãã¥ãŒã¯ãŒã®åæ¹ããã§ãã¯ããããšããéçšã«ãŒã«ã«ããŸããããã¡ãããã¬ãã¥ãŒã¯ãŒã®Approveããªããã°ãPull Requestã¯ããŒãžã§ããŸããã æ©æ¢°çãªãã§ãã¯ã§ã¯ãªãã®ã§ãå€å°ã®äžå®ã¯ãããŸãããä»ã®ãšããããŸããã£ãŠããŸãã ã€ã³ã¿ãŒãããã«åºããªãEC2ã€ã³ã¹ã¿ã³ã¹ã§CodeDeploy Agentãåããã«ã¯ãããã·ãå¿
èŠ ããã¯ã泚æç¹ãªã®ã§ãããããŒã¿ããŒã¹ã眮ãããŠãããããã¯ãŒã¯ã¯ãã€ã³ã¿ãŒãããã«ã¯æ¥ç¶ã§ããªãããã«ãªã£ãŠããã®ãäžè¬çã§ãã äžæ¹ã§CodeDeploy Agentãæ£åžžã«åäœããããã«ã¯ãå€åãHTTPSã®éä¿¡ãã§ããããšãå¿
é ã§ãã CodeDeploy Agentãå€éšã®APIã宿çã«ã³ãŒã«ããŠãããã€ãå®è¡ããå¿
èŠããããã©ãã確èªããŠããããã§ãã ãã®å ŽåãCodeDeploy Agentã®æ§æãã¡ã€ã«ã«å€åãéä¿¡ããããã·ããããã®ãããã·ãµãŒãã®URLãèšå®ããå¿
èŠããããŸãã åœç€Ÿã§ã¯ãå€åãã®éä¿¡ãã§ãããããã¯ãŒã¯ã«Apacheã§ãããã·ãµãŒããç«ãŠããã®URLãCodeDeploy Agentã®æ§æãã¡ã€ã«ã«èšå®ããŸããã Apacheã®èšå®ã¯ä»¥äžã®éãã§ãã Listen *:8088 <VirtualHost *:8088 > ProxyRequests on AddDefaultCharset off AllowCONNECT 443 <Proxy codedeploy-commands.ap-northeast-1.amazonaws.com > <LimitExcept CONNECT > Order deny , allow Deny from all # â CodeDeploy Agent ãåããŠãããã·ã³ã®IP Allow from xx.xx.xx.xx </LimitExcept> </Proxy> </VirtualHost> CodeDeployåŽã¯ãconf.ymlãæ¬¡ã®ããã«ä¿®æ£ããŸãã Windowsã®å Žåã C:\ProgramData\Amazon\CodeDeploy\conf.yml ã«ãããŸãã --- :log_dir : 'Amazon/CodeDeploy/log' :root_dir : 'Amazon/CodeDeploy' :verbose : true :wait_between_runs : 1 :wait_after_error : 1 :bundle_name : 'artifact_bundle.tar' :proxy_uri : http://xx.xx.xx.xx:8088 # ããã«ãããã·ãµãŒãã®IPãèšè¿° ããã§ãCodeDeploy Agentãåèµ·åããã°æ£åžžã«åãããã«ãªããŸãã â» ç°å¢ã«ãã£ãŠã¯ã»ãã¥ãªãã£ã°ã«ãŒããªã©ãããã¯ãŒã¯ã¬ã€ã€ã®èª¿æŽãå¿
èŠã§ãã çµããã« é·å¹Žãæåã§ãã£ãŠãããã®ãèªååããŠãæãããŠããŸãéçšãåãããå¿é
ã¯ãããŸãããããã£ãããšéçšã«ä¹ããŸããã ããŒã¿ããŒã¹ãã¯ã©ãŠãã«ç§»è¡ãããšããåææ¡ä»¶ãšã¢ããªã±ãŒã·ã§ã³ã®CI/CDã®æ§ç¯çµéšã®å¿çšãå®çŸã®ããŒãã€ã³ãã ã£ããšæããŸãã â»ããŒã¿ããŒã¹ã®ã¯ã©ãŠãç§»è¡ã«ã€ããŠã¯ãåœããã°ã«è©³çްãªèšäºããããŸãã®ã§ãã芧ãã ããã user-first.ikyu.co.jp user-first.ikyu.co.jp ãã®èšäºã®çè
ã«ã€ã㊠ã·ã¹ãã æ¬éšCTO宀æå±ã® åŸ³æŠ ã§ãã ãµãŒãã¹ã®æè¡åºç€ã®éçºéçšã宿æ³ãµãŒãã¹ã®éçºæ¯æŽãè¡ãªã£ãŠããŸãã
ãã®èšäºã¯äžäŒ.com ã¢ããã³ãã«ã¬ã³ããŒã®20æ¥ç®ã®èšäºã§ãã qiita.com ã¯ãããŸããŠã宿æ³ãµãŒãã¹ã®UIãã¶ã€ã³ãæ
åœããŠããŸãæ²³æã§ãã äžäŒã®ãã¶ã€ããŒã¯éšçœ²ããšã«åšç±ããŒã ãç°ãªããŸããç§ã¯é·ãéãå¶æ¥äŒç»éšãã¶ã€ããŒãšããŠåããŠããŸããããä»å¹Ž4æãããããã¯ãéçºéšUIãã¶ã€ããŒãšããŠåããŠããŸããïŒæ¬ããã°ã§ã¯ãåè
ãWebãã¶ã€ããŒãšããŸãïŒ Webãã¶ã€ããŒãšUIãã¶ã€ããŒããã£ãŠã¿ãŠãå€ãã®ããšããéã£ããã®ã§ãã©ããªéããªã®ããã話ãããŠããã ããŸãã ç®æ¬¡ ïŒïŒ ä»äºå
容ã®éã ïŒïŒ å¿
èŠãªã¹ãã«ã®éã ïŒïŒ ä»äºã®é²ãæ¹ã®éã ïŒïŒ ãŸãšã ä»äºå
容ã®éã ããžã¥ã¢ã«è¡šçŸã«ç¹å äžäŒã®Webãã¶ã€ããŒã®äž»ãªæ¥åå
容ã¯ããããããŒãžãªã©ã®æŽæ°äœæ¥ãæœèšç޹ä»ããŒãžãç¹éã»äŒç»è²©ä¿ããŒãžãã¡ãŒã«ãã¬ãžã³çã®äœæã§ããããŒãžå
šäœã®ããžã¥ã¢ã«ã管çããŠããã®ã§ãäžã€äžã€ã®ç»åã®éžå®ãªã©ãµã€ãå
šäœã®é°å²æ°äœãã«æ¬ ãããªã圹å²ã§ãã ç§ã¯ãæœèšã®é
åããŠãŒã¶ãŒã«å±ããããšããŽãŒã«ã«ããŠãæœèšã®äžçæãæããããããŒãžäœããæèããŠè¡ã£ãŠããŸããã æäœæ§ã®åäžã«ç¹å äžæ¹ãUIãã¶ã€ããŒã®äž»ãªæ¥åå
容ã¯ããŠãŒã¶ãŒãã䜿ããããããšæããã¶ã€ã³ãå®çŸããããšã«ç¹åããŠããŸãã宿æ³ãã©ã³ããã£ããæŽçãããæ§å³ãèŠãããã«ã©ãŒãªã³ã°ãæé©ãªæåã®å€§ããã䜿ããããæ€çŽ¢æ©èœãªã©ãæèããŠããŠãŒã¶ãŒã«ãšã£ãŠäœ¿ãåæã®ãããµã€ããç®æããŠããŸãã åºæ¬çã«ã¯äºçŽã®ã³ã³ããŒãžã§ã³çåäžãç®çãšããŠæ¹åãç¹°ãè¿ããŸãããäºçŽã«ã¯é¢ä¿ãªãéšåã§ã䜿ãããããèŠããããè¯ãããçºã®æ¹åããããŸããå
·äœäŸãšããŸããŠã¯ãå®¿æ³æé衚瀺ã峿ãã€ã³ãå©çšã§ã®å²åŒåŸã®æé衚瀺ã«åãæ¿ãããããæ©èœã远å ãããããã©ãã®ã£ã©ãªãŒã®ãµã ãã€ã«è¡šç€ºã®è¿œå ãªã©ãè¡ããŸããã å¿
èŠãªã¹ãã«ã®éã æå å Webãã¶ã€ããŒã®å¿
èŠãªã¹ãã«ã¯ãæå åãã§ããæœèšã®é
åããŠãŒã¶ãŒã«å±ããããŒãžäœããæãšããŠã€ã³ãã¯ããæ®ããããŒãžäœããªã©ãè¡ããŸããããªã·ã£ã¬ã ã£ããããã£ããããšãã£ãèŠãç®ã®å°è±¡ãè£
食çèæ¡ã倧åã§ãã èšèšå äžæ¹ãUIãã¶ã€ããŒã®å¿
èŠãªã¹ãã«ã¯ãèšèšåãã§ãããŠãŒã¶ãŒã®ç®ç·ã«ç«ã£ãŠãŠãŒã¶ãŒãæ±ããåé¡ã®æ¬è³ªãèãããããã解決ããããã®èšèšããã衚çŸã圢ãäœã£ãŠããããšãéèŠã§ãã Webãã¶ã€ããŒã¯ãå€ãã®å ŽåãæœèšåŽãå¶æ¥æ
åœããæç€ºæžãããã®ã§ãäœãèŠããããã®æå³ããã¿åããã¶ã€ã³ã§è¡šçŸããæµãã§ãããUIãã¶ã€ããŒã¯ãä»äœãåé¡ã§ããããã£ãã䜿ãããããªãã®ã§ã¯ãšä»®èª¬ãç«ãŠããªã©ããã¶ã€ã³ããããŸã§ã®éçšããšãŠãéèŠã«ãªããŸãã ä»äºã®é²ãæ¹ã®éã ããžã¥ã¢ã«çãªã¯ãªãªãã£ã®è¿œæ±ãèªåã ãã§è¡ãã Webãã¶ã€ããŒã¯å¶æ¥æ
åœãæœèšãšã®èª¿æŽã¯ãããŸãããäœæ¥ã®é²è¡èªäœã¯äžäººã§è¡ããŸããçŽæå
ã§ããã°ããžã¥ã¢ã«çãªã¯ãªãªãã£ãçªãè©°ããããšã«æéãå²ãããšãã§ããŸãã å
±åäœæ¥ãªãã§ã¯ã®ã«ãŒã«ããã äžæ¹ãUIãã¶ã€ããŒã¯ããŒã±ãã£ã³ã°ããšã³ãžãã¢ãšã®å
±åäœæ¥ãªã®ã§ãäœæ¥ã®é²è¡ã¯èªåã ãã®å€æã§ã¯é²ããããŸããããŸãããšã³ãžãã¢ãšèªèåãããªã©ãæç« ã«æ®ãã®ãéèŠã§ãããããããšããªãããããªã©ãæ¡ä»¶ããšã«èšèªåããŸãã å人ãã¬ãŒããããŒã ãã¬ãŒãšãªã£ãããšã§ãèªåã®ã¿ã€ãã³ã°ã§ãªãªãŒã¹ã§ããªãããšã«ã¹ãã¬ã¹ãæããããèšèªåããäœæ¥ãç
©ãããæãããããããšããããŸããã ãããããªãªãŒã¹åã«å¿
ãã¬ãã¥ãŒãå
¥ãããšã§ãã¹ãé²ãããããªãããããšããã®ãæç« ã§æ®ãããšã§ãèªåèªèº«ãæèã®æŽçãã§ããããéå»ã®ãªãªãŒã¹ãæ¯ãè¿ãéã«ã圹ç«ã£ãŠãŸãã ãŸãšã äžäŒã«ãããŠã®åãã¶ã€ããŒã®éãã«ã€ããŠãç°¡åã«ãŸãšããŠã¿ãŸããããããŸã§ãç§ãå人çã«æããããšãªã®ã§ãäžè¬çãªãWebãã¶ã€ããŒãšUIãã¶ã€ããŒã®éãããšã¯ç°ãªããããããŸããã ç®çå¥ããŒã ã§åã
äœæ¥ããŠããäžäŒã®ãã¶ã€ããŒã§ããããäžäŒããã綺éºãªãµã€ããããé«çŽæãæãããã¶ã€ã³ããäœãããããšããã®ã¯å
±éããŠç®æããŠããããšã§ãããã®ããã«ç§ãã¡ãã¶ã€ããŒã¯ããã¶ã€ã³ã®åïŒæå åãèšèšåïŒãé§äœ¿ããŠããçŸããæ©èœçãªãµã€ãã§å®¿æ³å
ãéžãã§ããããšããããŠãŒã¶ãŒã®å¿å°ããäœéšãå¶ããã¹ããæ¹åãç¹°ãè¿ããŸãã äžäŒã§ã¯ããšãã«è¯ããµãŒãã¹ãã€ãã£ãŠãã仲éïŒãã¶ã€ããŒïŒãšã³ãžãã¢ïŒããŒã±ãã£ã³ã°ïŒã ç©æ¥µåéäž ã§ããå¿ååã«ã«ãžã¥ã¢ã«ã«é¢è«ãããããšãå¯èœã§ãã®ã§ããæ°è»œã«ãé£çµ¡ãã ããã ææ¥ã¯ @hayatoise ããã«ãããèªæžå宿ã®ã話ãã§ãããæ¥œãã¿ã«ïŒ
ãã®èšäºã¯äžäŒ.comã¢ããã³ãã«ã¬ã³ããŒ2018ã®19æ¥ç®ã§ãã qiita.com ããçšåºŠã®èŠæš¡ã®ãŠã§ãã¢ããªã±ãŒã·ã§ã³ã§ããã°ãå¿çæ§èœãæãªãããšãªãè€éãªæ¥ååŠçãå®éããããå Žé¢ãåºãŠããŸãã ãã®ãããªå ŽåãåŠçãããçšåºŠã®ç²åºŠã§åãåºããŠãå¿çãè¿ãããã»ã¹ãšã¯å¥ã®ããã»ã¹ã§åŠçããããšããæ¹æ³ãèããããŸãã äŸãã°ãäºçŽå®äºåŠçã®äžã§ã¡ãŒã«éä¿¡éšåã ããå¥ã®ããã»ã¹ã§åŠçããããšãã£ãå
·åã§ãã ASP.NETã§ãã®ãããªããã¯ã°ã©ã³ããžã§ãåŠçãå®çŸããã«ã¯ãã©ã®ãããªæ¹æ³ãããåŸãã§ããããã ãã®èšäºã§ã¯ã.NETç°å¢ã§å©çšã§ããããã¯ã°ã©ãŠã³ããžã§ãã®ã©ã€ãã©ãªã§ããHangfireã«ã€ããŠãåœç€Ÿã§ã®å©çšäºäŸãç°¡åã«ç޹ä»ããŸãã Hangfireãå°å
¥ããçµç·¯ åœç€Ÿã®ãµãŒãã¹ã«ãåœç¶ãäžè¿°ãããããªããã¯ã°ã©ãŠã³ããžã§ãã®ããŒãºããããŸããã ASP.NETã§ããã¯ã°ã©ãŠã³ããžã§ãã®åŠçãå®çŸããå Žåãå
¬åŒã«æäŸãããŠãã QueueBackgroundWorkItem ã䜿ããšããææ®µããããŸãã ãããªãå°å
¥ã¯éåžžã«ç°¡äŸ¿ã§ãããããã倧äºãªåŠçãããã¯ã°ã©ãŠã³ããžã§ãã§å®è¡ããããšãèãããšããžã§ãã®ã¹ããŒã¿ã¹(ãã¥ãŒã€ã³ã°ãåŠçäžãåŠçæ£åžžå®äºãåŠç倱æ)ããžã§ãã®å®è¡å±¥æŽã®ç®¡çãè¡ãããããšèãããŸããã ãã®å ŽåãQueueBackgroundWorkItemãæ¡çšãããªãããã®éšåã¯èªåã§äœããªããã°ãªããŸããã ãŸããã¯ã©ãŠããæäŸãããã¥ãŒåŠçã®ãµãŒãã¹ãäœ¿ãæ¹æ³ãããåŸãŸããããã®å Žåãããžã§ãã®ã¹ããŒã¿ã¹ããžã§ãã®å®è¡å±¥æŽã®ç®¡çã¯èªåã§äœããªããã°ãªããŸããã Hangfireã¯ããžã§ãã¹ãã¬ãŒãžãšãžã§ãã®ç®¡çæ©æ§ãçµã¿èŸŒãŸããŠããããã€ãæ¢åã®.NETã®ã³ãŒãã倧ããå€ããããšãªãå©çšã§ãããšããå©ç¹ããããŸãã äœè
ã«ããã° Hangfire is a .NET Framework alternative to Resque, Sidekiq, delayed_job, Celery. ã ããã§ãã 以äžã®ç¹ãç·åçã«å å³ããŠãHangfireãæŽ»çšããããšã«æ±ºããŸããã æ§æ Hangfireã䜿ãå Žåãã¢ããªã±ãŒã·ã§ã³ã®æ§æã¯å€§ãã以äžã®ãµãã€ãããåŸãŸãã ããã¯ã°ã©ãŠã³ããžã§ãåŠçãè¡ããããŠã§ãã¢ããªã±ãŒã·ã§ã³ã®å
éšã«ããã¯ã°ã©ãŠã³ããžã§ããµãŒããåäœãããã ããã¯ã°ã©ãŠã³ããžã§ãåŠçãè¡ããããŠã§ãã¢ããªã±ãŒã·ã§ã³ãšããã¯ã°ã©ãŠã³ããžã§ããµãŒããå®å
šã«åé¢ããã åœç€Ÿã§ã¯ãå®å
šã«åé¢ããæ§æã«ããŸãããå
éšã«ããã¯ã°ã©ãŠã³ããžã§ããµãŒããåäœãããå ŽåããŠã§ãã¢ããªã®ããã»ã¹ã®åèµ·åãšãžã§ãã®åŠçã®ç¶æ
ãæ°ã«ããå¿
èŠããããããå®å
šã«åé¢ããã»ããéçšãç°¡åã ãšå€æããŸããã äžèšã®å³ã®éãããžã§ããã¥ãŒã®ã¹ãã¬ãŒãžã«ã¯Elasticache Redisã䜿ã£ãŠããŸããHangfireã¯æšæºã¹ãã¬ãŒãžãšããŠSQL Serverã䜿ããŸããã Redisã®ã»ãããã髿§èœã§ãããšãããã³ãããŒã¯çµæ ãèæ
®ããRedisã«ããŸããã ãŸãããžã§ãã®ã¹ããŒã¿ã¹ãå皮管çãã§ããDashboardã¯ãHangfireã䜿ããŠã§ãã¢ããªãšãããã¯ã°ã©ãŠã³ããžã§ããµãŒããšãå¥ã®ãµãŒãã«æ§ç¯ããŸããã å®è£
äŸ å®è£
èªäœã¯ãšãŠãç°¡åã§ãã namespace Sample.Service.JobQueue { /// < summary > /// ããã¯ã°ã©ãŠã³ããžã§ãå°å
¥ã®ããã®ãµã³ãã«ã¯ã©ã¹ /// </ summary > public class JobQueueSampleService { public void DoSomething( string param1) { JobQueueClient.Enqueue(() => DoAsBackgroundJob(param1)); } /// < summary > /// ãã®ã¡ãœããããã¥ãŒã«è©°ããã /// </ summary > /// < param name = "param1" > /// Hangfireã¯ããã©ã¡ãŒã¿ãJsonã§ã·ãªã¢ã©ã€ãºããŠã¹ãã¬ãŒãžã«è©°ããã /// </ param > [Hangfire.AutomaticRetry(Attempts = 3 )] // <== ãªãã©ã€åæ°ããã¥ãŒã«è©°ããã¡ãœããã®å±æ§ã§åæ°ãæå®ãããæå®ããªããš10åãªãã©ã€ããªãã©ã€ããªããªã0åã«ããŠããã public void DoAsBackgroundJob( string param1) { // --- do something } } public class JobQueueClient { private static readonly Lazy<IBackgroundJobClient> _cachedClient = new Lazy<IBackgroundJobClient>(() => new BackgroundJobClient()); public static string Enqueue(Expression<Action> methodCall) { var client = _cachedClient.Value; return client.Create(methodCall, new EnqueuedState(QueueName)); } } } Hangfireã¯ãã¡ãœããããžã§ããã¥ãŒã«ãšã³ãã¥ãŒããããšããä»çµã¿ã«ãªã£ãŠããŸããâã®ã³ãŒãã§ã¯ã JobQueueClient.Enqueue(() => DoAsBackgroundJob(param1)); ã§ã DoAsBackgroundJobã¡ãœããã§ãžã§ããšããŠãžã§ãã¹ãã¬ãŒãžã«ä¿åããŠããŸãã ãšã³ãã¥ãŒããããšã§ãã¡ãœããã®ã·ã°ããã£ããã©ã¡ãŒã¿ããã®ã¡ãœãããå±ããã¢ã»ã³ããªåãªã©ããžã§ãã¹ãã¬ãŒãžã«ä¿åãããŸããããã¯ã°ã©ãŠã³ããžã§ããµãŒãã¯ããã®æ
å ±ãããã¥ãŒããŠããªãã¬ã¯ã·ã§ã³ã䜿ã£ãŠãä¿åãããã¡ãœãããåŒã³åºããŸãã ãªãã¬ã¯ã·ã§ã³ã䜿ãã®ã§ãHangfireã®ã¯ã©ã€ã¢ã³ããšãªããŠã§ãã¢ããªãšããã¯ã°ã©ãŠã³ããžã§ããµãŒãã¯åãã¢ã»ã³ããªãåç
§ããå¿
èŠããããŸãã â»Hangfireã«ã¯ã BackgroundJob.Enqueue ãšãããšã³ãã¥ãŒåŠçã®ããã®ããããããã€ã³ã¿ãŒãã§ãŒã¹ãããã®ã§ãããããã¯åŸè¿°ããçç±ã«ããã䜿ããŸããã§ããã å·¥å€«ç¹ åè¿°ããéããHangfireã®ã¯ã©ã€ã¢ã³ããšãªããŠã§ãã¢ããªãšããã¯ã°ã©ãŠã³ããžã§ããµãŒãã¯åãã¢ã»ã³ããªãåç
§ããå¿
èŠããããŸãã å®éçšã§ãããå®çŸããããšãããšã次ã®2ç¹ãèããå¿
èŠããããŸãã æ¯æ¥è€æ°åãããã€ããããŠã§ãã¢ããªã±ãŒã·ã§ã³ãšããã¯ã°ã©ãŠã³ããžã§ããµãŒãã®ã¢ã»ã³ããªãäžèŽãããå¿
èŠãããã ãŠã§ãã¢ããªã±ãŒã·ã§ã³ã®ãããã€ãµã€ã¯ã«ãããLong Runningãªãžã§ãã§ããã¡ããšåŠçãå®éãããå¿
èŠãããã ãããã ãšã³ãã¥ãŒãããŠã§ãã¢ããªã±ãŒã·ã§ã³ãšåãã¢ã»ã³ããªãåç
§ããŠããããã¯ã°ã©ãŠã³ããžã§ããµãŒãã§åŠçãå®éãããå¿
èŠãããã ãã®ãµãã€ãå®çŸããå®çŸããããã«ã以äžã®ãµãã€ã®ææ®µãæ¡çšããŸããã Hangfireã®ååä»ããã¥ãŒãå©çšããã ããã¯ã°ã©ãŠã³ããžã§ããµãŒãã¯Windows ServiceãšããŠçšŒåãããåãã¢ã»ã³ããªãåç
§ããŠãããŠã§ãã¢ããªã±ãŒã·ã§ã³ãå€ãããŒãžã§ã³ã«ãªã£ãŠãåããç¶ããã Hangfireã®ååä»ããã¥ãŒãå©çšããã Hangfireã¯ããã¥ãŒã«ååãä»ããããšãã§ããŸããããååã®ãã¥ãŒã«è©°ãããããžã§ãã¯ãã®ååã®ãã¥ãŒãåŠçããããã«æå®ãããããã¯ã°ã©ãŠã³ããžã§ããµãŒãã§ããåŠçãããŸããããã¥ãŒåã¯éåžžãæ¬¡ã®ããã«ãã¥ãŒã«è©°ããã¡ãœããã®å±æ§ã§æå®ããŸãã [Queue( "testqueue" )] public void SomeMethod() { } ãããŠãããã¯ã°ã©ãŠã³ããžã§ããµãŒãåŽã§ã¯ãµãŒããåæåãããšãã«ããã¥ãŒã®ååãæå®ããŸãã以äžã®ããã«ã var options = new BackgroundJobServerOptions { Queues = new [] { "testqueue" } }; app.UseHangfireServer(options); // or using ( new BackgroundJobServer(options)) { /* ... */ } ããã§ã testqueue ãšãããã¥ãŒã«è©°ããã¡ãœããã¯ãâã®ãµãŒãã§ããåŠçãããªããªããŸãã ããŠã ããããŒãžã§ã³ã®ã¢ã»ã³ããªãåç
§ããŠãããŠã§ããµãŒãããã¥ãŒã«è©°ããã¡ãœããã¯åãããŒãžã§ã³ã®ã¢ã»ã³ããªãåç
§ããŠããããã¯ã°ã©ãŠã³ããžã§ããµãŒãã§åŠçãããã ãšããèŠä»¶ã¯ã以äžãå®çŸããã°æºããããã§ãã åãããŒãžã§ã³ã®ã¢ã»ã³ããªãåç
§ããŠãããŠã§ããµãŒããšããã¯ã°ã©ãŠã³ããžã§ããµãŒãã¯åããã¥ãŒåãå©çšããããã®ãã¥ãŒåã¯ãã«ãåäœã§çæããå®å
šã«ãŠããŒã¯ã§ããã ãã«ãåäœã§çæããå®å
šã«ãŠããŒã¯ãªå€ãšããŠããã«ãããŒãžã§ã³ã®çªå·ããããŸãããããã§ãã®çªå·ããã¥ãŒåã«ããããšã§ãã®èŠä»¶ãæºããããšãã§ããŸããã ãã ããHangfireã®ãµã³ãã«ãªã©ã§äžçªããèŠããã BackgroundJob.Enqueue ã§ã¯ããã¥ãŒåãã¡ãœããã®å±æ§ãšããŠããæå®ã§ããŸãããã€ãŸããåçã«èšå®ã§ããªãã®ã§ãã調ã¹ãŠã¿ããšã BackgroundJobClient ã¯ã©ã¹ã®Createã¡ãœãããçŽæ¥äœ¿ãããšã§ãã¥ãŒåãåçã«æå®ã§ããããšãããããŸããã®ã§ã以äžã®ãã㪠BackgroundJobClient ãã©ããããã¯ã©ã¹ãäœãEnqueueã¡ãœãããå®è£
ããŸããã public class JobQueueClient { private static readonly Lazy<IBackgroundJobClient> _cachedClient = new Lazy<IBackgroundJobClient>(() => new BackgroundJobClient()); public static string Enqueue(Expression<Action> methodCall) { var client = _cachedClient.Value; return client.Create(methodCall, new EnqueuedState(QueueName)); } } } ããã¯ã°ã©ãŠã³ããžã§ããµãŒãã¯Windows ServiceãšããŠçšŒåããåããç¶ããã æ°ãããŠã§ãã¢ããªããããã€ãããŠãå€ãããã¯ã°ã©ãŠã³ããžã§ããµãŒããåäœããŠããã°ããããã€ãµã€ã¯ã«ãããLong Runningãªãžã§ãããã¡ããšåŠçã§ããŸãã ããã¯ãã·ã³ãã«ã« ããã¯ã°ã©ãŠã³ããžã§ããµãŒãã¯Windows ServiceãšããŠå®è£
ããæ°ããããŒãžã§ã³ã®ããã¯ã°ã©ãŠã³ããžã§ããµãŒãããããã€ãããŠããå€ãããŒãžã§ã³ã®ããã¯ã°ã©ãŠã³ããžã§ããµãŒãã¯åæ¢ããªãããã«ããŸããã ããã¯ã°ã©ãŠã³ããžã§ããµãŒããWindows Service ãšããŠåããæ¹æ³ã¯ã å
¬åŒãµã€ãã«ãéèšãããŠããŸã ããããããã®ããæ¹ã«ã¯åŸããã«ã Topshelf ã䜿ã£ãŠServiceã«ããŸãããWindows Serviceã®ã€ã³ã¹ããŒã«ãã¢ã³ã€ã³ã¹ããŒã«ãéå§ã忢ãç°¡åã«å¶åŸ¡ã§ããããã§ãã ããã¯ã°ã©ãŠã³ããžã§ããµãŒãã®ãããã€ã¯AWS Codedeployã䜿ããŸãã Codedeployã®after installã®hookã§ãããã¯ã°ã©ãŠã³ããžã§ããµãŒããWindows ServiceãšããŠã€ã³ã¹ããŒã«ããéå§ãããŠããŸãã ãã®ãšããé
眮ãããã©ã«ãããããã€ããŒãžã§ã³ããšã«å€ããããšã§ãæ¢åã®Serviceãåããç¶ããªãããæ°ããããŒãžã§ã³ã®Serviceã皌åãããããšãã§ããŸãã appspec.ymlã¯âã®ããã«ããŸãã version : 0.0 os : windows files : - source : / destination : d:/latest hooks : AfterInstall : - location : /after-install.bat after-install.batã¯ã以äžã®éãã rem $T ARGET_FOLDER ã ãã«ãæã«ãã«ãããŒãžã§ã³ã«æžãæããã xcopy D:\latest D:\ $T ARGET_FOLDER\ /E /Y /I /Q D:\ $T ARGET_FOLDER\bin\BackgroundJob.ProcessingServer.exe install D:\ $T ARGET_FOLDER\bin\BackgroundJob.ProcessingServer.exe start ãã ãããã®ãŸãŸã ãšæ°žé ã«Windows Serviceãå¢ãç¶ããŠããŸããŸãã察çãšããŠãæ¥æ¬¡ã§1æ¥ä»¥äžå€ããªã£ãããŒãžã§ã³ã®ããã¯ã°ã©ãŠã³ããžã§ããµãŒãã忢ããããã«ããŸããã ãŸãšã åœç€Ÿã§ã¯Hangfireããããã¯ã·ã§ã³ç°å¢ã®æ¥ååŠçã§æŽ»çšãå§ããŠãŸã æ¥ãæµ
ãã§ããããããçŸæç¹ã§ã¯ãåé¡ãªãåäœããŠããŸãã ä»åŸã¯ãçãééã§åãããŠãããããåŠçããŠã§ãã¢ããªã®ããã¯ã°ã©ãŠã³ããžã§ãã«åãæ¿ããŠããããšããäœ¿ãæ¹ãæ³å®ããŠããŸãã ãã®èšäºã®çè
ã«ã€ã㊠ã·ã¹ãã æ¬éšCTO宀æå±ã® åŸ³æŠ ã§ãã ãµãŒãã¹ã®æè¡åºç€ã®éçºéçšã宿æ³ãµãŒãã¹ã®éçºæ¯æŽãè¡ãªã£ãŠããŸãã
ãã®èšäºã¯äžäŒ.com ã¢ããã³ãã«ã¬ã³ããŒã®18æ¥ç®ã®èšäºã§ãã qiita.com ããã«ã¡ã¯ã 瀟å
æ
å ±ã·ã¹ãã éšã®äžæã§ãã äžäŒã§ã¯OfficeITã«é¢ããå
šãŠã®æ¥åãæ¹åãæ
åœããŠããŸããããããæ
ã·ã¹ã§ãã æ¬æ¥ã¯ãäžäŒã®æ
ã·ã¹ãè¡ã£ãŠããæŽ»åã®ãã¡ãéçºè
ããã°ããã瀟å
åãã®SlackããŒã«ãéçº(?)ããããšã«ã€ããŠèšèŒããããšæããŸãã ã©ããªããŒã«ãäœã£ãã®ãïŒ äžäŒã§ã¯ã³ãã¥ãã±ãŒã·ã§ã³ããŒã«ãšããŠãéãšã³ãžãã¢ã§ãã£ãŠãSlackãæŽ»çšãããŠããŸãã ãã®Slackã䜿ã£ãŠã ãã¡ãã£ãšããããšãæ€çŽ¢ã§ããbotãããã°äŸ¿å©ãªããããªããïŒã ãšæã 瀟å
åãã«æäŸããŸããã å
·äœçã«ã¯äžèšã®ãããªããšãSlackäžã§æ€çŽ¢ã§ããããã«ããŠããŸãã å
ç·çªå·ããã¡ãŒã«ã¢ãã¬ã¹ãªã©ã®ç€Ÿå¡æ
å ±ãæ€çŽ¢ã ã座åžè¡šãããç¡ç·LANã®ããŒ(ãã¹ã¯ãŒã)ããªã©ã®URLãæ€çŽ¢ã äŒè°å®€ã®ç©ºãç¶æ³ã確èªã(äºå®ã空ããŠããã°botäžããäºçŽãå¯èœã«ããŠããŸãã) ã㢠ãçŸèã¯äžèŠã«ãããããšããããšã§å®éã®åäœãã¢ã§ãã é°å²æ°ãäŒããã°å¹žãã§ãã ã¡ãªã¿ã«ããœããšã¯botã®èµ·åããªã¬ãŒã§ãã ãœ<ãªãã¡ãã>ãšæžããšbotãåå¿ããããã«ããŠããŸãã äœè«ïŒãªãã§ããœããªã®ïŒ èµ·åããªã¬ãŒã¯äžèšã®æ¡ä»¶ãæºããå¿
èŠããããŸããã äžèšæ¡ä»¶ãå
šãŠæºããã®ãããœãã§ããã èŠããããã ããœãã£ãŠãªããã€ã³ãã¯ããããŸãããã æã¡ãããã ãèªèº«ã®ããŒããŒãé
åèŠãŠã¿ãŠãã ããããpããšãoããè¿ããŠæã¡ããããªãã§ããã ãã¶ããªãã ãã¶ããããããŒã¯ãŒããèµ·åããªã¬ãŒã«ãããšbotã誀æ€ç¥ãã¡ããã®ã§ã ããœãã§å§ãŸãããŒã¯ãŒãã£ãŠãªããªããªãã§ãããã æ§æ ãã®ããŒã«ã®æ§æã¯äžèšã®ããã«ãªã£ãŠããŸãã ããŒã«ãæ€çŽ¢/åçããé åºãšããŠã æçš¿ãããããŒã¯ãŒãããäŒè°å®€ç¶æ³ç¢ºèªããå«ãå ŽåãäŒè°å®€äºçŽæ
å ±ãåçã äžèšããŒã¯ãŒãã§ã¯ãªãå ŽåãGoogle SpreadSheetãã«èšèŒããããã確èªãããã°SpreadSheetã®å
容ãåçã SpreadSheetã«ãããŒã¯ãŒããç¡ãå ŽåãADã«ç»é²ãããŠããç€Ÿå¡æ
å ±ãã©ãã確èªãåçã ãšããé åºã§æ€çŽ¢/åçããããããã«ããŠããŸãã (botã®èµ·åããªã¬ãŒãç¡çããäžã€ã§å®çµããããã«ããã®ã§è¥å¹²ç¡çããããŸããã) â 詳现 瀟å¡ãç¹å®ã®ãã£ã³ãã«ã«æçš¿ããã Slackã®Outgoing Webhookã§æçš¿ãããå
å®¹ãæ€ç¥ããGAS(Google Apps Script)ã«æçš¿å
容ãPostããã â»1 æçš¿å
容ããäŒè°å®€ç¶æ³ç¢ºèªããªã®ã確èªã äŒè°å®€äºçŽã®å ŽåïŒäŒè°å®€ç©ºãæ
å ±ãè¿ããŠçµäºã â»2 ããã§ã¯ãªãå ŽåïŒæ¬¡ã®ã¹ããããžã Google SpreadSheetã®å
容ãGASã«ãŠç¢ºèªã èšèŒãããå ŽåïŒæ€çŽ¢çµæãè¿ããŠçµäºã â»3 èšèŒããªãå ŽåïŒæ¬¡ã®ã¹ããããžã æ€çŽ¢å
容ãhubotçšã®Slackãã£ã³ãã«ã«æçš¿ãADãSlackã®ãŠãŒã¶äžèŠ§ã«æ€çŽ¢æ
å ±ãå«ãŸããŠããã確èªããçµæãè¿ãã ADããã¯é»è©±çªå·ãå
ç·çªå·ãéšçœ²åãªã©ã®æ
å ±ãæœåºã â»4 SlackAPIã®ãusers.listãã䜿ã£ãŠãEmailAddressãããŒã«SlackUserIDãæœåºã â»5 â»1 åèURL â»2 åèURL å°å³ã«ããã£ãã®ã察象ã®ãªãœãŒã¹(äŒè°å®€)ãé²èŠ§ç¶æ
ã«ããªããšäºå®ãååŸã§ããªãã®ã§ã ããŸããªããšããŠã CalendarApp.subscribeToCalendar(\<resourceIDãå
¥å>); ãšäºåã«å®çŸ©ããŠãããšè¯ãã§ãã â»3 ãã¡ãã®URL ãåèã«è¡çªå·ãååŸããŠã ãã¡ã ãåèã«å¯Ÿè±¡ã®ã»ã«ãååŸããŠãŸãã â»4 WindowsServerã§hubotãèµ·åããŠããŸãã ãGet-AdUser -Filter 'enabled -eq $true' -Properties *ã ããŠãADç»é²æ
å ±ãå
ç·çªå·ãªã©å¿
èŠãªãã®ãåŒã£åŒµã£ãŠãŸãã â»5 åèURL èª²é¡ ã¡ã³ããã³ã¹æ§ãèããã«é©åœã«äœã£ãŠããŸã£ãã®ã§æ§æããšãŠãè€éã«ãªã£ãŠããŸããŸãããã ADã«ã€ããŠã¯ããããAWS Directory Serviceã«ç§»è¡äºå®ãªã®ã§ãADæ
å ±ãªã©ã¯hubotã䜿ããã« Lambdaã§åç
§ããããã«ãããå€å°ã¯ã·ã³ãã«ãªæ§æã«ãªãã®ã§ã¯ãªãããšèããŠããŸãã botããªãªãŒã¹ããŠããèµ·ããããš å
ç·çªå·ãšãã座åžè¡šã£ãŠåç
§ããæ©äŒã¯ãããã®ã®ãããããšããæã« ãã©ãã«æžããŠãã£ãã£ãç¶æ
ãã«é¥ããŸãããã ãé°æ§ã§ããœãã¯ç€Ÿå
ã§ããå©çšãããŠããŸãã®ã§ã çµæãšããŠããã©ãã«æžããŠãã£ãã£ãç¶æ
ããè§£æ¶ã§ãã 瀟å¡ããäœããæ¢ããæéãå°ãã¯æžãããã®ããªãšæããŸãã äœè«ã§ããã人ããæ¢ãæéãã«æéãè²»ããã®ã¯ 幎é150æé ãããããã§ããã ãã®æéãå°ãã§ãæžãããæå©ããã§ããããªãšæããŸãã æåŸã« ããããããäžäŒæ
ã·ã¹ã¯ä»å玹ä»ããããŒã«ã®ãããªãã®ãªã©ãæäŸããŠã 瀟å¡ã ãæ¬æ¥ããã¹ãæ¥åã«éäžããŠæéãå²ããããã ãµããŒããç¶ããŠãããŸãã ãããŠããã®èšäºãåãå¿ãæã€èª°ãã®åèã«ãªãã°å¬ããã§ãã id:undersooon ã§ããã ææ¥ã¯@s-tokutake ã® ãHangfire [å°å
¥ç·š]ã ã§ãããæ¥œãã¿ã«ïŒ
ãã®èšäºã¯äžäŒ.com ã¢ããã³ãã«ã¬ã³ããŒã®17æ¥ç®ã®èšäºã§ãã qiita.com 宿æ³äºæ¥éšã®ããã«ãããšå±±å£ã§ãã UIUXããŒã ã§ããã³ããšã³ããããã¯ãšã³ãã®ã¢ããªã±ãŒã·ã§ã³éçºãæ
åœããŠããŸãã äžäŒã§ã¯å®¿æ³äºæ¥ãšã¬ã¹ãã©ã³äºæ¥ããããŸãã ç§ãæå±ãã宿æ³äºæ¥ã§ã¯éçºèšèªã«C#ãšVB.NETã䜿çšããŠããŸãã ãã®èæ¯ããéçºã«ã¯Windowsã䜿ã£ãŠããŸãã æ®æ®µMacãLinuxã§WebéçºããŠããWebãšã³ãžãã¢ã«ãšã£ãŠã¯WindowsãC#ã䜿ã£ãWebéçºã¯ããŸã銎æã¿ããªããããããŸããã ããã§ãããªæ¹åãã«WindowsãC#ã䜿ã£ãWebéçºã«ã€ããŠã話ããããšæããŸãã C#ã«ã€ã㊠ãŸãã¯C#ã«ã€ããŠã C#ã«è§Šããããšã®ãªãæ¹ã¯ã©ããªã€ã¡ãŒãžãæã£ãŠããŸãããïŒ Microsoft補ïŒJavaã¿ããïŒäœ¿ã£ãŠããäŒæ¥ã¯ïŒ è²ã
ãªã€ã¡ãŒãžãããããšæããŸãã ããã§ã¯C#ãäŒæ¥ãéçºç°å¢ãèšè¿°ãšãã£ãç¹ãã説æããŸãã 䜿ã£ãŠããäŒæ¥ C#ã䜿ã£ãŠããäŒæ¥ã£ãŠã©ããªæ¥çãªãã§ãããïŒ äž»ã«ã²ãŒã ç³»ãéèç³»ã§äœ¿ãããŠããã€ã¡ãŒãžã§ãã ã²ãŒã ç³»ã¯ã³ã³ã·ã¥ãŒããŒããœã·ã£ã²ã«éããªãã§ãããUnityã䜿ã£ãŠããäŒæ¥ã¯ãã®æµãã§ãµãŒããŒãµã€ããC#ãšããäŒæ¥ãå€ãããã§ãã éèç³»ã¯Microsoftã®ãµããŒããæåŸ
ããŠã®å°å
¥ã§ããããã ãµããŒãæéã®é·ããç¹åŸŽã®äžã€ã§ããããæ¡çšã®çç±ã®äžã€ãããããŸããã https://support.microsoft.com/ja-jp/lifecycle/search?alpha=Microsoft%20.NET%20Framework%203.5 ãèŠããš2008幎ã«åºã.Net Framework 3.5ïŒC#ã®å®è¡ç°å¢ïŒã2028幎ãŸã§ãµããŒããããããšã«ãªã£ãŠããã®ã§ã20幎ãã®ãµããŒãæéãããããšã«ãªããŸãã èªç€Ÿã®WebãµãŒãã¹ãã¢ããªïŒã²ãŒã ãé€ãïŒããã£ãŠããäŒç€Ÿã§ã¯ãŸã ãŸã æ¡çšããŠããäŒæ¥ãå€ããšã¯èšããŸããã äœè«ã§ãã C#erã«ç¹åããäŒç€Ÿ ãªããŠã®ãã§ããŸãããã²ãŒã åãã§ããã éçºç°å¢ åŒç€Ÿã§ã¯ Visual Studio ãšããIDEã䜿çšããŠããŸãã Visual StudioãšèããŠæãæµ®ãã¹ãã®ã¯ Visual Studio Code ã§ããããã Visual StudioãšVisual Studio Codeã¯å
šãã®å¥ç©ã§ãã Visual Studio Codeã¯ã¯ãã¹ãã©ãããã©ãŒã ã§åäœããã®ã«å¯ŸããŠãVisual Studioã¯Windowsã§ã®ã¿åäœããŸãã C#ã®éçºã«äœ¿çšããIDEãšããŠã¯Visual StudioãäžåŒ·ã§ãã ä»ã«ã¯ Visual Studio for Mac ãJetBrainsããåºãŠãã Rider ãšããIDEããããŸããäžäŒã§ã¯äœ¿çšããŠããŸããã äžäŒã¯.Net FrameworkãšããWindowsã§ã®ã¿åäœããC#ã®å®è¡ç°å¢ãã¡ã€ã³ã«äœ¿çšããŠããŸãã ãã®ããWindowsã«ããã¯ã€ã³ãããŠããŸãããã¯ãã¹ãã©ãããã©ãŒã ã§ãã.Net Coreã®ç»å Žã«å ããäžèšã®IDEãããããMacãLinuxã§ã®éçºãå¯èœã§ãã ãŸã .Net Coreã®æ¡çšäºäŸã¯å°ãªãã§ããC#ã¯Windowsã ãã®ãã®ã§ã¯ãªããªã£ãŠããŠããŸãã Windowså
éšã§ã®WebãµãŒã㌠ããŒã«ã«éçºç°å¢ã¯IISãšãããã®ã䜿çšããŸãã ããããApacheãnginxã®ãããªWebãµãŒããŒã§ãã ç»åã®ããã«GUIããã®æäœãå¯èœã§ããããã¡ããCUIããã®æäœãå¯èœã§ãã äžäŒã§ã¯éçºç°å¢ã®åææ§ç¯ãããŠãããããããã¡ã€ã«ãããããããå®è¡ãããšãã®IISã®ãµã€ããæ§ç¯ãèšå®ããŠãããããã«ãªã£ãŠããŸãã Docker å®ã¯WindowsãDockerãåããããšãã§ããŸãã Macã§äœ¿ãããŠããDocker for Macã®WindowsçãDocker for WindowsããããŸãã å
éšã§ã¯Hyper-Vã§MobyLinuxãç«ãŠãŠãã®äžã«Dockerã³ã³ããããã¹ãã£ã³ã°ãããããã«ãªã£ãŠããŸãã ããã ãã§ãªãä»ãVirualboxãªã©ã®ä»®æ³ç°å¢æ§ç¯ãœããã«é ŒããUbuntuã䜿ãããšãã§ããWSLïŒWindows Subsystem for LinuxïŒãšãããã®ããããŸãã VagrantãDockerãšã¯äœ¿ãåæãéãã®ã§èºãããšããããŸããã䜿çšçšéãéå®ããã°ä»ã®ãšããåé¡ãããŸããã www.atmarkit.co.jp Webãã¬ãŒã ã¯ãŒã¯ äžäŒã§ã¯C#ã§Webãéçºãããšãã«ASP.NET Web FormsãšASP.NET MVCãASP.NET Web APIã䜿çšããŠããŸãã ASP.NET Web Formsã¯ã€ãã³ãããªãã³ã¢ãã«ã§Windowsã¢ããªã±ãŒã·ã§ã³ã®ç¥èãWebã§ã掻çšã§ããããã«äœããããã¬ãŒã ã¯ãŒã¯ã§ãã åäœãã¹ããè¡ãã«ããã£ãããåºæã®æŠå¿µããã¥ãŒãšãªãHTMLã®å¶åŸ¡ãé£ãããªã©ãä»ã®Webéçºã«ã¯åã£ãŠãããæ°èŠã§æ¡çšããã¡ãªããã¯ãããŸããã ãã®ããããããæ°èŠãããžã§ã¯ããäœãå Žåã¯MVCãWeb APIã§äœæããããšæããŸãã ASP.NET MVCã«ã€ããŠã¯ç¹çããç¹ã¯ãããŸããããäžè¬çãªMVCãã¬ãŒã ã¯ãŒã¯ã®æ©èœãåãã£ãŠãããèãããåãããã§ã¡ããã©ããå¡©æ¢
ã®ãã¬ãŒã ã¯ãŒã¯ãšãªã£ãŠããŸãã ASP.NET MVCã¯MVCãšããååã¯ã€ããŠããŸããå®ã¯ã¢ãã«ã«çžåœããæ©èœã¯ãããŸããã ããã§ããã¯ã€ã³ãããŠããªãã®ã§ã¢ãã«ã®äœæã¯æè»ã«è¡ããããã«ãªã£ãŠãããšãããã¡ãªããã§ãã èšè¿°ååŒ ããããã¯C#ã®èšè¿°ã玹ä»ããŸãã C#ã¯åŒ·ãéçåä»ãã®èšèªã§ãã ãããŠãªããžã§ã¯ãæåèšèªã§ããããŸãã å®éã®ã³ãŒããèŠãŠã¿ãŸãããã public class Child : Parent { private readonly string str; private readonly int num; public Child( string str, int num) { this .str = str; this .num = num; } public string GetContent() { return $ "str = {str}, num = {num}" ; } } var child = new Child( "test" , 1 ); child.GetContent(); // str = test, num = 1 ãªããžã§ã¯ãæåèšèªããã£ãŠããæ¹ãªã现ããå·®ç°ã¯ããã©çè§£ããããã®ã§ã¯ãªãã§ããããã ãã®ã³ãŒãã ãèŠããšããªãJavaã«è¿ãã§ããã åå空éãããã±ãŒãžã«ããã¢ã¯ã»ã·ããªãã£ã¬ãã«ãéã£ããEnumã«ã¡ãœãããçãããªããšãã£ãéãã¯ãããŸãã å ããŠåæšè«ãgetter setterãasync awaitãªã©äŸ¿å©ãªæ©èœã«å ããŠLINQãšãã䟿å©ãªã³ã¬ã¯ã·ã§ã³ã©ã€ãã©ãªããããŸãã åæšè« // intåã« var num = 1 ; // List<string>åã« var strList = new List< string >() { }; getter, setter, ã¡ã³ã public class Person { public string FirstName { get; set; } public string LastName { get; set; } public string FullName { get => $ "{FirstName}{LastName}" ; } } var Person = new Person(); Person.FirstName = "Taro" ; Person.LastName = "Tanaka" ; Console.WriteLine(Person.FullName); ããããã£ããšã«ã¢ã¯ã»ã¹ä¿®é£Ÿåãå€ããããšãã§ããŸãã public int Age { get; private set; } readonlyãšãããã®ãã public class Person { private readonly DateTime birthday; public Person(DateTime birthday) { this .birthday = birthday; } } ã€ã³ã¹ã¿ã³ã¹ãã£ãŒã«ãã§ããã°ã³ã³ã¹ãã©ã¯ã¿å
ã§ã®ã¿å²ãåœãŠå¯èœãšããå¶éãã€ããããšãã§ããŸãã åæå ãªããžã§ã¯ãåæåå public class Person { public string FirstName { get; set; } public string LastName { get; set; } public Person() { } } var Person = new Person() { FirstName = "Taro" , LastName = "Tanaka" }; ååä»ãåŒæ° public class Person { public Person( int age, DateTime birthday) { // åŠç } } var Person = new Person(age: 5 , birthday: DateTime.Now); async await åæ°ã®ã¿ã¹ã¯ public async Task< string > GetSingleAsync() { var result = await GetStringAsync(); return $ "çµæ={result}" ; } private Task< string > GetStringAsync() { var task = Task< string >.Run(() => { // äœãéãåŠç return "async!" ; }); return task; } var single = new SampleAsync().GetSingleAsync().Result; è€æ°ã®ã¿ã¹ã¯ public async Task< string > GetMultiAsync() { var task1 = GetStringAsync(); var task2 = GetStringAsync(); var task3 = GetStringAsync(); var task4 = GetIntAsync(); var results = await Task.WhenAll(task1, task2, task3); return string .Join( "," , results); } var multi = new SampleAsync().GetMultiAsync().Result; LINQ ã³ã¬ã¯ã·ã§ã³ã䟿å©ã«æ±ããæ¡åŒµã¡ãœããã§ãã ããããšãŠã匷åã§ãããããããããC#ã¯è¯ããšèšããã»ã©ã§ãã var arr = new string [] { "a" , "bb" , "ccc" }; // å«ãã§ããã arr.Any(s => s == "a" ); // True // çµã蟌㿠arr.Where(s => s.Length >= 2 ); // IEnumerable<string> { "bb", "ccc" } // å°åœ± arr.Select(s => s + s); // IEnumerable<string> { "aa", "bbbb", "cccccc" } // ä»ã«ãè²ã
IEnumerableãªå€ïŒç°¡åã«èšããšforeachã§ã«ãŒãå¯èœïŒãè¿ãããããã¡ãœãããã§ãŒã³ã§æžãããšãå¯èœã§ãã arr.Where(s => s.Length >= 2 ) .Select(s => s + s) .ToArray(); ä»ã«ã æ¡åŒµã¡ãœãã ãžã§ããªã¯ã¹ 屿§å®çŸ©ãAttribute nullæ¡ä»¶æŒç®å äŸå€ãã£ã«ã¿ãŒ ã¿ãã«ãåè§£ ãšãã£ããã®ããããŸãã èšè¿°ã ãèŠããšã¢ãã³ãªèšèªã«å£ãã䟿å©ãªãã®ãããã£ãŠããŸãããã ãã®èšäºã§å°ãã§ãWindowsãC#ã§ã®Webéçºã«èå³ãæã£ãŠããããã幞ãã§ãã ææ¥ã¯ id:undersooon ãã¡ãã£ãšããããšãæ€çŽ¢ã§ãããSlack botãäœã£ããã§ãã
æ¬èšäºã¯ãäžäŒ.com Advent Calendar 2018ã®16æ¥ç®ã®èšäºã§ãã qiita.com ããžã¿ã«ããŒã±ãã£ã³ã°éšã§äž»ã«å®¿æ³ãµã€ããæ
åœããŠããç°äž( id:yakisoba6318 )ã§ãã ä»åã¯ä»å¹Ž2æã«å°å
¥ããAMPã«ã€ããŠå°å
¥æãšä»ã«ã€ããŠç޹ä»ããããšæããŸãã å
容ã«é¢ããŠã¯äž»ã«å®¿æ³ãµã€ãã®è©±ãšãªããŸãã AMPãšã¯ïŒ AMPãšã¯ãAccelerated Mobile Pages ïŒã¢ã¯ã»ã©ã¬ã€ãã£ããã»ã¢ãã€ã«ã»ããŒãžïŒãšèšããäž»ã«Googleãæå±ããŠããã¢ãã€ã«ãŠã§ãé«éåãç®çãšãããããžã§ã¯ãã§ãã ããã§ã¯ãã®AMPãããžã§ã¯ãã®ãªãŒãã³ãœãŒã¹ãã¬ãŒã ã¯ãŒã¯ïŒAMP HTMLïŒãæããŠAMPãšèšããŸãã www.ampproject.org äžäŒ.comã«ãããAMPå°å
¥åæ© ã©ã³ãã£ã³ã°ããŒãžã®ã¹ããŒãæ¹å é床æ¹åã«ããæµå
¥ã®å¢å ãŠãŒã¶äœéšåäž ãªã©ãããããããŸãã ç°¡æœã«èšããš ã©ã³ãã£ã³ã°ããŒãžã®æé©å ã§ãã Choose a structured data feature | Search | Google Developers äžäŒ.comã®AMPããŒãžã®çŽ¹ä» çŸåšäžäŒã§å
¬éããŠããAMP察å¿ããŒãžãšãã€ã³ãã玹ä»ããŸãã å·Šããã¬ã¹ãã©ã³åºèããŒãžãå®¿æ³æœèšããŒãžã宿æ³èгå
ããŒãžã宿æ³ç¹éããŒãž ã¬ã¹ãã©ã³åºèããŒãžAMP ãªããã«ãŒã x AMPã§æµå
¥å¢ amp-list ã§ãã©ã³æ
å ±ãå²åŒçãåç衚瀺 ランチ - ザ・ロビー - ザ・ペニンシュラ東京/コンチネンタルダイニング [一休.comレストラン] ïŒã¹ããããã®ã¿ç¢ºèªã§ããŸã å®¿æ³æœèšããŒãžAMP amp-list ãã©ã³æ
å ±ã»ã¯ãã³ã衚瀺 amp-access ã§ã¯ãŒãã³è¡šç€º ザ・プリンス パークタワー東京 - 宿泊予約は[一休.com] ïŒã¹ããããã®ã¿ç¢ºèªã§ããŸã 宿æ³èгå
ããŒãžAMP ã¬ã¹ãã³ã·ã(Canonical / Responsive AMP ) amp-toolbox-optimizerã䜿ã£ãããŒãžã®æé©å ãŸã ãŸã 詊éšçãªããŒãžã§ä»ã¯äº¬éœãéæ²¢ãç®±æ ¹ãäžéšæž©æ³å°ã®ã¿ã§ãããããããšãªã¢ãæ¡å€§äºå® 京都観光で行きたい名所!京都旅行におすすめ人気スポットランキング 19選【2018年】 - [一休.com] ïŒã¬ã¹ãã³ã·ã察å¿ã®ããPCã»ã¹ããã©ã¡ãã§ã確èªã§ããŸã 宿æ³ç¹éããŒãž amp-storyå®éšçã«å
¬éäž é«çŽå®¿ã®çŽ æããªããã«è¡šç€ºã§ããããŒãž ãã ãæ¥æ¬ã§ã¯æ€çŽ¢ã§AMPViewãšããŠã®è¡šç€ºã¯ãŸã åºæ¥ãŠãªã ä»åŸã®å±éãæåŸ
ジ・ウザテラス ビーチクラブヴィラズ 新規開業[一休.com] ïŒamp-storyãPC衚瀺ã«å¯Ÿå¿ããŠããããPCã»ã¹ããã©ã¡ãã§ã確èªã§ããŸã AMPã³ã³ããŒãã³ãã®æŽ»çšäŸ AMPããŒãžãäœãã«ããã£ãŠæ¬ ãããªãã®ãå
¬éãããŠãã³ã³ããŒãã³ãã§ãã æ¥ã
ããããªã³ã³ããŒãã®éçºãé²ãã§ããŠAMPã§åºæ¥ãããšãå¢ããŠããŠããŸãã ä»åã¯ãã®äžéšã䜿ã£ãå©çšäŸã玹ä»ããŸãã www.ampproject.org åçãªã«ã«ãŒã»ã«ãåºããã < amp-list src = "ãã©ãã®ã£ã©ãªãŒAPI" height = â254â layout= âfixed-heightâ single-item> < template type = "amp-mustache" > < amp-carousel controls loop height = "254" layout= "fixed-height" type = "slides" > {{#photos}} < div > < amp- img src = "{{ImageUrl}}" layout= "fill" alt = "{{ImageAlt}}" ></ amp- img > </ div > {{/photos}} </ amp-carousel > </ template > </ amp-list > amp-listã¯ampäžã§xhrã§ããã®ã§APIãããªã¹ãååŸãåãåã£ããªã¹ããmustache圢åŒã§ã«ãŒããããŠç»åãåçã«çæããããšãã§ããŸãã https://www.ampproject.org/docs/reference/components/amp-list https://www.ampproject.org/docs/reference/components/amp-mustache ã«ã«ãŒã»ã«ã®ç»åææ°ã衚瀺ãããã < amp-state id = "GuideTopPhotoUrl" src = "ãã©ãã®ã£ã©ãªãŒAPI" ></ amp-state > < amp-carousel controls loop height = "254" layout= "fixed-height" type = "slides" on= "slideChange:AMP.setState({ GuideState: { header: { selectedSlide:event.index, Is_slide:true } } })" > <!-- ç¥ --> </ amp-carousel > < div > < span [ text ]= "!GuideState.header.is_slide ? '' : (GuideState.header.selectedSlide + 1) + '/' + (GuideTopPhotoUrl.items.photos.length + 1) " > </ span > </ div > on屿§ã«slideChangeãããªã¬ãŒãèšå®ããŠsetStateãæŽæ°ãæŽæ°ããæ
å ±ãspanã«bindããããšã§åçã«ææ°ãæŽæ°ããããšãã§ããŸãã https://www.ampproject.org/docs/reference/components/amp-carousel https://github.com/ampproject/amphtml/blob/14153fe212a80aeb6f1e7a7f14e4849cc228eba9/spec/amp-actions-and-events.md#L177 çµå±AMPã¯ã©ããªã®ïŒ 玹ä»ããããã«æ¢ã«å€ãã®ããŒãžãAMPåããŠããŸããã广ã©ãã ã£ãã®ãã ãããã工倫ãå¿
èŠãªç¹ããã£ãã®ã§ãããèžãŸããŠç޹ä»ããããšæããŸãã ãµã€ãããã©ãŒãã³ã¹ Before: AMP Visually Complete 4G äžããé ã«éåžžã®ã¹ããããŒãžãAMPããŒãžãGoogleãã£ãã·ã¥äžã®AMPããŒãž ãã¡ãã¯å°ãå€ãã¬ããŒãã§ãããå§ãã¯AMPã³ã³ããŒãã³ãã®äœ¿ãéããamp-stateã®äžèŠãªæŽæ°ãå€ãã£ããã AMPã®èŠä»¶ã¯æºãããŠããããŠãŒã¶äœéšãæªåããŠããŸããã ãªã®ã§å¯Ÿå¿ãšã㊠Googleãã£ãã·ã¥ããã®é
ä¿¡ã®æ©æµãåãããããªã¢ã«ã¿ã€ã æ§ã®äžèŠãªã³ã³ãã³ãã¯xhrã§ååŸããªã amp-stateã®æŽæ°ãbindããã®ã«æéããããããUIäžã§ã®äžèŠãªstate管çãèŸãã å
·äœçãªäŸãšã㊠ãã©ãã®ã£ã©ãªãŒã®amp-listãèŸãã ééã®UIãamp-state + hidden屿§ããamp-accordionã«å€æŽ çµæãšã㊠After: AMP Visually Complete 4G äžããé ã«éåžžã®ã¹ããããŒãžãAMPããŒãžãGoogleãã£ãã·ã¥äžã®AMPããŒãž AMPãoriginã®ã¹ããããŒãžããVisually Completeã®é¢ã§ã¯æ©ãç¶æ
ãŸã§æã£ãŠããããšãã§ããŸããã ã¡ãªã¿ã«TTFBã¯originãã»ãŒåãã§ãããDOMContentLoadã§å€§ããé
ããåã£ãçµæãã®ãããªæ°åã«ãªã£ãŠããŸããïŒweb page testïŒ ãŠãŒã¶äœéš amp-listã§æœèšã®ãã©ã³ãååŸããŠããŸãããå°å
¥åœåã¯èªã¿èŸŒã¿åŸã«å±éããããã«ããŠããŸããã ãã ãããã ãšããŒãžäžéšã®ã³ã³ãã³ãïŒã¢ã¯ã»ã¹ãæœèšæ
å ±ãªã©ïŒé²èЧäžã«ãªãããŒã«ãã£ãŠç»é¢ããã蟌ã¿äœéšãæªããªã£ãŠããŸããã ããã§ãããããã¹ã±ã«ãã³ã¹ã¯ãªãŒã³ãçšæããŠé«ãã確ä¿ããããšã§ãŠãŒã¶äœéšãæãªããªãããã«å¯Ÿå¿ããŸãããïŒAMPéçºè
ã®æ¹ããã®ã¢ããã€ã¹ïŒ ããã§è¡šç€ºãé
ããŠããŠãŒã¶äœéšã«åœ±é¿ãå°ãªãããŒãžã«ãªããŸããã ä»åŸã®æ¹é äžäŒ.comã§ã®ä»åŸã®AMPå±éã«ã€ããŠã¯ä»¥äžã®æ€èšãããŠããŸãã amp-storyã®æŽ»çšäºäŸãå¢ãã AMPäžã§jsãåãamp-scriptã䜿ã£ãã³ã³ãã³ãã®ãªããå ITP2.0ã«ãããã©ããã³ã°å¯ŸçïŒSafari察å¿ïŒãšããŠamppackagerãamp-toolbox-optimizerãªã©ã®äœ¿çšã«ããå¯Ÿå¿ digitalidentity.co.jp ãŸãšã AMPã®ã³ã³ããŒãã³ãã¯å®¹éçšæ³ãæèããŠäœ¿ãã®ãè¯ãããã ãšæããŸããã AMPããŒãžãšããŠã®ãµã€ãã®åœ¹å²ãèãã€ã€è¯è³ªãªãŠãŒã¶äœéšãšæµå
¥ãç²åŸã§ãããµãŒãã¹ããããããäœã£ãŠãããããšæããŸãã AMPãšèããšã¹ããã ãã®å°è±¡ã®ãããŸããã PCããŒãžãšããŠã®AMPãã³ã³ããŒãã³ããåå¥ã«shadowDOMãšããŠããŒãžã«åãå
¥ããããšãã§ããããšæŽ»çšã®å¹
ã¯ãšãŠãåºãã§ãã ä»åŸã®é²åãããç®ãé¢ããªãã§ããïŒ ææ¥ã¯ id:IganinTea ããã®ã C#ãšWindowsãã§ãïŒ
ãã®èšäºã¯äžäŒ.com ã¢ããã³ãã«ã¬ã³ããŒã®14æ¥ç®ã®èšäºã§ãã qiita.com ããã«ã¡ã¯ã id:kentana20 ã§ããäžäŒã§å®¿æ³ãµãŒãã¹ã®éçºãããŠããŸãã 仿¥ã¯äžæšæ¥ã®å€ã«å®æœããã€ãã³ããIkyu Frontend Meetupãã®æ§åãã¬ããŒãããããšæããŸããã€ãã³ãããŒãžã¯ãã¡ãã ikyu.connpass.com 幎æ«ã®å¿ããææã«ãããããããå€ãã®æ¹ã«ãå¿åã»ãåå ããã ããŸããã ä»åã®ã€ãã³ãã®ãã£ãã éå»ã«2床ãäžäŒã§ã¯ããã¯ç³»ã€ãã³ãããã£ãŠããŸããããããŒã¡ãŒã¡ãŸãã€ãã³ããããããªãããšæã£ãŠãããšãã«ã id:supercalifragilisticexpiali ãæžãã user-first.ikyu.co.jp ãèŠãä»ç€Ÿã®ãšã³ãžãã¢ã®æ¹ãããæ
å ±äº€æããŸãããããšè€æ°åãåãããäŸé Œããã£ãã®ã§ãã€ãã³ãã«ããŠããŸããããšæã£ãŠä»åã®Meetupéå¬ã«è³ããŸããã ã»ãã·ã§ã³ã®å
容 ä»åã®ã€ãã³ãã§ã¯ãäžäŒ.com / äžäŒã¬ã¹ãã©ã³ã§ã®ããã³ããšã³ãéçºããããŒãã«3æ¬ã®ã»ãã·ã§ã³ãè¡ããŸããã ã»ãã·ã§ã³1: ãJavaScript/Vue.js ã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãã¥ãŒãã³ã°ã 1æ¬ç®ã®ã»ãã·ã§ã³ã¯å®¿æ³ãµãŒãã¹ã®ãšã³ãžãã¢ã§ãã id:ryo-utsunomiya ãJavaScript/Vue.jsã®ããã©ãŒãã³ã¹ãã¥ãŒãã³ã°ã«ã€ããŠã話ããŸããã ryo-utsunomiya ã«ããJavaScript/Vue.jsã®ããã©ãŒãã³ã¹ãã¥ãŒãã³ã°ã®äºäŸ äžäŒ.comã¢ãã€ã«Webã®ããã«ããŒãžãé«éåããäºäŸãããšã« Lighthouse, Calibreã䜿ã£ãããã©ãŒãã³ã¹ã®èšæž¬ 忥ä»ç€Ÿã®ããŒãžãåèã«ããç®æšèšå® JavaScriptã®ãã¥ãŒãã³ã°ã®ãã€ã³ã ãªã©ãã話ããŸããã ã»ãã·ã§ã³2: ãimgixå°å
¥ã§ç»åæé©åãšãµã€ãã¹ããŒãæ¹åã 2æ¬ç®ã®ã»ãã·ã§ã³ã§ã¯ãç»åã®æé©åã«ãããã¥ãŒãã³ã°ã®äºäŸã id:akasakas ãã話ããŸããã akasakasã«ããç»åæé©åäºäŸã®ã»ãã·ã§ã³ ããšããšèªç€Ÿ(Image Magick)ã§ç»åã®ãªãµã€ãºãåãæããªã©ã®å å·¥åŠçãããŠãããšããããç»åæé©å/é
ä¿¡ã®SaaSã§ããimgixãå°å
¥ããŠæé©åããã話ã å°å
¥åã®èª²é¡æŽç æè¡éžå®ã®èгç¹ãšimgixã«æææ±ºå®ãããã€ã³ã imgixã®åªããŠããç¹ å°å
¥åŸã®å¹æ ãªã©ã®æµãã§ã話ããŸãããèª²é¡ â 解決ã®ããã®ææ³ â 解決åŸã®ææãé ã远ã£ãŠèªãããŠããŠããšãŠãããããããã»ãã·ã§ã³ã§ãããã»ãã·ã§ã³ã®äžã§ãèªãããŠããŸããããäžäŒãæäŸãããµãŒãã¹ã«ãããŠç»åã¯ãšãŠãéèŠã§ããŠãŒã¶äœéšã«å€§ããªåœ±é¿ãäžããéšåãªã®ã§ãæé©åã«ãã£ãŠãŠãŒã¶äœéšãåäžã§ããããšã¯æ¬åœã«è¯ãææã«ã€ãªãã£ããšæã£ãŠããŸãã ã»ãã·ã§ã³3: ãäžäŒ.comã¬ã¹ãã©ã³ã®ã¹ããŒããã©ã³æ€çŽ¢ããŒãžãSPAã«ãªããŸããã 3æ¬ç®ã®ã»ãã·ã§ã³ã§ã¯ãã€ãã³ãã®ãã£ããã«ãªã£ãããã°ãšã³ããªãããšã« id:supercalifragilisticexpiali ãäžäŒã¬ã¹ãã©ã³ã¢ãã€ã«Webã®ã¬ã¹ãã©ã³æ€çŽ¢ããŒãžãSPAã«ããäºäŸããã話ããŸããã ããã£ãšäœ¿ãããããããµã¯ãµã¯åãããã«ããšãããããã¯ãã®ããŒãº SEOãèœãšããªãããã«ãšããé客é¢ã®ããŒãº Atomic Designãæèããã³ã³ããŒãã³ãæåèšèšãåãå
¥ããŠçç£æ§ãäžããããšããæè¡é¢ã§ã®ããŒãº ãšãã£ãå€è§çãªèгç¹ãã Vue.js, Nuxt.js, ITCSS ãå°å
¥ããäºäŸã现éšãŸã§äžå¯§ã«ã話ããŸããã å
å®¹ãæ¿ããåå è
ã®ã¿ãªãããçå£ã«èããŠãã ãã£ãŠããŠããšãŠãè¯ãã»ãã·ã§ã³ã§ããã ããã«ãã£ã¹ã«ãã·ã§ã³ / æèŠªäŒ 3æ¬ã®ã»ãã·ã§ã³çµäºåŸã¯ããŒã«çæã«ããã«ãã£ã¹ã«ãã·ã§ã³ãšæèŠªäŒãè¡ããŸããã äºåã«åå è
ã®æ¹ããããã ããŠãã質åãããŒã¹ã«ã¹ããŒã«ãŒãšè©±ããããåå è
ããåœæ¥åºã質åã«çããQ&A圢åŒã§é²è¡ããŸããã ç·šéåŸèš éå»2åã¯ä»ç€Ÿãšååã§å®æœããMeetupã€ãã³ãã§ããããä»åã¯äžäŒåç¬ã§ã®éå¬ã ã£ãã®ã§ãåå è
ãéãŸãããã€ãã³ãã«æºè¶³ããã ãããããªã©äžå®ãªç¹ã¯ãããŸãããããŸããŸãæºè¶³ããã ããããã§ãéå¬ããŠããã£ãã§ãã ãããããã£ããç¶ç¶çã«æ¹åãç¶ããŠãããäœå¶ãã§ããŠããã®çŸšãŸããã #ikyu_dev — Yoshiaki Itakura (@ita_3y) 2018幎12æ12æ¥ é¢çœãã£ãã§ã #ikyu_dev — ãããããïŒ çã®é床 (@gyagyagyaxtu) 2018幎12æ12æ¥ è²ã
æçãªè©±ãèããŠè¯ãã£ãã§ãïŒããããšãããããŸããïŒ #ikyu_dev — ããŒã (@Rw_taaaka) 2018幎12æ12æ¥ äžäŒ.com / äžäŒã¬ã¹ãã©ã³ãšãã«ããŸã ãŸã ããã³ããšã³ãéçºã§ããããããšã¯ããããããã®ã§ãç¶ç¶çã«ã³ãã³ãæ¹åãç¶ããŠãŠãŒã¶ã«ãšã£ãŠäœ¿ãããããµãŒãã¹ãæäŸããŠãããããšæããŸãã ææ¥ã¯ã¢ããã³ãã«ã¬ã³ããŒã¯ãäŒã¿ãæåŸæ¥16æ¥ã¯ id:yakisoba6318 ã«ããã äžäŒ.comã«ãããAMPå°å
¥ã«ã€ããŠãã§ãããæ¥œãã¿ã«ïŒ
ãã®èšäºã¯äžäŒ.comã¢ããã³ãã«ã¬ã³ããŒ2018ã®13æ¥ç®ã®èšäºã§ãã qiita.com ããã«ã¡ã¯ã ä»å¹Žã®7æã«å
¥ç€Ÿããã¬ã¹ãã©ã³äºæ¥éšã®æž¥çŸã§ãã äžäŒ.com ã¬ã¹ãã©ã³ã«ãŠããã³ããšã³ããšããã¯ãšã³ãã®éçºãè¡ãªã£ãŠãããŸãã ãã®èšäºã®æŠèŠ åºèããŒãžãSPAåããèæ¯ åºèããŒãžãªãã¥ãŒã¢ã« ãã©ã³è©³çްããŒãžã®SPAå Vue.js ã«ããã¢ãŒãã«ã®å®è£
æ¹é äºåããŒã ã¢ãŒãã«ã®éé URLãåçã«çæãã Fastly ã§ã®æ®µéçãªãªãŒã¹ Fastly ã«ã€ã㊠VCL ã®èšå® Fastly Fiddle ã«ãããã¹ã ä»åŸã®å±æ åºèããŒãžãSPAåããèæ¯ åºèããŒãžãªãã¥ãŒã¢ã« ç§ãäžäŒã«å
¥ç€Ÿãã1ã¶æåãåºèã®æ
å ±ã¯è€æ°ã®ããŒãžã«ãŸããã£ãŠããŸããã å
·äœçã«ã¯ãåºèã®ããŒãžã¯ãã©ã³äžèЧãåºèæ
å ±ãã¢ã¯ã»ã¹ããããªã©ã®æ
å ±ãå¥ã
ã®ã¿ãã«åãããŠãããããŒãžé·ç§»ãå¿
èŠã§ããã ããããrestaurant2 *1 ãžã®ãªãã¥ãŒã¢ã«ãšå
±ã«ãSPAãšããŠçãŸãå€ãã£ãã®ã§ããã Before: æ§åºèããŒãž After: æ°åºèããŒãž ãã©ã³è©³çްããŒãžã®SPAå ãã®åŸå
¥ç€Ÿããç§ã¯ãŠãŒã¶äœéšãããã«åäžãããããã«ã ç¬ç«ããŠãããã©ã³ã®è©³çްããŒãžã®ã¢ãŒãã«åãæ
åœããŸããã ããã«ãããåºèããŒãžå
ã§å®çµã§ããç¯å²ãåºããããäºçŽãããããUIã«ãªããŸããã â»çŸåšãäžèšã®ãã©ã³è©³çްããŒãžã¯åããŠããŸãããåŸè¿°ããããã«ã¢ãŒãã«ãžç§»è¡äºå®ã§ãã Before: ãã©ã³è©³çްããŒãž After: ãã©ã³è©³çްã¢ãŒãã« ä»åã¯ãã®ã¢ãŒãã«åã®å®è£
ã«ã€ããŠç°¡åã«ã話ãããšãšãã«ã 段éçãªãªãŒã¹ã®åãçµã¿ã«ã€ããŠã玹ä»ããŸãã Vue.js ã«ããã¢ãŒãã«ã®å®è£
æ¹é äžäŒã¬ã¹ãã©ã³ã®ããã³ããšã³ãéçºã§ã¯ Vue.js ã䜿ãããŠããŸãã ã¢ãŒãã«ã®å®è£
ãVue.jsã§å¶åŸ¡ããŠãããä»åã¯ãã®åºæ¬çãªå®è£
æ¹éã玹ä»ããŸãã 倧ãŸããªåŠçã¯ä»¥äžã®ãšããã§ãã // åºèããŒãžã® Vue ãã¡ã€ã« <template> <!-- ç¥ --> <object-plan-item @mouseenter= "preloadPlanDetail" @click:plan= "openPlanDetail" /> <composition-plan-detail-modal :activated= "showPlanDetail" @update:activated= "onClose" /> </template> export default { // ç¥ data() { return { showPlanDetail: false } ; } , methods: { openPlanDetail(plan) { // â ã¢ãŒãã«ã®ééåŠç this .showPlanDetail = true ; // â¡URL ã®åççæ global.history.pushState( null , '' , this .planDetailUrl(plan)); } , onClose() { // â ã¢ãŒãã«ã®ééåŠç this .showPlanDetail = false ; // â¡URL ã®åççæ global.history.pushState( null , '' , `/$ {this .restaurant.id } /`); } , preloadPlanDetail(plan) { ã // â¢ãã©ã³è©³çްæ
å ±ã®å
èªã¿ } , planDetailUrl(plan) { // URL ãçæãè¿åŽãã } , } } <object-plan-item> ãåãã©ã³é
ç®ã®ã³ã³ããŒãã³ãã <composition-plan-detail-modal> ãã¢ãŒãã«ã®ã³ã³ããŒãã³ãã§ãã â ã¢ãŒãã«ã®ééåŠç ã¢ãŒãã«ã®è¡šç€ºç¶æ
㯠showPlanDetail ãå®çŸ©ããŠããã® boolean å€ã§ç®¡çããŠããŸãã åçŽã§ããããã©ã³ã®ã詳现ã»äºçŽããã¿ã³ãã¯ãªãã¯ããããšãã« showPlanDetail = true , ã¢ãŒãã«ã®èæ¯ãã¯ãªãã¯ããããšãã« showPlanDetail = false ãšãªãã衚瀺ãåãæ¿ãããŸãã â¡URL ã®åççæ ã¢ãŒãã«ãéãããšãã« URL ãåçã«çæããŠããŸãã History API ãå©çšããŠã global.history.pushState(null, '', this.planDetailUrl({ plan, time })); ãšããããšã§ã¢ãŒãã«ãéãããšãã« URL ãæŽæ°ãããå±¥æŽã«ã远å ããããã«ããŠããŸãã ã¢ãŒãã«ãéãããšãã¯ã global.history.pushState(null, '', `/${this.restaurant.id}/`); ãšããŠåºèããŒãžã® URL ã«æ»ããŸãã â¢ãã©ã³ã®è©³çްæ
å ±ãå
èªã¿ ãã©ã³ã®è©³çްæ
å ±ãå
ã«èªã¿èŸŒãåŠçãæžããŠããŸãã å®éã«ã¯ <object-plan-item> ãã mouseenter ã®ã€ãã³ãã emit ããã preloadPlanDetail ãçºç«ãããŸãã ãŠãŒã¶ãããããšããã©ã³äžèЧã®é
ç®ãããŠã¹ãªãŒããŒãããšåæã«ããªããŒããèµ°ãã®ã§ ã¢ãŒãã«ãéãããšãã«ã¯ã·ãŒã ã¬ã¹ã«ãã©ã³è©³çްã衚瀺ãããäœéšãæäŸã§ããŸãã (â»ããŒãã£ã³ã°ãå®äºããŠããªãå Žåã¯ããŒãã£ã³ã°ç»åã衚瀺ãããŸã) å¿è«ä»ã«ãåŠçã¯ãããŸããã以äžãã¢ãŒãã«åã®å€§ãŸããªå®è£
ãšãªããŸãã Vue.js ã䜿ãããšã§ã¢ãŒãã«ã®ééç¶æ
ããå
èªã¿ãããã©ã³ã®æ
å ±ãã¢ãŒãã«ã«åãæž¡ããã®ã¯äŸ¿å©ãªç¹ã§ããã Fastly ã§ã®æ®µéçãªãªãŒã¹ ä»åã¢ãŒãã«åããããŒãžã¯äºçŽå°ç·ã«çŽçµããŠãããšããããšãããã ãªãªãŒã¹åœåã¯ç¹å®ã®åºèã®ã¿ã«éå®å
¬éããŸããã ãã®éå®å
¬éã« Fastly ã䜿ããŸããã Fastly ã«ã€ã㊠äžäŒã§ã¯ãªããŒã¹ãããã·ãšã㊠Fastly ãå©çšããŠããŸãã Fastly ã¯èšå®èšèªã® VCL ãæžãããšã§ãªãã€ã¬ã¯ãã®åŠçããã¬ã¹ãã³ã¹ã®å¶åŸ¡ãç°¡åã«è¡ãããšãã§ããŸãã ä»åã¯ãç¹å®ã®åºèããŒãžã«ã¢ã¯ã»ã¹ãããšãã®ã¿ã ?modal_enabled=1 ãšããã¯ãšãªãã©ã¡ãŒã¿ãä»äžããããã« VCLã®èšå®ãè¡ããŸããã ãããŠããã®ãã©ã¡ãŒã¿ãä»äžãããŠããå Žåã¯ã¢ãŒãã«ãéãããã«ã¢ããªã±ãŒã·ã§ã³åŽã§ãã³ããªã³ã°ããŸããã æµããšããŠã¯äžèšã®ãããªã€ã¡ãŒãžã§ãã ç¹å®åºèã®URLã«ã¢ã¯ã»ã¹ãã https://restaurant.ikyu.com/( åºèID) Fastly ã§ ?modal_enabled=1 ãä»äžãããURLã«ãªãã€ã¬ã¯ãããã https://restaurant.ikyu.com/( åºèID)?modal_enabled=1 ?modal_enabled=1 ãååšãããšãã®ã¿ã¢ããªã±ãŒã·ã§ã³åŽã§ã¢ãŒãã«ãéã ã¡ãªãã Fastly ã§ã®æ®µéçãªãªãŒã¹ã®ã¡ãªãããšããŠã¯äžèšã®ãããªãã®ããããŸãã éå®ãªãªãŒã¹ãã§ãã ä»åã®äž»ç®çã§ãããURLã«å¿ããéå®ãªãªãŒã¹ãå¯èœã§ãã Fastly ã®ãããã€ãé«é VCL ã®æ¬çªç°å¢ãžã®åæ ããCIã®ãã¹ããå«ããŠ2åã»ã©ã§å®äºããŸãã åãæ»ãã容æ äžèšã®ãããã€ãé«éã§ããããšãšé¢ä¿ããã®ã§ããããªã«ããã©ãã«ããã£ãå Žåã®åãæ»ãã容æã§ãã ã¢ããªã±ãŒã·ã§ã³ã®ãªãªãŒã¹ã¯20åçšãããã®ã§ããã¯ããããããã€ã³ãã§ãã ãããŸã§ä»ã®ææ³ã§ã®æ®µéçãªãªãŒã¹ã¯è¡ãããŠãããã®ã®ã Fastly ã䜿ã£ã段éçãªãªãŒã¹ã¯åããŠã®è©Šã¿ã§ããã VCL ã®èšå® ããŠãå®éã« VCL ã§èšå®ããå
容ãã玹ä»ããŸãã(å¿
èŠã«å¿ããŠå€æ°åçãå€ããŠããŸã) table test_ids { "100000": "true", } sub vcl_recv { #FASTLY recv if (req.url.qs !~ "modal_enabled=" && req.url.path ~ "^\/(\d{6})" && table.lookup(test_ids, re.group.1) ) { error 700; # å
éšçã«error statusãé£ã°ãããšã§ãªãã€ã¬ã¯ããè¡ã } } sub vcl_error { #FASTLY error if (obj.status == 700) { set obj.http.Location = "https://" req.http.host req.url.path "?modal_enabled=1" if(req.url.qs == "", "", "&" req.url.qs); set obj.status = 307; set obj.response = "Temporary Redirect"; return (deliver); } } table ã®é
ç®ã§ç¹å®åºèã®IDãæå®ããŠããŸãã ããã§æ°ã«ãªã£ãæ¹ãããããç¥ããŸãããã VCL ã®èšå®ã§ã¯å
éšçã« error status ãé£ã°ãããšã§ãªãã€ã¬ã¯ããè¡ããŸãã Fastly Fiddle ã«ãããã¹ã ãã® VCL ã®èšå®ãè¡ãã«ãããã Fastly Fiddle ãšãããµãŒãã¹ãå©çšããŸããããã㯠VCL ã®ã³ãŒãããªã³ã©ã€ã³ã§ç°¡åã«ãã¹ãã§ãããµãŒãã¹ã§ãã Fastly Labsãå®éšçã«éçšããŠãã ããã§ãã Fastly Fiddle ã®ç»é¢ Fastly Fiddle ã¯å®è¡ããã³ãŒããä»ã®ãŠãŒã¶ãšå
±æããããšãã§ããŸãã äžèšã®ã³ãŒãã ãµã³ãã« ãšããŠçšæããŸããã ããŒãžã«ã¢ã¯ã»ã¹ããããå³äžã®[RUN]ãã¿ã³ãæŒããŠã¿ãŠãã ããã table test_ids ã«å«ãŸããIDã«å¯Ÿå¿ããURL(/100000)ã«å¯ŸããŠãªã¯ãšã¹ããéããšããªãã€ã¬ã¯ããçºçããããšãããããŸãã ãªãã€ã¬ã¯ãçµæ å察ã«ã test_ids ã«å«ãŸããªãIDã«å¯Ÿå¿ããURL(äŸãã° /200000)ã«ãªã¯ãšã¹ããéã£ãŠããªãã€ã¬ã¯ããããŸããã æ¯é Send a request ã®é
ç®ã /100000 ãã倿ŽããŠéãã§ã¿ãŠãã ããã ãã®ããã«ããŠãFastly ã«ããç¹å®åºèã®ã¿ã®æ®µéçãªãªãŒã¹ãã§ããããã«ãªããŸããã ä»åŸã®å±æ ä»åã®ã¢ãŒãã«å®è£
ã§åºèã®ããŒãžã®SPAåãé²ã¿ãŸããã ããããã¢ãŒãã«ã®URLã«çŽæ¥ã¢ã¯ã»ã¹ãããšãã¯ãæªã 以åã®ãã©ã³è©³çްããŒãžã«é·ç§»ããããã«ãªã£ãŠããŸãã ä»åŸã¯ãã®ãããªå°ç·ã«ãã¢ãŒãã«ãéãããã«å¯Ÿå¿ããŠãããŸãã ãŸããä»å Fastly ã§ã®æ®µéçãªãªãŒã¹ã®ä»çµã¿ãæŽã£ãã®ã§ãä»åŸã®æ©èœè¿œå ã§ã©ãã©ã掻çšããŠãããããšæããŸãã ææ¥ã¯ id:kentana20 ããã® 12/12 Ikyu Frontend Meetup éå¬ã¬ããŒã ã§ãïŒ ãæ¥œãã¿ã«ïŒ *1 : æ°ããã¢ãŒããã¯ãã£ã«ããäžäŒ.com ã¬ã¹ãã©ã³ã®Webã¢ããªã±ãŒã·ã§ã³ãæãã
ãã®èšäºã¯äžäŒ.comã¢ããã³ãã«ã¬ã³ããŒ2018ã®11æ¥ç®ã§ãã qiita.com ã¯ããã« ãã¶ã€ããŒãšèããŠãçããã¯ã©ã®ãããªäººãæ³åããŸããïŒ ãèŠãç®ãçŸãããã£ãããäœãã人ãããããžã¥ã¢ã«ãã¶ã€ã³ã®å°éå®¶ããšããã€ã¡ãŒãžãæãããŠããæ¹ãå€ãã®ã§ã¯ãªãã§ããããïŒ ãã¶ã€ããŒã®ã¢ãŠããããã ããèŠãã°ãã®éãã§ãããã¢ãŠããããã«è³ããŸã§ã®ãã¶ã€ã³ã®èãæ¹ ãåãçµã¿æ¹ã圹å²ãããæ°å¹Žã§å€ãã£ãŠããŠããŸãã 以åã¯ãæ
å ±ãæŽçããŠè²ã圢ã䜿ãããªãããžã¥ã¢ã«ãã¶ã€ã³ããã¶ã€ããŒã®äžå¿çãªæ¥åã ãšèããããŠããŸããã ããããWebãã¶ã€ã³ã®æšæºåãé²ã¿ãé¡äŒŒãµãŒãã¹ã®ä¹±ç«ãå¢ãããŠãŒã¶ãŒãã奜ãŸãããµãŒãã¹ãã©ãããéèŠãããããã«ãªããŸããã ãã广çãªãã¶ã€ã³ãå®çŸããããã«ãäºæ¥æŠç¥ããµãŒãã¹ã®çŸç¶ãããŒã±ããããŒãºã«ç®ãåãããã¶ã€ã³ã«æŽ»ããããšããåããæŽ»çºã«ãªããŸããã ãšã¯ãããçå±ã¯çè§£ã§ããŠãå
·äœçã«äœãããã°è¯ãã®ãããããã«ãããšæããŠããæ¹ãå€ãã¯ããããã§ä»åã¯ãäžäŸãšããŠç§ãäžäŒã®ãã¶ã€ããŒãšããŠåãçµãã§ããããšãã玹ä»ããããšæããŸãã Index ïŒïŒ ããŒã³ããâãªã©ã®ã«ãŒã«ã¯æäœéã«ããŠéœåºŠèãã ïŒïŒ èªåãã¡ãç®æããã¶ã€ã³ã®æ¹éãææåãã ïŒïŒ ãã¶ã€ããŒãèªç±ã«çºæ£ããå°ãå
ã®å°æ¥ã«ã€ããŠèããå Žãèšãã ïŒïŒ ãã¶ã€ã³ã«åãæããåã«èãã ããŒã³ããâãªã©ã®ã«ãŒã«ã¯æäœéã«ããŠéœåºŠèãã äžäŒã®ã¬ã¹ãã©ã³äºæ¥ã®ããŒã³ãããŒã§å®çŸ©ããŠããã®ã¯ãè€æ°ã®ããŒãžã§ç»å Žããåºæ¬çãªUIããŒããšã¿ã€ãã°ã©ãã£ã®åºæºã®ã¿ã§ãã ããŸã詳现ãŸã§å®çŸ©ãããšã«ãŒã«ã«çžãããŠèããæ©äŒã倱ãããå¯èœæ§ããããŸãããããã¥ã¡ã³ãã®æŽåã«æéããããã®ãåŸçã§ã¯ãããŸããã æ¢ããŠã«ãŒã«ã決ãããããç¶æ³ã«å¿ããŠãã¶ã€ããŒãèªåã®é ã§èããæè¯ãšæããã®ãç»é¢ã«åæ ãããŠå¹æãèŠãŠã¿ãã 工倫ã§ããäœå°ãæ®ãããšã§ãµãŒãã¹æ¹è¯ã®ææ¡ããããããªããå€åã®ä¿é²ã«ã€ãªãããšèããŸããã ãã ããéœåºŠãã¶ã€ã³ããããšããŠãŒã¶ãŒã®ããã«ããµãŒãã¹ã®ããã«ããªããªãèŠçŽ ã«ã€ããŠã¯Vueã³ã³ããŒãã³ãã«å®çŸ©ããŠããã¶ã€ã³ãã³ãŒãã£ã³ã°ã®å¹çåãšãµãŒãã¹ã®äœ¿ããããã®äž¡æ¹ã®å®çŸãç®æãããšã«ããŸããã ç®æããããã¶ã€ã³ã®æ¹éãææåããŠå
±æãã ãã¶ã€ã³ãããŠããŠãã°ãã°é ãæ©ãŸããã®ã¯æ£è§£ãè€æ°ããããšã§ãã ãã¶ã€ã³ã®åãæªãã¯å€æè»žã«ãã£ãŠå€ãããŸããã人ã«ãã£ãŠç°ãªãææ³ãæã¡ãŸãã ããŒã ã§ãã¶ã€ã³ãèããå Žåãåã
ã«å
šãç°ãªãã³ã³ã»ããã§èããŠããŸãããµãŒãã¹å
šäœã§ã®äžè²«æ§ãæãªãããããšããããŸãã ããšãã£ãŠãããŒã³ããâãå
å®ãããã°è¯ãããšèšããšåè¿°ã®éããããã§ã¯ãªããšæã£ãŠããŸãã ããã§ããµãŒãã¹ãã¶ã€ã³ã³ã³ã»ãããšãããã®ãææåããããšã«ããŸããã ã«ãŒã«ã§ã¯ãªãã³ã³ã»ãããã€ãŸãæ¹åæ§ã§ãã å
·äœçã«ããããããããããããæžãããã§ã¯ãªããå®çŸãããæ¯è²ãïŒã€ïœïŒã€ã®é
ç®ã«èœãšã蟌ã¿ãèªåãã¡ãäœã£ãŠãããããã¯ãã®ç®æšãšããŠæ®ããŸããã ãããŠããã®ç®æšã«ãããããŠããªãç®æã«ã€ããŠãããããããã©ãã ããïŒããããããæ¹æ³ãããããããã©ããã£ãŠé²ããããïŒããšãã£ãããšããæ¬¡é
ã§ç޹ä»ãããUI/UXãã¶ã€ã³èªãå Žãã§è©±ãåã£ãŠããŸãã äžäŒã¬ã¹ãã©ã³äºæ¥ã®ãµãŒãã¹ãã¶ã€ã³ã³ã³ã»ããïŒæç²ïŒ 楜ãããäºå®ããªããŠãèŠãããªããµãŒãã¹ã§ããããš æçã§ç®çãéæã§ãããµãŒãã¹ã§ããããš çŽæçã«æäœãã§ããèããå¿
èŠããªããµãŒãã¹ ã·ã¹ããããã¯ã«ãªãããã人éå³ããããµãŒãã¹ ãã¶ã€ããŒãèªç±ã«çºæ£ããå°ãå
ã®å°æ¥ã«ã€ããŠèããå Žãèšãã ç®åã®ã¿ã¹ã¯æ¶åã§ãã£ãšããéã«æ°ãæãéããŠããŸã£ãããšããçµéšã¯ãããŸãããïŒ ãŸããèªåã®èããæ£ãããããããææ¡ããŠãè¯ããã®ããšèºèºããŠããŸãããšããããšã¯ãããŸãããïŒ ãããã®èª²é¡ãããŒã ã§è§£æ¶ããŠãå°ããªããšã§ãè¯ãã®ã§å®è¡ãç©ã¿éããŠããããããšããæ³ããããUI/UXãã¶ã€ã³èªãå ŽããšããããŒãã£ã³ã°ã宿œããããšã«ããŸããã é±ã«äžæéã仿±ããŠããã¿ã¹ã¯ããé¢ããŠãããããã£ãŠããããããšããã£ãŠã¿ããããšã«ã€ããŠèããèªç±ã«è©±ãããã®æéã§ãã ææ¡ããå
容ããªãã§ãããã°è¯ãããã§ã¯ãããŸããããçãã®ãªãããšãè¡ååã«ããããèããããŠãæå³ããããŸããã ãããŠæãé¿ããã¹ãã¯ãäœãããªãããšãã§ãã äœãããªããã°æ¥çžŸã¯äœäžããŠãããŸãã ãã»ã©çå€ããªããšã§ãªãéãããŸããã£ãŠã¿ãããã£ãŠã¿ãçµæãèžãŸããŠæ¬¡ã®æã¡æãèããã ãã®ç¹°ãè¿ãããµãŒãã¹æ¹åã«ã¯äžå¯æ¬ ã§ãã ãã¶ã€ã³ã«åãæããåã«èãã ãããããæ©èœãä»ãããããç»é¢ãã¶ã€ã³ããã ããããšèšãããæã«ããããªããã¶ã€ã³ããŒã«ã«åãã£ãŠããŸãã®ã¯é©åã§ã¯ãããŸããã ãã®åã«ããŸãã¯äŒç»è
ã®è©±ã«è³ãåŸããå®çŸãããããšãææ®µãçŸæç¹ã§ã®ä»®èª¬ããªã¹ã¯ãªã©ãæžãåºããåææ
å ±ãæŽçããŸãã ãããŠããããã®åæãå
ã«ã¿ãŒã²ããã®æ·±æããããŠãããŸãã ããŒã¿ãããããããšãšãããŒã¿ããã¯ããããªãäžç¢ºããªããšã«åããŠãŸãšãããšè¯ãã§ãããã ãã¢ãªã³ã°ãããŒã¿è§£æãä»ç€Ÿåæã®äœæ¥ã¯å¿
ããããã¶ã€ããŒãæ
åœããå¿
èŠã¯ãããŸããã èªåã§ã§ãããªãèªåã§ããã°è¯ãã§ãããã§ããªãå Žåã«ã¯åŸæãªäººã®ååãåŸãŠãè¯ããšæããŸãã éèŠãªããšã¯äºå®ãšå¯èœæ§ããã£ãããšææ¡ããããšã§ãã äžéããŸãšãçµããããããã€ãã®ã¿ãŒã²ããã°ã«ãŒãã®ãŠãŒã¶ãŒåãæ³åã§ããããã«ããŠããããããã¶ã€ã³ã«åãçµã¿ãŸãã ãã®ããã»ã¹ãèžãã æãšèžãã§ããªãæãšã§ããã¶ã€ã³ãææ¡ããéã®èª¬åŸåãèªä¿¡ããææ¡å
容ãå€ããã¯ãã§ãã å€å°æéã§ããã®ããã»ã¹ãèžãã§äºæž¬ãã宿œåŸã«ã©ããªã£ãã®ããããŠããŠãšããŠèç©ãããšãã¢ã€ãã¢ã®åŒãåºããå¢ããããšæããŸãã ãããã« ãããã ã£ãã§ããããïŒ ããããããã§ããïŒããšæãå
容ãå€ãã£ããšæããŸããã13幎éECãµã€ãã®ãã¶ã€ã³ã«æºãã£ãŠããŠæ°ä»ããã®ã¯ãé£ããèããå¿
èŠã¯ãªããšããããšã§ããã ã·ã³ãã«ã«èãããåœããåã®ããšãåœããåã«ã¡ãããšãã£ãŠã¿ãçµæãèŠããŠããããšãå€ã
ãããŸãã å°ãã§ãåèã«ãªãã°å¹žãã§ãã æåŸãŸã§ãèªã¿ããã ããããããšãããããŸããã æ¬¡åã¯@atsumim ã® ããã©ã³è©³çްããŒãžã®ã¢ãŒãã«åã Fastly ã§æ®µéçãªãªãŒã¹ãã話ãã§ãããæ¥œãã¿ã«ïŒ
ãã®èšäºã¯äžäŒ.comã¢ããã³ãã«ã¬ã³ããŒ2018ã®10æ¥ç®ã§ãã qiita.com ããã«ã¡ã¯ãã¬ã¹ãã©ã³äºæ¥éšã®ææŸ€ã§ãã WEBã¢ããªã±ãŒã·ã§ã³ãšã³ãžãã¢ãšããŠããã³ã/ãµãŒããŒåããæ©èœéçºãè¡ã£ãŠããŸãã ä»åã¯äžäŒ.com ã¬ã¹ãã©ã³ã®æ§ã¢ããªã±ãŒã·ã§ã³ã®ããã³ããšã³ãéçºç°å¢æ¹åã«ã€ããŠã話ããŸãã â» ãã®èšäºã®å·çæç¹ã§ã¯ä»¥äžã®å
容㯠master ã«åã蟌ãŸããŠããŸãããååã®ããã³ããšã³ããšã³ãžãã¢ïŒã¬ãå¢ïŒããäœãææããã£ãã远èšããŸãã ãã®èšäºã®æŠèŠ äžäŒ.com ã¬ã¹ãã©ã³ã®æ§WEBã¢ããªã±ãŒã·ã§ã³ïŒä»¥äž restaurant1 ïŒã¯ãªããããã³ããšã³ããã«ããè¶
é
ãã Storybook ã®ãããªã¢ããªãšåãé¢ããããé«éã§ãã«ãã§ããç°å¢ãããã°ãã£ãšå¿«é©ã«éçºã§ããã®ã§ã¯ãªããïŒ Storybook ã ãš vue-devtools ã䜿ããªãã®ã§ Storybook ïŒã®æäœéã®æ©èœãæã€ïŒå°ããã¢ããªã±ãŒã·ã§ã³ãäœã£ãŠã¿ãã äžäŒ.com ã¬ã¹ãã©ã³ã®éçºç°å¢ æ°ã¢ãŒããã¯ãã£ãžã®ç§»è¡ç¶æ³ äœåºŠããã®ããã°ã§ãåãäžããŠããŸãããçŸåšïŒ2018幎12æïŒãäžäŒ.com ã¬ã¹ãã©ã³ã¯æ°æ§ãµãã€ã®WEBã¢ããªã±ãŒã·ã§ã³ã䞊è¡ãã圢ã§éçšãããŠããŸãã å€ããã皌åããŠãã VBScript ã§æžãããã¢ããªã±ãŒã·ã§ã³ã¯ restaurant1ããªãã¥ãŒã¢ã«åŸã® Python ã§æžãããæ°ããã¢ããªã±ãŒã·ã§ã³ã¯ restaurant2 ãšåŒã°ããŠããŸãã çã
ãš restaurant2 ãžã®ç§»è¡ã¯é 調ã«é²ãã§ããŸãããäŸç¶ãšã㊠restaurant1 ã®äžã«ä¹ã£ãŠããéšåãå€ãæ®ã£ãŠããŸãã ããšãã°ã¹ããŒããã©ã³çã®åºèãããç»é¢ã¯æ©èœè¿œå ã®æ©äŒãå€ãããŒãžã§ããããŸã restaurant2 ãžã®ç§»è¡ãå®äºããŠããŸããã æ°ã¢ãŒããã¯ãã£ã ããè§Šãã°OKããšããç¶æ
ãŸã§ã¯ãŸã å°ããããããã ãšããã®ãçŸç¶ã§ãã restaurant1 ã®ããã³ããšã³ãã«ã€ã㊠ããŠã"ã¬ã¬ã·ãŒ"ãªã©ãšèšã£ãŠããŸããŸããããå®ã¯ããã³ããšã³ãã«éã£ãŠèšãã°æ§ã¢ããªã±ãŒã·ã§ã³ããããŸã§å€ãã¯ãããŸããã jQueryã§ãŽãªãŽãªæžãããããŒãžããããŸãããäž»èŠããŒãžã«é¢ããŠã¯ ES2015+ ãš Vue.js ã§éçºã§ããç°å¢ãæŽã£ãŠããŸãã restaurant2 ã®ãã«ãã«ã®ã³ãŒãã«æ¯ã¹ããšè¥å¹²èŠå£ãã¯ããŸããååã¢ãã³ã ãšèšã£ãŠããã§ãããã åé¡ã¯ãããã³ããšã³ããã«ãã ãšãŠã€ããªãé
ã ããšã§ãã ãã«ãã«ãã«æéããããããšã«é¢ããŠè¯ããšããŠã watch ããŠãããšãã®å·®åãã«ãã 1åä»¥äž ããããŸããïŒCore i7 ã®éçºæ©ã§ïŒ é
ãåå ã¯ç¹å®ã§ããŠããªãã®ã§ããã ã¢ã»ããã®è¥å€§å ãããã Windows ã ãšãã«ããé
ãïŒ restaurant1 㯠ASP ã§æžãããŠããã®ã§ Windows å¿
é ã§ãïŒ ã»ãã¥ãªãã£ã®ããã«å
¥ããŠãããã¡ã€ã«ç£èŠãœããã®çžæ§ã®åé¡ ãªã©ããããããªå¯èœæ§ãèããããŸãã ããŠæ¬æ¥ã§ããã°æ ¹æ¬åå ãç¹å®ããŠè§£æ±ºããã®ãçã§ãããã©ãã«ãåé¡ã®åãåããããŸããããªãã®ã§å¥ã®è§£æ±ºæ¹æ³ãèããŠã¿ãŸãã restaurant1 ã« Storybook ãå°å
¥ããŠã¿ã ããŸãŸã§ã¯ãŠããããã¹ããæžããŠãã©ãŠã¶ã䜿ã£ãåäœç¢ºèªã®åæ°ãæžããããªãã¹ããã®åé¡ãæèããªããŠæžãããã«æ°ãã€ããŠããŸããã ããããã¯ãæ°èŠã®ã³ã³ããŒãã³ãã0ããäœããšãããã¶ã€ã³ã®åŸ®èª¿æŽãããéã¯ã©ãããŠããã«ãã®é
ããæ°ã«ãªããŸãã restaurant2 ã宿æ³ã®ãµã€ãã§ã¯ æ¢ã« Storybook ãå°å
¥æžã¿ã ã£ãããšãããã"éçºçšã® Playground ãšããŠ" restaurant1 ã«ã Storybook ãå
¥ããŠã¿ãããšè©ŠããŠã¿ãŸããã â» restaurant2 ã§ã¯"ãã¶ã€ããŒãšã®ååãã¹ã ãŒãºã«ãã" ãšããç®çã§ Storybook ãæŽ»çšãããŠããŸãã詳现ã¯ãŸããã€ãã Storybook ã§ååããïŒ ããŠåé ã§ãæžããŸãããçµå± Storybook ãå°å
¥ããããšã¯èŠéããŸãããçç±ã¯ vue-devtools ã䜿ããªãããã§ãã ä»åã¯ãã¶ã€ã³ã·ã¹ãã ãšããŠã§ã¯ãªããéçºçšã® Playground ãšã㊠Storybook ã䜿ãããã®ã§éçºããŒã«ãããŸãåããªãç¹ã¯èŽåœçãªåé¡ã§ãã ïŒæåã«æ°ä»ããããšããæãã§ããç§èªèº«ã¯ãããŸã§ããŸãã¡ãããš Storybook ã䜿ã£ãããšãªãã£ãã®ã§...ïŒ Github ã® issue ãèŠããšã¯ãŒã¯ã¢ã©ãŠã³ããããããã§ãã...ããã§ã«å°å
¥ã§ã ãã¶æ¶èããŠããŠããã以äžã® yak shaving ãããæ°ã¯èµ·ããªãã£ãã®ã§å¥ã®æ¹æ³ãæ€èšããããšã«ããŸããã ïŒè¿œèš: ç¡çããã§ãã iframe ãå¥ã¿ãã§éããš vue-devtools ã䜿ããŸãïŒ Storybook çžåœã®ã¢ããªã±ãŒã·ã§ã³ãäœã£ãŠã¿ã ããèããã°ä»åã®çšéã«éã£ãŠèšãã° Storybook ã®å
šæ©èœã䜿ããå¿
èŠã¯ãããŸãããããããããšã¯è³ã£ãŠã·ã³ãã«ã§ãã èŠæ±ã»ä»æ§ ã¢ããªã±ãŒã·ã§ã³ãšç¬ç«ããç°å¢ã§åäœç¢ºèªããªããã³ã³ããŒãã³ããéçºã§ãã vue-devtools ã䜿ãã LiveReload Mac ã§ãéçºã§ãã ã³ãŒãã®ã³ãããªã©ããã« restaurant1 ã®ã³ãŒãããã®ãŸãŸç¢ºèªã§ãã Storybook 颚ã«ã¹ããŒãªãŒãæžãã ãã®ä»æ§ãæºããå°ããªã¢ããªã±ãŒã·ã§ã³ãæžããŠã¿ãããšã«ããŸããã â» ãããŸã§ Playground ãšããŠäœ¿ããæçµç¢ºèªã¯ã¢ããªã±ãŒã·ã§ã³ã«çµã¿èŸŒãã§ããåæã ãŸãã¯äœ¿ãæ¹ããçŽ¹ä» stories.js ã«Storybook 颚ã®APIã§ã¹ããŒãªãŒã远å ããŠãã storiesOf( 'sample' ) .add( 'hello' , h => h( 'h3' , [ 'hello. this is my story.' ] , {} )); storiesOf( 'DatePicker' ) .add( 'select' , h => h(CustomDatePicker, { props: { value: '2018-12-01' } } )); restaurant1 å
ã§ yarn play ãå®è¡ããŠãµãŒããŒãèµ·å UIãããµãã®ã¯ã容赊ãã ãã...ã ããã ãã§ããããã¢ããªã±ãŒã·ã§ã³ãšåãé¢ãããç°å¢ã§ã³ã³ããŒãã³ããéçºããããšããããšã¯å®çŸã§ããŠããŸãã ãã ãããã€ã³ã ããããã¯èè¶³ãªæ°ãããŸããããã£ãããªã®ã§ãã ãããã€ã³ããã玹ä»ããŸãã ãšã«ããã·ã³ãã«ã«ïŒ æ°ããã©ã€ãã©ãªã远å ããªã Storybook like 㪠API 以äžã®3ç¹ãå¿ãããŠå®è£
ããŸããã ãã®ããŒã«ã䜿ã人ãããŒã«ã®æ©èœãæ¡åŒµããããšããŠã³ãŒããèªã人ã®è² æ
ãæå°éã«ãªãããã«æ°ãã€ããŠããŸãã ãŸãã¯äœããã³ãŒããå°ãããã·ã³ãã«ã«ãªãããã«å¿ãããŸããããŸãäžçšæã«æ°ããã©ã€ãã©ãªã远å ãããšãã§ã³ãŒããèªãã 人ã«è² æ
ããããŠããŸãã®ã§ restaurant1 ã«è¿œå æžã¿ã®ã©ã€ãã©ãªã®ã¿ã䜿çšããããšã«ããŸããã webpack-dev-server ã§ãã¹ã ä»åã¯ã¢ããªã±ãŒã·ã§ã³ã®äžã« playground ãã£ã¬ã¯ããªãäœãããã«é¢é£ãã¡ã€ã«ãæ ŒçŽãã webpack-dev-server ã§ãã¹ãããŠããŸãã ä»åã®ã¢ãããŒã·ã§ã³ãããã«ãã®é床æ¹åããªã®ã§ æ¬ã¢ããªã® webpack ã®èšå®ã䜿ãåãããšã¯ããã«æ°ãã playground 以äžã«æ°åè¡ã®ã·ã³ãã«ãªèšå®ãã¡ã€ã«ïŒ playground/webpack.config.js ïŒã远å ããŸããã // package.json { // ç¥ "scripts" : { // ç¥ "play" : "webpack-dev-server --config playground/webpack.config.js" } } // playground/webpack.config.js { // ç¥ devServer: { contentBase: path.resolve(__dirname, 'dist' ), port: 9000, } , } 9000çªããŒãã§ dist ãã£ã¬ã¯ããªã®å
容ããã¹ãããŸãã storiesOf 颿° storiesOf 颿°ã®å®è£
ã¯ããã ãã§ãã storiesOf ãš add ã§ãªããžã§ã¯ãã«ã³ã³ããŒãã³ããç»é²ããŠãããŸãã // playground.js const stories = {} ; // Component ãæ ŒçŽ const tableOfContents = {} ; // ããã²ãŒã·ã§ã³çš // TODO : HMR function storiesOf(title) { tableOfContents [ title ] = tableOfContents [ title ] || {} ; return { add(scenario, value) { const key = `$ { title } :$ { scenario } `; tableOfContents [ title ][ scenario ] = key; playground [ key ] = { render: value } ; return this ; } , } ; } const getStories = () => stories; const getTableOfContents = () => tableOfContents; export { storiesOf, getStories, getTableOfContents, } ; â» vue-play ã®å®è£
ãåèã«ãããŠããã ããŸããã github.com ãã¬ãã¥ãŒæ©èœ import { getStories } from './playground' ; export default { name: 'PlaygroundPreview' , data() { return { scenario: '' , stories: {} , } ; } , methods: { setScenario() { const hash = decodeURI( window . location .hash); this .scenario = hash.replace( '#' , '' ); } , } , computed: { current() { return this .stories [this .scenario ] ; } , } , created() { this .stories = getStories(); this .setScenario(); window .addEventListener( 'hashchange' , this .setScenario); } , render(h) { return h( this .current, [] , {} ); } , } ; ã¹ããŒãªãŒãšããŠç»é²ããã³ã³ããŒãã³ãã®ãã¬ãã¥ãŒéšåã§ãã URL ã®ããã·ã¥éšåã«ã³ã³ããŒãã³ãã®ããŒãå
¥ããããã«ããããã·ã¥ã®å€æŽã«ãã£ãŠãã¬ãã¥ãŒãããã³ã³ããŒãã³ããåãæ¿ããããã«ããŠããŸãã http://localhost:9000/#{ã¹ããŒãªãŒã®ã¿ã€ãã«}:{ã¹ããŒãªãŒã®å°èŠåºã} ä»åŸã®å±æ webpack ã®èšå®ãã¡ã€ã«ãå«ãã250è¡çšåºŠã®ã³ãŒãã§ãããŸã§ã®å
容ãå®çŸã§ããŸããã ã·ã³ãã«ãªå®è£
ã§æäœéããããããšã¯ã§ããããšæã£ãŠããŸãã WEBãã©ã³ãã®èªã¿èŸŒã¿ãã§ããŠããªã Vuex ãšé£æºããã³ã³ããŒãã³ãã®åäœç¢ºèªãã§ããªã DefinePlugin ã®å¯Ÿå¿ async/await ã䜿ã£ãŠããã³ãŒãã§ãšã©ãŒãåºãã®ã§ webpack ã®èšå®ãèŠçŽã UIãã€ã±ãŠãªã ãªã©ãã§ã«ããã€ã課é¡ã¯èŠã€ãã£ãŠããã®ã§ããããã¬ãŒã³ããŒã·ã§ã³ã ãã«è²¬ä»»ãæã€ã·ã³ãã«ãªã³ã³ããŒãã³ãã®éçºã§ããã°ååã«æŽ»çšã§ããããšæããŸãã å®ã¯ãã¢çšã«ããã€ãå®éã«äœ¿ãããŠããã³ã³ããŒãã³ãã远å ããããšæã£ãã®ã§ãããã»ãšãã©ã®äž»èŠã³ã³ããŒãã³ãã Vuex ã«äŸåããŠããŠããŸã远å ã§ããŸãã§ããã ããèšãããŠããããšã§ããããããã㊠Presentation Component ãš Container Component ã®åé¢ãéèŠã§ããã ããå°ããã©ãã·ã¥ã¢ããããŠãè¯ãããã§ããã° master ã«åã蟌ãããšæããŸãã
ãã®èšäºã¯äžäŒ.comã¢ããã³ãã«ã¬ã³ããŒ2018ã®9æ¥ç®ã§ãã qiita.com å°å
¥ç·š ã«ç¶ããéçšç·šã§ãã ãã2幎é RundeckãéçšããŠããŠçºçãããã©ãã«ãšãã®å¯ŸåŠã«ã€ããŠæžããŸãã â»ãã®èšäºã§èšåããRundeckã¯ããŒãžã§ã³2.6.9ã§ãã ãã©ãã«ã¯ãµãã€ãããŸããã ããŒã¿ããŒã¹ãé«è² è·ã«ãªãåäœãäžå®å®ã«ãªã£ã ãªãããžã§ããèµ·åããªã ããŒã¿ããŒã¹ãé«è² è·ã«ãªãåäœãäžå®å®ã«ãªã£ã åå ã¯è€æ°ãããŸããã ããŒã¿ããŒã¹(AWS RDS)ã®ã€ã³ã¹ã¿ã³ã¹ã¿ã€ããå°ãããã å®å
šã«ãµã€ãžã³ã°ã®ãã¹ã§ãããåäœç¢ºèªã§è€æ°ã®ãžã§ãã倧éã«åããããšãã§ããt2.smallã®ã€ã³ã¹ã¿ã³ã¹ã§ååã«åäœããã®ã§ãt2.smallã§å€§äžå€«ã ãããšããã®ãŸãŸæ¬çªå°å
¥ããã®ã§ãããéçšéå§ããŠ2ã¶æãããã§ãé«è² è·ã«ãªããŸãããéããã«t2.mediumã«ã¹ããã¯ã¢ããããŸããã ã³ãã¯ã·ã§ã³ããŒã«ã®èšå®ãæŒããŠããã Rundeckã¯ãrundeck-config.propertiesãšãããã¡ã€ã«ã«ããŒã¿ããŒã¹ã®æ¥ç¶æ
å ±ãèšè¿°ããŸãã ããã©ã«ãã§ã¯ãH2 Databaseã䜿çšããåæã®æ¥ç¶æ
å ±ã«ãªã£ãŠããŸãã ãããRDS(MySQL)ã䜿ãããã«ä¿®æ£ããã®ã§ããããã®éãã³ãã¯ã·ã§ã³ããŒã«ã®èšå®ãæŒããŠããŸããããã®ãããæ¥ç¶ãäžåããŒã«ãããªãããšããç¶æ
ã«ãªã£ãŠããŸããã 以äžã®èšè¿°ãrundeck-config.propertiesã«è¿œå ããããšã§é©åã«ããŒã«ãããããã«ä¿®æ£ããŸããã dataSource.pooled=true dataSource.properties.removeAbandoned=true dataSource.properties.removeAbandonedTimeout=60 ããŒã¿ããŒã¹ã®ã€ã³ããã¯ã¹äžè¶³ ãã®issue ã§è°è«ãããŠããŸãããRundeckã®ããŒã¿ããŒã¹ã«ã¯GUIã®æ§èœã倧ããæ¹åã§ããã€ã³ããã¯ã¹ãããã€ããããŸãããããã®ã€ã³ããã¯ã¹ã¯ããã©ã«ãã§ã¯ä»äžãããŠããªãããã§ããéçšéå§åŸãGitHubãGoogle Groupã«æçš¿ãããŠããæ
å ±ã調æ»ãã ãã®issue ã§ç޹ä»ãããŠããã€ã³ããã¯ã¹ã #1547 ã§ç޹ä»ãããŠããã€ã³ããã¯ã¹ãä»äžããããšã§æ§èœãæ¹åã§ããŸããã å®è¡ãã°ãããŸãç¶ãã ããã¯éçšãéå§ããåããããã£ãŠãã課é¡ã ã£ãã®ã§ãããŒã¿ããŒã¹ã®é«è² è·ã®åå ã«ã¯ãªããŸããã§ãããã察åŠãå¿
èŠãªèª²é¡ã§ã¯ãããŸããã Rundeckã¯ããŒã¿ããŒã¹äžã®å®è¡ãã°ãåé€ããŸãããé·æééçšããŠå®è¡å±¥æŽã倧éã«æºãŸã£ã段éã§å®è¡å±¥æŽã®æ€çŽ¢ãè¡ãªã£ãå ŽåãããŒã¿ããŒã¹ã®è² è·ãé«ãŸãå¯èœæ§ãããã®ã§ã宿çã«åé€ããä»çµã¿ãå¿
èŠã ãšå€æããŸããã åé€ããå®è¡ãã°ã®æ¡ä»¶ã¯ä»¥äžã®éãã§ãã ãžã§ãã¯ææ°ã®1äžä»¶ã®å®è¡ãã°ãä¿æããã1äžä»¶ãè¶
ãããå€ãé ã«åé€ãããã ææ¬¡1åã ãå®è¡ããããžã§ããããã°ã1æé以å
ã«è€æ°åå®è¡ããããžã§ãããããŸãããŸãã調æ»ã®ããã«å€ãå±¥æŽã調ã¹ãããšããããããããŸããããã®ãããªåæãèæ
®ããŠãäžèšã®ãããªã«ãŒã«ã«ããŸããã ãããŠãRundeckã®ããŒã¿ããŒã¹ã®æ§é ãçè§£ããŠã©ã®ããŒãã«ã®ããŒã¿ãåé€ããã°ããã®ããèŠã€ãã宿çã«åé€ããããã°ã©ã ãäœæããŸããã 調æ»ãããšãã以äžã®deleteæã®å®è¡ããã°è¯ãããã§ãã delete from log_file_storage_request where execution_id in ( @jobhistoryids ) delete from execution where id in ( @jobhistoryids ) delete from base_report where jc_exec_id in (@jobhistoryids ) @jobhistoryidsã¯ãbase_reportããŒãã«ã®jc_exec_idåã®å€ã§ãã ããšã¯ãäžèšã®æ¡ä»¶ã«åèŽãããžã§ãã®Idãšåé€ä»¶æ°ãç¹å®ããå¿
èŠããããŸãã ããã¯æ¬¡ã®SQLã§ååŸã§ããŸããã select inntable.jc_job_id as JobId, inntable.counts - 10000 as DeleteCount from ( SELECT jc_job_id, count(jc_exec_id) counts FROM base_report group by jc_job_id ) inntable inner join scheduled_execution se on se.id = inntable.jc_job_id where se.execution_enabled = 1 and inntable.counts > 10000 order by inntable.counts desc ãã®selectæã§ãå®è¡åæ°ã1äžåãè¶
ããŠãããžã§ãã®Idãšè¶
éåæ°ãããããŸãã â»äŸãã°10300åå®è¡ãããããã300åãè¶
éåæ°ã«ãªããŸãã ãããŠã次ã®SQLã§åé€å¯Ÿè±¡ã®jc_exec_idãç¹å®ããŸãã SELECT jc_exec_id FROM base_report where jc_job_id = @jobId -- äžã®selectæã§èŠã€ãã£ã JobId order by date_completed asc -- å®äºæ¥æã§æé ã§ãœãŒãããããšã§1äžä»¶ãè¶
éããå®è¡ãã°ã®Idãç¹å®ã§ãã limit @deleteCount -- äžã®selectæã§èšç®ããåé€å¯Ÿè±¡ä»¶æ° DeleteCount ããšã¯ããã®selectæã§ååŸã§ããjc_exec_idããã©ã¡ãŒã¿ã«ããŠäžè¿°ãã3ã€ã®deleteæãå®è¡ããã°ãåé€å®äºã§ãã ãªãããžã§ããèµ·åããªã ããŒã¿ããŒã¹ã®ãã©ãã«ãæ²»ã£ãåŸã¯ãã°ããé 調ã«åäœããŠããŸãããããããæå®ããæéãªã®ã«ãããã«èµ·åããªãããšããçŸè±¡ãçºçããããã«ãªããŸããã 詳ããç¶æ³ãèŠãŠã¿ããšããããå®è¡ãé
å»¶ããŠããããã§ããã ãããããšèª¿ã¹ãŠã¿ããšãRundeckãå
éšã§äœ¿ã£ãŠãããžã§ãã¹ã±ãžã¥ãŒã©ã©ã€ãã©ãªã®Quartzã®ãã©ã¡ãŒã¿ãåå ã§ããã Rundeckã®å
¬åŒããã¥ã¡ã³ã ã«ããã°ã The maximum number of threads used by Rundeck for concurrent jobs by default is set to 10 ãšæžããŠããéããããã©ã«ãã§ã¯æå€§ã§10æ¬ã®ãžã§ãã®åæå®è¡ãå¯èœã§ãã äžæ¹ãäžäŒã§ã¯å©çšãä¿é²ãããçµæãã¿ã€ãã³ã°ã«ãã£ãŠã¯10以äžã®ãžã§ããåæã«å®è¡ããããããªç¶æ³ã«ãªã£ãŠããããã®çµæãå®è¡ãé
å»¶ããããã«ãªã£ãŠããŸããããã®èšå®ãå€ããã«ã¯ã以äžã®èšè¿°ãrundeck-config.propertiesã«è¿œå ããŸãã quartz.props.threadPool.threadCount=30 ãã®èšè¿°ã«ãã£ãп倧30ãŸã§åæå®è¡ã§ããããã«ãªããåé¡ãèµ·ããªããªããŸããã çµããã« ä»åã¯å®éã«éçšããŠããŠçºçãããã©ãã«ãšãã®å¯ŸåŠã«ã€ããŠç޹ä»ããŸãããåèã«ãªãã°å¹žãã§ãã äžäŒã§ã¯Windowsã®ã¿ã¹ã¯ã¹ã±ãžã¥ãŒã©ããRundeckãžç§»è¡ããŸãããRundeckã¯æªç¥ã®ããŒã«ã ã£ãã®ã§èŠåŽããç¹ããããŸããããèµ·ãã£ãåé¡ã¯èª¿æ»ããã°è§£æ±ºçãèŠã€ãããã®ã°ããã ã£ãã®ã§ãç§»è¡ã¯ååæåãããšæããŠããŸãã ããŸã GUIã®æ¥æ¬èªå 管çç»é¢ãè±èªã ãšãããã«ããã®ã§ãäžäŒã§ã¯ ã¬ã€ãã©ã€ã³ ã«ãããã£ãŠãäž»èŠãªéšåã ãã§ããæ¥æ¬èªã«ããŠããŸãã éšåçãªããŒã«ã©ã€ãŒãŒã·ã§ã³ã§ã¯ãããŸããããªããããã·ããªã¬ãã«ã§ã¯ããã®ã§ãæ¬å®¶ã®æ¹ã«ãå°å
¥ã§ããããã« PR ãéã£ãŠããŸããæ¬¡ã®ããŒãžã§ã³ã§åã蟌ãŸãããããããŸãã^ - ^ ãã®èšäºã®çè
ã«ã€ã㊠ã·ã¹ãã æ¬éšCTO宀æå±ã® åŸ³æŠ ã§ãã ãµãŒãã¹ã®æè¡åºç€ã®éçºéçšã宿æ³ãµãŒãã¹ã®éçºæ¯æŽãè¡ãªã£ãŠããŸãã
ãã®èšäºã¯ äžäŒ.comã¢ããã³ãã«ã¬ã³ããŒ2018 ã®7æ¥ç®ã§ãã ããã«ã¡ã¯ãã¹ãäºæ¥éš ãã¶ã€ããŒã®æ±æ ¹ã§ãã çŽ1幎ãããŠ10æ25æ¥ã«ããŒã³ããã äžäŒ.com ã¹ã ã® å³æäºçŽãµãŒãã¹ ãã玹ä»ããããšæããŸãã SPAãšã¯ïŒ äžäŒ .com ã¹ãã®ç¹åŸŽã»UIUXã®ãã€ã³ã UIUXã®ãã€ã³ãâ æœèšã®é
åãäŒãã UIUXã®ãã€ã³ãâ¡ ãã©ã³ã®é
åãäŒãã UIUXã®ãã€ã³ã⢠空ãæéã»äºçŽæéããããããã UIUXã®ãã€ã³ã⣠äºçŽã®åã«å©çšæ¡ä»¶ããã£ãã説æ ããããã®ããã«ã¹ã15éž æ±äº¬ã®ããã«ã¹ã 1. ã¶ã»ããã³ã·ã¥ã© ã¹ã 2. ã¶ ã¹ã ã¢ãã ãã³ããªã³ ãªãªãšã³ã¿ã«æ±äº¬ 3. ã¢ãã³ã»ã¹ãïŒã¢ãã³æ±äº¬ 4. AO ã¹ãïŒã¯ã©ãïŒã¢ã³ããŒãº æ±äº¬ 5. ã¹ã€ã¹ã»ããŒãã§ã¯ã·ã§ã³ ã¹ã ããªã€ïŒã¶ã»ããªã³ã¹ã®ã£ã©ãªãŒ æ±äº¬çŽå°Ÿäºçº 6. ã¹ãïŒãŠã§ã«ãã¹ããžã¥ãŒã«ïŒãã€ã¢ãã ãªãŒãžã§ã³ã·ãŒ æ±äº¬ 7. ãã©ã«ãã¥ãŒãïŒããã«ãã¥ãŒãªãŒã¿ã 8. SPA THE SAKURAïŒã¶ã»ããªã³ã¹ ãããã¿ã¯ãŒæ±äº¬ 9. 庵ã¹ã TOKYOïŒãã«ãã³æ±äº¬ãå°å Ž æ±äº¬ããïŒæé以å
ã§è¡ããæ
通ã»ãªãŸãŒã 10. 赀沢ã¹ãïŒèµ€æ²¢è¿è³é€š 11. GINYU SPAïŒã®ã³ãŠãŠã¹ãïŒïŒç®±æ ¹åé 12. 庵ã¹ã KARUIZAWAïŒè»œäºæ²¢ããªãªãããã㫠倧éªã»äº¬éœã®ããã«ã¹ã 13. CONRAD SPAïŒã³ã³ã©ããå€§éª 14. MEGURI SPA & WELLNESSïŒã€ã³ã¿ãŒã³ã³ããã³ã¿ã«ããã«å€§éª 15. ã¶ ã¹ã ã¢ãã ãã©ãŒã·ãŒãºã³ãºããã«äº¬éœ ãããã« SPAãšã¯ïŒ ãšã³ãžãã¢ã®ã¿ãªããŸã¯ãSPAããšèããŠãŸã ãSingle Page ApplicationïŒã·ã³ã°ã«ããŒãžã¢ããªã±ãŒã·ã§ã³ïŒã ãæãæµ®ãã¹ããããããŸããããçœ ã§ããããã¿ãŸããã ããã§ã玹ä»ããã®ã¯ã æ¥åž°ã枩济ããµãŠãã®ã»ããªã©ã¯ãŒãŒã·ã§ã³ãããµãŒãžã®æœè¡ãåãããã ã ãã€ã¹ã ïŒDay spaïŒããã ããã«ã¹ã ãã®ããšã§ãã æè¿ã§ã¯ããµéãããµãŠããŒããå¢ããŠããããã§ããã æž©æµŽæœèšã§èº«äœãæž©ããŠããã¢ããããªãŒãã¡ã³ããªã©ã®æœè¡ãåãããšã è¡è¡ããªã³ãã®æµããè¯ããªããã广ãé«ãŸããŸãã ãDay spaãã®wikiè±èªçã«ãããšã A day spa is a business that provides a variety of services for the purpose of improving health, beauty and relaxation through personal care treatments such as hair, massages and facials. A day spa is different from a beauty salon in that it contains facilities such as a sauna, pool, steam room, or whirlpool that guests may use in addition to their treatment. ... äžäŒ .com ã¹ãã®ç¹åŸŽã»UIUXã®ãã€ã³ã ã€ãŸããäžäŒ .com ã¹ããå³éžããã¹ãã¯ã è¡äžã«ãããªã©ã¯ãµãã³ããšã¹ããµãã³ãšã¯éã ãã¹ ã» ãµãŠã ãªã©ã®æž©æµŽæœèš ããŒã« ã ãã£ãããã¹ãžã ãªã©ã®éåæœèš ãã¹ããŒãã®ãŸãŸå¯ãã ãªã©ã¯ãŒãŒã·ã§ã³ã©ãŠã³ãž ãªã©ã®æœè¡ååŸã«äœ¿ããä»åž¯æœèšããã£ããã äžè¬ã«ã¯æµéããªããã ããã® åç²§åãã©ã³ã ã䜿ã£ãŠãããããšãã£ãé
åãã¢ããŒã«ããŠããå¿
èŠããããŸãã UIUXã®ãã€ã³ãâ æœèšã®é
åãäŒãã ã»ã»ã» æœèšã®é
åãšããã°ãäœãšèšã£ãŠã åç ã§ãã äžäŒ.comã®ä»ã®ãµãŒãã¹ã«ãå
±éããŸãããé«çŽæã®ããçŸããåçãã§ããã ã倧ããèŠãããšãŠãŒã¶ãŒã«ãã®æœèšã蚪ãããšãã®ã€ã¡ãŒãžãæã£ãŠããããŸãã ãªã®ã§ãç»é²ããã®ã«åçã¯å¿
é ããŸãããéšå±ã®ã¹ããã¯ïŒåºããã¹ãã¹ã€ãŒããã©ãããå®å
šå宀ã§ãããetcïŒã枩济æœèšã®å
容ïŒããããã¹ãã³ãŒã«ããã¹ããã©ã€ãµãŠããã¹ããŒã ãµãŠããæž©æ³ãå²©ç€æµŽããããïŒãããŒã«ããã£ãããã¹ãžã ã¯æ°Žçããã¬ãŒãã³ã°ãŠã§ã¢ãã¬ã³ã¿ã«ã§ãããã©ãããã·ã³ãã«ãªããã¹ãã¢ã€ã³ã³ã§è¡šçŸããŸããã UIUXã®ãã€ã³ãâ¡ ãã©ã³ã®é
åãäŒãã ããããã¯ã¹ããçã®ãã£ããã£ã§èª¬æããŸãã ãã©ã³äžèЧããã³ãã©ã³æŠèŠã§ã¯ãã¿ã€ãã«ã»å©çšã§ããä»åž¯æœèšã»æ»åšæéç®å®ã»æéããããããã«ãªã£ãŠããŸããã¡ãªã¿ã«ã ã¿ã€ãã«ã«ããåæ° 㯠çŽç²ãªããªãŒãã¡ã³ãã®æé ã§ãã«ãŠã³ã»ãªã³ã°ãæœè¡ååŸã«äœ¿ããä»åž¯æœèšã®å©çšæéãå«ãã§ããŸããããã®ãããã«ååŸã®ä»åž¯æœèšå©çšæéãå«ãã å
šäœã®æ»åšç®å®ã®æéãå¥ã«è¡šç€º ããããšã§ãã©ã®ãããæéã«äœè£ãããã°ãã®ãã©ã³ããã£ããäœéšã§ããããããããŸãã ãã©ã³å
容ã§ã¯ããªãŒãã¡ã³ãã®è©³çްãšãšãã«ã©ããªãéšå±ã§æœè¡åããã®ããä»åž¯æœèšã¯ãããããã€ïŒæœè¡åãåŸãïŒã©ã®ãããã®æéãã©ããªæœèšã䜿ããã®ãããããŸãã UIUXã®ãã€ã³ã⢠空ãæéã»äºçŽæéããããããã ãã©ã³ã決ãŸã£ãããäºçŽæéã確èªããããã¿ã³ãã空ãæéãæ¢ããŠã¿ãŸãã ãŸãã«ã¬ã³ããŒã§ãæ¥ä»ããéžæãæ¬¡ã«ã æœè¡ã¹ã¿ãŒãæé ããéžã³ãŸãã æéã¯ã¬ã¹ãã©ã³ã®äºçŽãšã¯ç°ãªã æ¥åºæéã§ã¯ãããŸãã ãïŒå°ã§ãä»åž¯æœèšã¯ãæœè¡ã¹ã¿ãŒãã®âååããå©çšã§ããŸãããšè¡šç€ºããŠããŸãã®ã§ããããåèã«15åå»ã¿ã®æéãã¿ã³ãéžãã§äºçŽãã©ãŒã ã«é²ã¿ãŸãã UIUXã®ãã€ã³ã⣠äºçŽã®åã«å©çšæ¡ä»¶ããã£ããèª¬æ æ³šææèšã«å
¥ããŠèªãã§ãããºãšããŠããŸãã®ã§ã¯ãªã 女æ§éå® ã ãã¿ããã£äžå¯ ã®ãã©ã³ãªã©ã§å©çšã§ããªãæ¡ä»¶ãéžã¶ãš äºçŽå®äºã§ããªãããã«ãªã£ãŠããŸãã ãã®ä»ãæœèšã¹ã¿ããããäºåã«ãŠãŒã¶ãŒãžè³ªåã»ç¢ºèªãã§ããããã«ãªã£ãŠããŸãã ããããã®ããã«ã¹ã15éž ãšããããšã§ã äžäŒ .com ã¹ãã®äžãã以äžã®ãã€ã³ãã§ããããã®æœèšãã»ã¬ã¯ãããŠ15éžã玹ä»ããŸãã ããã«ã¹ããæ
通ã»ãªãŸãŒãã¹ãã§ãã æž©æµŽæœèšå©çšä»ããã©ã³ããã ç·æ§ã女æ§ãå©çšã§ãã æ±äº¬ã®ããã«ã¹ã 1. ã¶ã»ããã³ã·ã¥ã© ã¹ã æ±äº¬ã»æ¥æ¯è°·ïŒã¶ã»ããã³ã·ã¥ã©æ±äº¬ 6é â
ãã¡ãå®éã«äœéšããŠããŸããïŒç§ã®äžã§æºè¶³åºŠïŒäœâ
ã颚åã¯ãªããµãŠãã®ã¿ã§ããããã£ããæããã©ã€ãµãŠããš ã»ã©ããæããã®ã¹ããŒã ãµãŠããã¢ããã®éŠããããã·ã£ã¯ãŒã®ã»ã ã¢ã€ã¹ãã¡ãŠã³ãã³ãããã®ã§ãµãŠããŒã®æ¹ãæºè¶³ããã ããã¯ãã ã¢ãããã©ããŒã®æœè¡ããšã£ãŠãæ°æã¡ãè¯ãã®ã¯ãã¡ããã ãã®åçã®ãªã©ã¯ãŒãŒã·ã§ã³ã«ãŒã ã§ã¯ããå·ããã°ã¬ãŒããã«ãŒããžã¥ãŒã¹ãš ãã³ãŽãŒãžã¥ãŒã¹ãããã ããŸãã ãŸããã®ãã§ã¢ã§ã¯ããããã³ã§é³æ¥œãèãããšãã§ããããèªæžç¯ã§ éèªãèªãããšãã§ããã®ã§ããããæé£ã«ã¯ãŽã£ããããã£ããå¯ããŸãã 2. ã¶ ã¹ã ã¢ãã ãã³ããªã³ ãªãªãšã³ã¿ã«æ±äº¬ æ±äº¬ã»äžè¶åé§
çŽçµïŒãã³ããªã³ ãªãªãšã³ã¿ã« æ±äº¬ 37é ããããäžäŒ.com ã¹ãã§äžçªãé«ããã©ã³ã®ããããã«ã¹ãã ã§ããããŒã³ãããŠããã«ãã¢ã§Xmasè¿ãã«äºçŽãå
¥ããŸããããããã ãšãŠã人æ°ãªã®ã§ãã€ãè¡ã£ãŠã¿ããïŒ å®å
šå宀ã®èŽ
ãæ¥µããã¹ãã¹ã€ãŒãã®ã»ããã颚åããµãŠããããçºæãæ¥œãããŸãã 3. ã¢ãã³ã»ã¹ãïŒã¢ãã³æ±äº¬ æ±äº¬ã»å€§æçºé§
çŽçµïŒã¢ãã³æ±äº¬ 34é èŠãŠãã ããããã®ããŒã«ïŒå·Šç«¯ã«ã¯å¯å£«å±±ãèŠããŸãã è¿·ãããããããŒãžã®ã¡ã€ã³ããžã¥ã¢ã«ã«æ¡çšããŠããŸããŸããã ããŒã«ã®ã»ããã£ãããã¹ãžã ãå€§æµŽå ŽãããªãŒãã¡ã³ãã«ãŒã æ¯ã® ãªã©ã¯ãŒãŒã·ã§ã³ãšãªã¢ãããçºæãçŽ æŽãããã§ãã 4. AO ã¹ãïŒã¯ã©ãïŒã¢ã³ããŒãº æ±äº¬ æ±äº¬ã»èãéãã«ãºïŒã¢ã³ããŒãº æ±äº¬ 37é çœã貎éãšããæŽç·Žããã空éãæšã®ã¬ãããæº¢ããããªãŒãã¡ã³ãã«ãŒã ãããé«å±€éãªãã§ã¯ã®é空ãçå±
ãæãçŽ æŽãããçºæãæ¥œãããŸãã å
šããªãŒãã¡ã³ãã«ãŒã ã«ã¯ãã©ã€ããŒãããã«ãŒãã·ã£ã¯ãŒã«ãŒã ãããä»ã®ã²ã¹ãã®ç®ãæ°ã«ãªããŸããã ããã«ãŒãšãªã¢äœµèšã®æž©æµŽãšãªã¢ã§ã¯ã颚åãã·ã£ã¯ãŒã®ä»ãç·æ§ã¯ãã©ã€ãµãŠããšæ°Žé¢šåã女æ§ã¯ã¹ããŒã ãµãŠããš360°ã·ã£ã¯ãŒãå®åãããŠããŸãã 5. ã¹ã€ã¹ã»ããŒãã§ã¯ã·ã§ã³ ã¹ã ããªã€ïŒã¶ã»ããªã³ã¹ã®ã£ã©ãªãŒ æ±äº¬çŽå°Ÿäºçº æ±äº¬ã»èµ€åèŠéã»æ°žç°çºïŒã¶ã»ããªã³ã¹ã®ã£ã©ãªãŒ æ±äº¬çŽå°Ÿäºçº 30é äžçäžã®ã»ã¬ãããæãããã¹ã€ã¹è£œæ€ç©æ§ã»ã«ã©ãŒåç²§åãã¹ã€ã¹ã»ããŒãã§ã¯ã·ã§ã³ãã䜿çšããåœå
åã®çŽå¶ãµãã³ã§ããšã€ãžã³ã°ã±ã¢ã®å
端æè¡ãçµéããããªãŒãã¡ã³ããå ªèœã§ããŸãã åçã¯ã¹ãã¹ã€ãŒãã»ãã¢ã«ãŒã ãè§éšå±ã®ããã©ãã®çºæãçŽ æµã§ããã ã¹ãã¹ã€ãŒãã®ãã©ã³ã§ã¯ãã®ãéšå±ã§ã¢ãã¿ãŒãã£ãŒãããã ãããšãã§ããŸãã 6. ã¹ãïŒãŠã§ã«ãã¹ããžã¥ãŒã«ïŒãã€ã¢ãã ãªãŒãžã§ã³ã·ãŒ æ±äº¬ æ±äº¬ã»æ°å®¿è¥¿å£ïŒãã€ã¢ãã ãªãŒãžã§ã³ã·ãŒ æ±äº¬ 28é èåãã¶ã€ããŒãææããã¹ã¿ã€ãªãã·ã¥ãªç©ºéã¯ãæšãªã©ã®å€©ç¶çŽ æã®æž©ãããæããããªããã³ã³ãã³ãã©ãªãŒãªé°å²æ°ãæŒããŸãã ããªãŒãã¡ã³ãåã«ã¯ããŒã«ããã£ãããã¹ãžã ãå©çšå¯èœãåçã®ãšãããããŒã«ã«ã¯ãžã£ã°ãžãŒããŠã©ãŒã ã«ãŒã ãåããããŒã«ãµã€ãã¯å±
å¿å°ã®ããããããã§ã¢ãšããŒãã«ãé
ãããŠããããããšãªã£ãŠããŸãã 7. ãã©ã«ãã¥ãŒãïŒããã«ãã¥ãŒãªãŒã¿ã æ±äº¬ã»èµ€åèŠéïŒããã«ãã¥ãŒãªãŒã¿ã ã¬ãŒãã³ã¿ã¯ãŒ 3é 100âååŸã®ä¹Ÿç¥ãã髿ž©ã§çºæ±ãä¿ããã©ã€ãµãŠãã50âååŸã®æž©åºŠã§èãäœã«è² æ
ããããã«ããã¹ããŒã ãµãŠãã®2çš®é¡ãã©ã€ã³ãããã ãã€ãã©ãšãžã§ããã®æ©èœãæã€æµŽæ§œããäœããã£ãããšäŒããããã©ãŠã³ãžã䜵èšããŸãã ããŒã«ã»ãã£ãããã¹ãžã ä»ãã®ãã©ã³ãªãæ°Žçããã¬ãŒãã³ã°ãŠã§ã¢ãç¡æã§ã¬ã³ã¿ã«ã§ããã®ã§æã¶ãã§å©çšã§ããŸãã 8. SPA THE SAKURAïŒã¶ã»ããªã³ã¹ ãããã¿ã¯ãŒæ±äº¬ æ±äº¬ã»åå·ïŒã¶ã»ããªã³ã¹ ãããã¿ã¯ãŒæ±äº¬ B1é éœäŒã®ãªãã«ããããéå¯ãšåºã空éã®ãªãã§ãæ¥æ¬å€æ¥ã®äŒçµ±çãªéŠãã«å
ãŸããããªãŒãã¡ã³ãã«ãŒã ã§ãã ããªãŒãã¡ã³ãåŸãã¢ãã¿ãŒãã£ãŒãããã ããã©ãŠã³ãžã¯ã竹æã«ãããããããªéããã«å
ãŸããªããããã£ãããšéããããšãã§ãã空éã«ãªã£ãŠããŸãã 9. 庵ã¹ã TOKYOïŒãã«ãã³æ±äº¬ãå°å Ž æ±äº¬ã»å°å ŽïŒãã«ãã³æ±äº¬ãå°å Ž 5é ã¬ã€ã³ããŒããªããžãæ±äº¬æ¹Ÿãã¥ãŒã楜ãããå€§æµŽå Žã¯ãããŒã«ã䜵èšããæ°Žçççšãšãªã¢ã«ãããŸããïŒææã¬ã³ã¿ã«ããïŒ æµ·ãçºãããã©ã¹ãã€ããéæŸçãªãã£ãããã¹ã»ã³ã¿ãŒã åçš®ãã·ãŒã³ãåããã宿æ³è
ã¯ç¡æã§24æéå©çšã§ããŸãã æ±äº¬ããïŒæé以å
ã§è¡ããæ
通ã»ãªãŸãŒã 10. 赀沢ã¹ãïŒèµ€æ²¢è¿è³é€š é岡ã»äŒæ±åžïŒèµ€æ²¢æž©æ³é· 壮倧ãªç·ã«å²ãŸãã赀沢枩æ³é·å
ã«ãçŸãšå¥åº·ããªã©ã¯ãŒãŒã·ã§ã³ã®å ŽæãšããŠèªçã ãã©ã³ã¹çºç¥¥ã®æµ·æŽçæ³ãã¿ã©ãœãã©ããŒãã®çºæ³ãããšã«çãŸããæµ·æŽæ·±å±€æ°Žã®ããŒã«ã«ã¯ã赀沢æ²ã®æ·±æµ·800mããæ±²ã¿äžããæ°é®®ãªæµ·æ°Žãæž©ããŠäœ¿çšãããŠããŸãã ãšã¹ããšãªã¢ã«ã¯ãç¹åŸŽã®ç°ãªã3ã€ã®ããŒã ïŒãµãŠãïŒãšæž©ã»å·ã®è¶³æ¹¯ãªã©ãå®åã æµ·æŽæ·±å±€æ°Žã®ããŒã«ã§ä»£è¬ãã¢ãããããåŸã«ã¯ãå®å
šå宀ã®ã¢ããã®éŠãã«å
ãŸãããéšå±ã§ããªãŒãã¡ã³ããåããããŸãããŸããåžæã®ã客æ§ã«ã¯ããã©ã¹æéã§çè±ã®ãã©ã100茪浮ã¹ããã©é¢šåããçšæããããšãå¯èœã§ãã 11. GINYU SPAïŒã®ã³ãŠãŠã¹ãïŒïŒç®±æ ¹åé ç¥å¥å·ã»ç®±æ ¹ã»å®®ãäž æ¥æ¬äžäºçŽã®åããªã宿ãšããŠåã®æ
通ãç®±æ ¹åéããã®éå¯ãªæã®ç©ºæ°ã«å
ãŸãããGinyu Spaã ããªãŒãã¡ã³ãååŸã« ãŠã©ãŒã¿ãŒã¬ãŒãã³ã®åããã«æãé倧ãªèªç¶ãçºããŠããã ããæºæ³ããæ¹§ãåºã倧å°ã®åã§ãäºæãè§£ãæŸã€ããšãã§ããŸãã ã»ã©ãã¹ãã®ãã¯ããã¯ã«ãããäœã®ç²ãããšãããšã ãã§ãªããèªåæ¬æ¥ã®ãã©ã³ã¹ãæŽãå¥åº·ãçŸãããžãšå°ããŸãã 12. 庵ã¹ã KARUIZAWAïŒè»œäºæ²¢ããªãªããããã« é·éã»è»œäºæ²¢ïŒè»œäºæ²¢ããªãªããããã« B1é ãã¡ãã®ã颚åã¯ãå°ç¬æž©æ³ãæ³è³ªã¯ãããªãŠã ïŒçé
žæ°ŽçŽ å¡©æ³ã âçŸèã®æ¹¯âãšãåŒã°ããèã®äžèŠãªè§è³ªãæ¯ç©Žã®æ±ããåã£ãŠããã女æ§ã«å¬ããå¹èœããããããæ¹¯äžããããã£ã±ãããã®ã§ãã¹ããŒããã¢ã¯ãã£ããã£ã§æ±ãæµããåŸãªã©ã«ãããããã§ãã åã®ãšãã»ã³ã¹ãéæã«åãå
¥ããããŒãªã³ã°ç©ºéã庵ã¹ã KARUIZAWAãã æ¥æ¬äººãªãã§ã¯ã®ç¹çްã§äžå¯§ãªæœè¡ãšãæ¥æ¬ç±æ¥ã®èŽ
æ²¢ãªç²§æã䜿çšããå¿ãšèº«äœãè§£ãã»ãããŠãããŸãã 倧éªã»äº¬éœã®ããã«ã¹ã 13. CONRAD SPAïŒã³ã³ã©ããå€§éª å€§éªã»äžä¹å³¶ã»æ¢
ç°ïŒã³ã³ã©ããå€§éª 38é æ·å·åŽãæãããªãŒãã¡ã³ãå
šå®€ããã¯ãå°äž200mããæãã¹ã«ã€ã©ã€ã³ãå»äžå»ãšè¡šæ
ãå€ããæ¯è²ãçºããªãããå®ããã®æéããéããããã ããŸããã·ã£ã¯ãŒããŒã¹ããã€ã¬ãããŠããŒã³ãŒããŒãå®åãããå®å
šãã©ã€ããŒããªç©ºéã§ãã æž©æµŽæœèšã¯ãµãŠãããžã§ãããã¹å®åã ç·æ§ïŒããããã¹ / ã³ãŒã«ããã¹ / ãã©ã€ãµãŠã 女æ§ïŒããããã¹ / ã¹ããŒã ãµãŠã ããã«ãŒã«ãŒã å
ã«ã¯ãã€ãããã¯ãªæ¯è²ãçºããªããããã£ãããšããæéããéããããã ããã©ãŠã³ãžã䜵èšãããªã³ã¯ã³ãŒããŒã«ã¯ãå£ç¯ã®ãã«ãŒããŠã©ãŒã¿ãŒãæž©ãããè¶ãçšæãããŠããŸãã 14. MEGURI SPA & WELLNESSïŒã€ã³ã¿ãŒã³ã³ããã³ã¿ã«ããã«å€§éª 倧éªã»æ¢
ç°ã»ã°ã©ã³ããã³ã倧éªïŒã€ã³ã¿ãŒã³ã³ããã³ã¿ã«ããã«å€§éª 4é å
šå®€ãã¯ããŒãŒãããã·ã£ã¯ãŒããã€ã¬ããã¬ããµãŒãåãããçæ¿ãããããªãŒãã¡ã³ãåŸã®ãæ¯åºŠãŸã§ãå
šãŠå宀å
ã§è¡ããã¹ãã¹ã€ãŒãã æž©æµŽæœèšã¯ãŸãã§é«çŽæ
é€šã®æž©æ³ã圷圿ãããæ¥æ¬åŒæµŽå Žã 倧éœäŒã®äžå¿ã§å³ãããæ³åãè¶ããæ¥µäžã®ãªãã¬ãã·ã¥ïŒãªã©ã¯ãŒãŒã·ã§ã³ãžã£ãŒããŒã楜ãããŸãã 15. ã¶ ã¹ã ã¢ãã ãã©ãŒã·ãŒãºã³ãºããã«äº¬éœ 京éœã»æ±å±±åšèŸºïŒãã©ãŒã·ãŒãºã³ãºããã«äº¬éœ ã€ã³ãã¢ããŒã«ã¯ã京éœå±æã®ãã£ãããšããåºãã確ä¿ããŠãããŸãã20ã¡ãŒãã«ã®åºãã«å ãã2ã€ã®ãžã£ã°ãžãŒãå®åããªãŸãŒãææº¢ããé°å²æ°ã®ãªããèŽ
æ²¢ãªã²ãšãšãããæ¥œãã¿ãã ããã ã颚åïŒæž©æµŽã»å·æµŽïŒã»ãµãŠãããæ¥œãã¿ããã ããŸãã ç·æ§ïŒãã©ã€ãµãŠã 女æ§ïŒã¹ããŒã ãµãŠã å
¥å¿µã«éžã³æãããèªç¶ã®åãšã©ã°ãžã¥ã¢ãªãŒãèåããã¹ãã³ã±ã¢ãã©ã³ããšãæ·±ãããŒãªã³ã°å¹æããããã京éœãªãã§ã¯ã®çŽ æããããã䜿çšããããªãŒãã¡ã³ãã¯ãæ¬ç©ã®ãã€ãããšæ°é®®ãªå®ããããããããŸãã ãããã« ã¿ãªããæ¯æ¥PCä»äºãããããµãŒãã£ã³ã§ç®ãé
·äœ¿ããŠããã®ã§ è©ããã»è
°çæã¡ã®æ¹ãå€ãã®ã§ã¯ãªãã§ããããïŒ ïŒãããã¯æ
¢æ§çãªè©ããã®è§£æ¶ã«ã¢ãããã©ããŒã«ã¯ãŸããŸãããïŒ ããŸã«ã¯èªåã®èº«äœãã¡ã³ããã³ã¹ããªããšé«ãããã©ãŒãã³ã¹ãåºããŸããã äžäŒ.com ã¹ãã§ã¯ãã ããŸXmasãŸã§ã®ãŠã£ã³ã¿ãŒã»ãŒã«ãéå¬äžã§ãã ãã®æ©äŒã«ãã²å¿èº«ãçããèŽ
æ²¢ãªäœéšãããŠã¿ãŸãããïŒ