Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

Angular Universal on Google App Engine

Angular Universal on Google App Engine

東京Node学園祭2018での発表資料です。

Kenji Imamula

November 23, 2018
Tweet

More Decks by Kenji Imamula

Other Decks in Technology

Transcript

  1. Angular Universal on Google App Engine   ౦ژNodeֶԂࡇ2018 2018/11/23

    גࣜձࣾΧϒΫ ࠓଜݠ࢜ @kimamula ˞("&੒෼߇͑Ί
  2. Topics 1. What is Angular Universal 2. How to Angular

    Universal 3. Hack Angular Universal  
  3. Google App EngineͱNode.js • 2018/06ɺSE (Standard Environment)Ͱ Node.jsΞϓϦͷσϓϩΠ͕Մೳʹ • ͨͩ͠ϕʔλ

    • Node.js 8, 10ʹରԠ • majorόʔδϣϯΛࢦఆͯ͠σϓϩΠ • minor, patchόʔδϣϯ͸উखʹ্͕Δ࢓༷  
  4. Quick Start Prerequisite: Angular CLI ؆୯ʂʂ $ ng new my-project

    $ cd my-project $ ng add @nguniversal/express-engine --clientProject my-project $ npm run build:ssr && npm run serve:ssr # … Node Express server listening on http://localhost:4000  
  5. isPlatformBrowser, isPlatformServer import { PLATFORM_ID } from '@angular/core'; import {

    isPlatformBrowser, isPlatformServer } from '@angular/common'; constructor( @Inject(PLATFORM_ID) private platformId: Object ) {} ngOnInit() { if (isPlatformBrowser(this.platformId)) { // Client only code. } if (isPlatformServer(this.platformId)) { // Server only code. } }  
  6. Transferstate: αʔόʔ import { TransferState } from '@angular/platform-browser'; import {

    TRANSFER_STATE_KEY } from './transfer-state-key'; constructor(transferState: TransferState) { // … transferState.onSerialize(TRANSFER_STATE_KEY, () => { return state; }); } import { makeStateKey } from '@angular/platform-browser'; export const TRANSFER_STATE_KEY = makeStateKey('MY_KEY'); ঢ়ଶڞ༗ͷͨΊ ͷΩʔͷ࡞੒ ԿΒ͔ͷํ๏ͰΞϓϦέʔγϣϯͷ ঢ়ଶΛऔಘͯ͠ฦ͢ʢFH/H3Yʣ  
  7. Transferstate: ΫϥΠΞϯτ import { TransferState } from '@angular/platform-browser'; import {

    TRANSFER_STATE_KEY } from './transfer-state-key'; constructor(transferState: TransferState) { if (transferState.hasKey(TRANSFER_STATE_KEY)) { const state = transferState.get( TRANSFER_STATE_KEY, defaultValue ); this.transferState.remove(TRANSFER_STATE_KEY); } } ౉͞Εͨ ঢ়ଶͷऔಘ  
  8. styles.cssͷSSR: ໰୊ • ίϯϙʔωϯτ͝ͱͷCSS • SSR͞ΕΔʢHTMLʹΠϯϥΠϯల։͞Ε Δʣ -> ॳظදࣔͷ࣌఺Ͱਖ਼͘͠ద༻͞ΕΔ •

    styles.cssʢάϩʔόϧͳCSSʣ • SSR͞ΕͣɺJSͷॲཧͷதͰΠϯϥΠϯల։ ͞ΕΔ -> ద༻·Ͱʹϥά͕Ͱ͖Δ  
  9. DX with a SSR Angular app ެࣜͷखॱʹهࡌͷscript͚ͩΛ࢖͏৔߹ 1.ίʔυฤू 2.खಈͰϏϧυίϚϯυ࣮ߦ •

    1͔ΒϏϧυͳͷͰΠϯΫϦϝϯλϧ͡Όͳ͍ 3.खಈͰNode.jsαʔόʔ࠶ىಈ 4.खಈͰϒϥ΢βϦϩʔυ  
  10. How to prerender universal-starterϦϙδτϦͷprerender.tsΑΓൈਮʢҰ෦վมʣ ['/', '/lazy', '/lazy/nested'].forEach(route => { const

    fullPath = join(BROWSER_FOLDER, route); previousRender = previousRender .then(_ => renderModuleFactory(AppServerModuleNgFactory, { document: index, url: route, extraProviders: [ provideModuleMap(LAZY_MODULE_MAP) ] }) ).then(html => writeFileSync(join(fullPath, 'index.html'), html) ); });  
  11. How to prerender universal-starterϦϙδτϦͷprerender.tsΑΓൈਮʢҰ෦վมʣ   ['/', '/lazy', '/lazy/nested'].forEach(route =>

    { const fullPath = join(BROWSER_FOLDER, route); previousRender = previousRender .then(_ => renderModuleFactory(AppServerModuleNgFactory, { document: index, url: route, extraProviders: [ provideModuleMap(LAZY_MODULE_MAP) ] }) ).then(html => writeFileSync(join(fullPath, 'index.html'), html) ); }); QSFSFOEFS ͢ΔύεͷҰཡ ύεʹର͢Δ )5.-Λੜ੒ ੜ੒͞Εͨ)5.-Λ ϑΝΠϧʹग़ྗ
  12. CSR vs SSR vs Prerender $43 443 1SFSFOEFS ΫϥΠΞϯτ ෛՙ

    º ̋ ̋ αʔόʔ ෛՙ ̋ º ̋ ॊೈੑ ̋ ̋ º  
  13. CSR vs SSR vs Prerender $43 443 1SFSFOEFS ΫϥΠΞϯτ ෛՙ

    º ̋ ̋ αʔόʔ ෛՙ ̋ º ̋ ॊೈੑ ̋ ̋ º ͜͜Λ̋ʹ Ͱ͖ͳ͍͔  
  14. ಈతίϯςϯπͷPrerender Server • ೝূ • ೝՄ • ݴޠ ౳ͷ൑ఆ /some/path

    PrerenderࡁΈHTML ঢ়گʹԠͯ͡ద੾ͳ HTMLΛฦ͢ ͜͏͍͏͜ͱ͕Ͱ͖ͨΒૉఢ͔΋…ʁ ʢݕ౼தʣ  
  15. HTTP/2 Server Push 4FSWFS #SPXTFS GET /css1.css Without Push 4FSWFS

    #SPXTFS GET /index.html Index.html With Push /css1.css (push) GET /index.html Index.html /css1.css  
  16. ࡞ͬͯΈΔ 2௨Γͷ࡞Γํ • Preload link headersΛ࢖͏ํ๏ -> ࠾༻ • ؆୯ʢৄࡉ͸࣍ͷεϥΠυͰʣ

    • Node.jsͷAPI Λ࢖͏ํ๏ • v10Ͱexperimentalϑϥάͳ͠Ͱ࢖͑Δ Α͏ʹͳͬͨ • ExpressͰͷ࢖͍উख͕ࠓͻͱͭ  
  17. Preload link headers 3FWFSTF QSPYZ #SPXTFS GET /index.html Index.html /css1.css

    (push) /PEFKT GET /index.html Index.html Link: </css1.css>; rel=preload;