Upgrade to Pro — share decks privately, control downloads, hide ads and more …

はじめてのSSR

 はじめてのSSR

React + ReduxでSSR+Isomorphicなアプリケーションを作ったときにつまづいた点をまとめました。
Node学園27時限目

Transcript

  1. ⴱ ׭ ג ך S S R 

  2. せ⵸: @brn (ꫬꅿ⨳ⵃa.k.a ـٕ٦ظ) 耵噟: ؿٗٝزؒٝسؒٝآص،٥iOSؒٝآص، ⠓爡: Cyberagent ،سذؙأةآؔRightSegment٥AI Messenger

    ـؚٗ: http://abcdef.gets.b6n.ch/ Twitter: https://twitter.com/brn227 GitHub: https://github.com/brn
  3. ⡦׾⠗ִ׋ְךַ ְׂSSR׾׃״ֲהׅ׷הꬊ䌢ח넝䏝זֿה׾׃גְ׷鎸✲כ״ֻ 鋅ַֽ׷ך׌ָծ ⴱ娄涸ז㉏겗ח瘶ִ׷גְ׷׮ךָ㼰זְ״ֲח䙼ִ׷կ זךדծSSR+Isomorphicז圓䧭ד،فٔ׾⡲׷♳ד䝢׿׌ֿהծ 㹋ꥷח鍑寸׃׋倯岀׾⚛ץג׫׷կ

  4. Language ְא׮鸐׶typescript׾鼅䫛׃׋կ ֿ׸荈⡤כNodeJS⩎הـٓؐؠ⩎דٌرٕךinterface㹀纏ָ⢪ְת ׻ׇגꬊ䌢ח葺ַ׏׋կַז׶ىأָ幾׷կ 暴חAPIךٖأهٝأךأؗ٦و׾Ⱏ鸐ךٌآُ٦ٕחInterfaceה ׃ג㹀纏ׅ׷הծ ꫼涸חAPIךؒٓ٦׾鋅אֽ׵׸׷ךד葺ְկ

  5. Library/Framework ـٓؐؠ⩎כReact(v16.0β) + Redux + React-Router v4 ؟٦غ؟؎سכExpress + Sequelize

    + MySQL NodeJSך湊鋔כsupervisord
  6. Structure ֿֿכꬊ䌢ח䝢׿׌կָծ 如ل٦آך״ֲז圓䧭ח׃׋կ

  7. server NodeJSך؟٦غ٦㹋鄲 DB،ؙإأהַ client ـٓؐؠ⩎ך㹋鄲 React + Redux isomorphic NodeJSהـٓؐؠ⩎דⰟ鸐ׅ׷㘗㹀纏הַ

    Root rendering SSR欽ך؟٦غ٦
  8. HTML Rendering Reactך؝ٝه٦طٝزכ֮׷ך׌ָծHTMLةؚ׾ろ׿׌Ⰻ⡤ךٖ ٝتؚٔٝ׾וֲׅ׷ַ䝢׿׌կ 穠㽷HTMLةؚװHeadةؚ׮Reactד㹋鄲׃גծ؟٦غ؟؎سדٖ ٝتؚׅٔٝ׷ة؎ىؚٝך׫ծ׉ך؝ٝه٦طٝز׾⢪׏׋կ

  9. data-reactid HTMLⰋ⡤׾Reactדٖٝتؚׅٔٝ׷הـٓؐؠ⩎דmountׅ׷ה ֹחdata-reactidָ׆׸גWarningָד׷ָծ React v16ַ׵כdata-reactid׾涪遤׃זֻז׏׋ךדWarningָ嶊 ִ׋կ

  10. Redux State of SSR SSRדⴱ劍朐䡾׾ٖٝتؚׅٔٝ׷׋׭חծ 剑ⴱכ؟٦غ؟؎سדdbַ׵《䖤׃׋ؒٝذ؍ذ؍׾湫䱸床׃גְ ׋կ ׃ַ׃ծֿ׸׌הAPIؒٝسه؎ٝزך✳ꅾ盖椚ָ涪欰ׅ׷կ

  11. viewָ《䖤ׅ׷ر٦ةָ㢌׻׏׋הֹחծ ؟٦غ⩎ךؒٝذ؍ذ؍《䖤鿇ⴓ׮⥜姻ָ䗳銲ד✳ꅾ盖椚חז׷կ APIエンドポイント DB React ؒٝذ؍ذ؍׾湫䱸《䖤 Reactח床ׅ ブラウザ

  12. Redux State of SSR DRYחװ׷׋׭ծ 㹋ꥷחredux-saga׾⹛⡲ׇׁג؟٦غ٦ⰻדlocalhostד荈魦ךؒٝ سه؎ٝز׾〨ְ׋կ fetch׾⢪׏גְ׋ךדծisomorphic-fetchػح؛٦آ׾ⵃ欽կ

  13. ٖؔٝآ葿ך鿇ⴓָRedux-Sagaַ׵ךؿٗ٦ 㹋ꥷחlocalhostח،ؙإأ׃גծ ⰻ鿇ד׮ֲ♧䏝ずׄؒٝسه؎ٝز׾〨ֻկ APIエンドポイント DB React Redux-Saga׾⹛ַׅ X-Rest-Requestقحت׾➰♷׃ 㹋ꥷחAPIؒٝسه؎ٝز׾ localhostחぢַ׏ג〨ֻ

    ブラウザ JSON ؒٝذ؍ذ؍ך《䖤
  14. Redux State of SSR ؟٦غ٦כ鵤ׅ⦼׾SSRךٖٝتؚٔٝ穠卓הծJSON׾勴⟝ח״׏ ג㢌ִזֽ׸לז׵זְկ 剑ⴱכGetػًٓ٦ة׾⢪׏גְ׋ָծ 植㖈כقحتחX-Rest-Request: 1׾鏣㹀ׅ׷ֿהד㔐鼘׃גְ׷կ ֮הծأومהPCד鵤ׅⰻ㺁ָ麩ֲךדծ

    User-Agentقحتח䩛⹛ד؟٦غ٦ַ׵䒷ֹ竰ְ׌UserAgent׾ إحزׅ׷կ
  15. Redux Initial state SSRׅ׷הׅדח歗꬗חכStateָٖٝتׁؚٔٝ׸גְ׷朐䡾זך דծⴱ劍朐䡾ך《䖤כأؗحف׃׋ְկ

  16. State as JSON ת׆ծ؟٦غ؟؎سדٖٝتؚٔٝ׃׋穠卓ךReduxךState׾html חJSONה׃ג㙵׭鴥׿דծinitialStateה׃גⵃ欽׃׋կ

  17. const initialState = JSON.stringify(state);! ! <script type="text/javascript"! dangerouslySetInnerHTML={{! __html: `window.__INITIAL_STATE__

    = ${initialState}}`! }} />!
  18. State as JSON 如חծcomponentDidMountךة؎ىؚٝדhistory.stateָ瑞׌׏׋ ׵ⴱ㔐ٖٝتؚٔٝהⴻ㹀׃גծ 植㖈ךstate׾history.replaceדhistory.stateח鏣㹀׃׋կ

  19. Page1 history Page2 history state Page3 history state state וךل٦آחٓٝر؍ؚٝ׃ג׮history.stateָ搀ְل٦آָծ

    SPAך饯挿הז׷ل٦آחז׷կ Page2 history Page1 history state Page3 history state state
  20. React-Router V4 㹋ꥷח؟٦غ؟؎سדוך؝ٝه٦طٝز׾䲽歗ׅ׷ַծ וךAPI׾〨ַֻ寸׭׷חכծ React-Router v3דכmatch׾⢪ֲ鎸✲כְ׏םְ֮׏׋ך׌ָծ React-Router v4דכ׉׮׉׮matchָ䐖姺ׁ׸גְ׋կ זךד➿׻׶חmatchPath׾⢪ֲկ

  21. import {! matchPath! } from 'react-router';! ! const match =

    matchPath("/article/1", {! path: '/articel/:articleId',! exact: true! });! ! if (match) {! console.log(match.params)! // Object { articleId: 1 }! }!
  22. React-Router V4 ׋׌׃ծֿך倯岀׌הـٓؐؠךٕ٦ذ؍ؚٝהNodeJSךٕ٦ذ؍ ؚٝד✳ꅾ盖椚חז׏ג׃תֲךדז׿הַ׃׋ְ…

  23. Webpack typescriptד㹋鄲׃׋׋׭ծNodeJS⩎׮typescriptד㹋鄲׃׋ְկ ׁ׵חWebpackדcss-modules׾⢪׏גְ׋ךדծWebpack׾⢪׻ זְהSSRָ⹛ַזְկ זךדWebpackדכtarget׾nodeח䭷㹀ׅ׷ֿהדծ__dirname׾ 笝䭯׃אאnode_modules⟃㢩ך؝٦س׾bundle׃׋կ

  24. module.exports = { entry: { server: './server/index.ts' }, target: 'node',

    externals: /^(?!^\.\.?\/)/, output: { path: `${__dirname}/dist`, filename: "[name].js", libraryTarget: "commonjs2" }, resolve: { extensions: [".js", ".ts"] } }
  25. Watch Webpackדwatch׃גְ׋ך׌ָծ♧אךؿ؋؎ָٕ㢌刿ׁ׸׷׌ ֽד؟٦غ٦ծؙٓ؎،ٝز⚕倯ָⰋגⱄ؝ٝػ؎ׁٕ׸ג礵牞遹 欰♳״ֻזְךהծ SSR׾遤ֲ鿇ⴓך頾蚚׌ֽ넝ְךדծSSR׌ֽׁ׵ח؟٦غ׾׋ג גفٗإأ׾ⴓꨄ׃׋կ

  26. Requst SSR Response HTML Supervisord Renderingサーバ Renderingサーバ Renderingサーバ Supervisord APIサーバ

    APIサーバ APIサーバ
  27. Cache ⽃秪חNginxהAppך꟦חmemcached ׾䮠׿דծ $request_uri--$is_mobile ׫׋ְז䠬 ׄךؗ٦ד⥂㶷׃גⱄⵃ欽կ

  28. Nginx memcached Node $host$request_uri--$is_mobile ׾ؗ٦חٍؗحءُ׾嗚稊 זֽ׸לٖٝتؚٔٝ x-memcached-keyח memcachedךؗ٦׾إحز x-memcached-keyقحت ך⦼׾ؗ٦ח⥂㶷

  29. SEO react-lazyload׾⢪׏גְ׋ךדծ GoogleװBotך،ؙإأך㜥さכ lazyload׾㐣תׇזְ穠卓׾鵤ׅ״ֲ חծ react-lazyload׾ٓحف׃׋؝ٝه٦ طٝز׾⢪׏׋կ

  30. public render() {! return !this.props.shouldRenderStatic! && this.props.isMobile ? (! <LazyLoad

    {...this.props}>! {this.props.children}! </LazyLoad>! ) : this.props.children;! }!
  31. תה׭ SSRכװ׏ם׉׸ז׶ח؝أزָ䱦ַ׷ז֭הְֲ䠬䟝կ 葿ղ孡׾⢪ֲֿה׮㢳ְ׃ծ 劤䔲ח䗳銲חז׷תדכװ׷ץֹדכזְկ 暴חؿٗٝزؒٝسך؝٦سָ؟٦غד׮⹛ֻךדծ䌢ח➙ـٓؐ ؠזךַNodeJSזךַ䠐陎ׅ׷ךָ꬗⦜׌׏׋կ ׀幠耮֮׶ָהֲ׀ְׂת׃׋կ