JavaScriptフロントエンド開発の昨今

B4afc7d853d7f1cb6a253d3c7183c05a?s=47 Naoya Ito
October 10, 2013

 JavaScriptフロントエンド開発の昨今

B4afc7d853d7f1cb6a253d3c7183c05a?s=128

Naoya Ito

October 10, 2013
Tweet

Transcript

  1. +BWB4DSJQUϑϩϯτΤϯυ ։ൃͷࡢࠓ !OBPZB@JUP

  2. ͜Μʹͪ͸

  3. ࿩ͷྲྀΕ •  )5.-ΞϓϦέʔγϣϯΞηϯϒϥ •  ˢΛݟΔͱ+4։ൃͷτϨϯυ͕Θ͔Δ •  .7˓ϑϨʔϜϫʔΫ •  ςετ • 

    ·ͱΊϑϩϯτΤϯυ։ൃ࣮ࡍͷͱ͜Ζ
  4. ΞϓϦέʔγϣϯαΠτΞηϯϒϥ ϑϩϯτΤϯυΞϓϦέʔγϣϯ੩తαΠτͷ ఆ൪ΞηοτΛ·ͱΊͯηοτΞοϓ $  middleman  init  -­‐–template=slim

  5. .JEEMFNBOͰͰ͖ͯ·͢

  6. ˓˓Ξηϯϒϥ •  NBTN HBT •  αΠτΞηϯϒϥ – .JEEMFNBO •  ελςΟοΫαΠτδΣωϨʔλ • 

    ΞϓϦέʔγϣϯΞηϯϒϥ – :FPNBO #SVODIJP •  +BWB4DSJQUΞϓϦέʔγϣϯʹൺॏ
  7. None
  8. None
  9. ZPXFCBQQ

  10. $  yo  webapp   $  grunt  server   $  grunt

     test   $  grunt  build   
  11. None
  12. :FPNBOHFOFSBUPSXFCBQQ •  (SVOUpMFKT •  CPXFSSD •  #PPUTUSBQGPS4BTT •  3FRVJSF+4 • 

    .PEFSOJ[S •  
  13. ΞϓϦέʔγϣϯΞηϯϒϥͷ࣮ࡍ •  ։ൃ΍ͬͯΔͱͦͷ͏ͪඞཁʹͳΔಓ۩͕ ೖ͍ͬͯΔ – ϕετɾϓϥΫςΟε •  ͢ͳΘͪߏ੒͔ΒτϨϯυ͕ݟ͑Δ

  14. :FPNBOͷߏ੒ཁૉ •  (SVOUλεΫϥϯφʔ •  #PXFSύοέʔδ؅ཧ •  :P4DB⒎PME Ξηοτͷੜ੒ 

  15. (SVOU

  16. (SVOUͬͯ  •  /PEFKTϕʔεͷλεΫϥϯφʔ – $P⒎FF΍4BTTΛίϯύΠϧ͢Δ – ϛχϑΝΠ͢Δ – ಈ࡞֬ೝ༻ͷ)551αʔόʔ্ཱͪ͛Δ – -JWF3FMPBEͰߋ৽ʹ߹Θͤͯϒϥ΢βΛࣗ ಈͰϦϩʔυ͢Δ – σϓϩΠ༻ͷ֤छλεΫΛ·ͱΊ࣮ͯߦ͢Δ

  17. None
  18. (SVOUʹ͍ͭͯৄ͘͠͸ŋŋŋ ൃചͷ8&# %#13&44Λ଴ͯ

  19. None
  20. #PXFS •  ϥΠϒϥϦͷόʔδϣϯɾґଘؔ܎؅ཧ – ཁ͸ϑϩϯτΤϯυΞϓϦ༻ͷ#VOEMFS $  cat  bower.json   {  

       "name":  "myapp",      "version":  "0.0.0",      "dependencies":  {          "sass-­‐bootstrap":  "~3.0.0",          "requirejs":  "~2.1.8",          "modernizr":  "~2.6.2",          "jquery":  "~1.10.2"      },      "devDependencies":  {}   }   $  bower  install
  21. /PEFKT ŋŋŋͱ͍͏Θ͚Ͱ࠷ۙͷϑϩϯτΤϯυ։ൃ ͸/PEFKTʹΑͬͯࢧ͑ΒΕ͍ͯ·͢

  22. :FPNBOHFOFSBUPS •  ZPHFOFSBUPSOBNF •  ͍Ζ͍Ζ͋Δ

  23. "OHVMBS+4ͷ͕Ұ൪ਓؾ

  24. HFOFSBUPSBOHVMBS •  "OHVMBS+4.7 ϑϨʔϜϫʔΫ •  ςετؔ࿈ –  LBSNBϦϞʔτςετϥϯφʔ –  +BTNJOFςεςΟϯάϑϨʔϜϫʔΫ

    –  1IBOUPN+4ϔουϨεϒϥ΢β –  USBWJTZNMܧଓతΠϯςάϨʔγϣϯ •  (SVOUpMFKT •  CPXFSSD •  KTIJOUSD •  FEJUPSDPOpH
  25. ͳΜ͔͍Ζ͍Ζ͋Γ·͢Ͷ

  26. .7˓ϑϨʔϜϫʔΫ ͔Βݟ͍͖ͯ·͠ΐ͏

  27. .7˓ϑϨʔϜϫʔΫ h"p://www.slideshare.net/OmasaYusaku/angular-­‐js-­‐orbackbonejs

  28. h"p://wazanova.jp/post/63527486760/ruby-­‐on-­‐rails-­‐angularjs-­‐node-­‐js

  29. JO 0DU ͋Μ·Γ ؾʹ͠ͳ͍

  30. ͳͥ.7˓ϑϨʔϜϫʔΫ  •  γϯάϧϖʔδΞϓϦέʔγϣϯ  •  K2VFSZ஍ࠈ  •  όϦσʔγϣϯ

     •  QVTI4UBUF  
  31. σʔλόΠϯσΟϯά͕ॏཁ ˞ݸਓతݟղͰ͋ΓࣾΛ୅ද͢ΔҎԼུ

  32. ཁ͸ɺ͜Ε͕͍ͨ͠ Model View View Ϟσϧ͕มߋ͞ΕͨΒŋŋŋ ը໘Λߋ৽ ը໘Λߋ৽ ੲͱҧͬͯ+4Ͱը໘͙Γ͙Γߋ৽͢ΔΑ͏ʹͳͬͨ͠ Πϕϯτ

  33. None
  34. #BDLCPOFKT.PEFMͱ 7JFXͷόΠϯυ class  TagsView  extends  Backbone.View      tagName:  'ul'

           initialize:  ()  -­‐>          @listenTo  @collection,  'add',  @addTag        addTag:  (tag)  -­‐>          tagView  =  new  TagView  model:tag          @$el.append  tagView.render().el        render:          @collection.each  (tag)  =>  @addTag  tag          return  @     #  Tags  extends  Backbone.Collection   tags  =  new  Tags  []   tagsView  =  new  TagsView  collection:tags     $('#tags-­‐view').html  tagsView.render().el
  35. TagsView   Backbone.View Tags   Backbone.Collection ೖྗΠϕϯτ Ϟσϧߋ৽Πϕϯτ

  36. None
  37. "OHVMBS+4૒ํ޲σʔλόΠ ϯσΟϯά <ul>      <li  ng-­‐repeat="todo  in  todo_list">  

           <input  type="checkbox"  ng-­‐model="todo.state"  />  {{todo.title}}      </li>   </ul> var  controller  =  app.controller('TodoCtrl',  function  ($scope,  todo_list)  {      $scope.todo_list  =  todo_list;      $scope.addTodo  =  function()  {          $scope.todo_list.push(                {  "title":  $scope.todo.title,  "state":  $scope.todo.state  }            );      };       });  
  38. <li  ng-­‐repeat="todo  in  todo_list">      {{todo.title}}   </li> $scope.

      todo_list όΠϯυ
  39. +4.7˓ϑϨʔϜϫʔΫ •  ݸਓతͳݟཱͯͰ͸ŋŋŋ –  ʮ.ˠ7΁ͷ௨஌ʯͷύλʔϯΛओ࣠ʹपลΛݻΊͨ΋ͷ •  όΠϯσΟϯάΛ͠΍͘͢㱺ΞϓϦέʔγϣϯߏ଄Խ •  ͦͷ΄͔ศརػೳ – 

    ϧʔςΟϯά –  ςϯϓϨʔτ –  όϦσʔγϣϯ –  ը໘ભҠ •  ΑͬͯɺσʔλϞσϧͷߋ৽ʹରͯ͠ը໘͕Ͳͷఔ౓ͲͷΑ ͏ʹ࿈ಈ͢Δඞཁ͕͋Δ͔ɺͱ͍͏ࢹ఺Ͱબఆ͢Δͱྑ͍
  40. ૄ݁߹Λࢧ͑Δٕज़ •  #BDLCPOFKT –  0CTFSWFSʹΑΔ.PEFM7JFXͷ෼཭ –  #BDLCPOFKTͷ௨஌ύλʔϯ •  "OHVMBS+4 – 

    ૒ํ޲σʔλόΠϯσΟϯά –  %FQFOEFODZ*OKFDUJPO –  ϑϨʔϜϫʔΫͷڧΊͷ੍໿ •  &NCFSKT –  ͳΜ͔σʔλόΠϯσΟϯάपΓ͕͍͚ͯΔΒ͍͠ •  0CKFDUPCTFSWF  –  J04ͷ,70Έ͍ͨͳͷɻ࣍ੈ୅+BWB4DSJQU –  ݱঢ়Ͳ͏ͳͬͯΔΜͰ͠ΐ͏ 
  41. ςετ͠қ͘ͳͬͪΌ͍·ͨ͠ ͱ͜ΖͰΞϓϦέʔγϣϯߏ଄ԽʹΑͬͯ

  42. ͦ͏ͩɺ +4΋ ςετ͠Α͏

  43. HFOFSBUPSBOHVMBS •  "OHVMBS+4.7 ϑϨʔϜϫʔΫ •  ςετؔ࿈ –  LBSNBϦϞʔτςετϥϯφʔ –  +BTNJOFςεςΟϯάϑϨʔϜϫʔΫ

    –  1IBOUPN+4ϔουϨεϒϥ΢β –  USBWJTZNMܧଓతΠϯςάϨʔγϣϯ •  (SVOUpMFKT •  CPXFSSD •  KTIJOUSD •  FEJUPSDPOpH
  44. ϞοΫ   ϥΠϒϥϦ Ξαʔγϣϯ   ϥΠϒϥϦ ςεςΟϯά   ϑϨʔϜϫʔΫ ϦϞʔτ

      ςετϥϯφʔ ࣮ߦ   ؀ڥ Jasmine Sinon.JS QUnit,   JsUnit expect.js   Chai Mocha   Testem,  Karma JsTestDriver   Buster.JS ࣮ϒϥ΢β   IE,  Chrome,   FirefoxͳͲ   ϔουϨεϒϥ΢β   PhantomJS   ϒϥ΢βγϛϡϨʔλ   Node.js  +  jsdom   Rhino  +  Envjs   ʰ8&# %#13&447P+BWB4DSJQU׆༻࠷લઢୈճʱΑΓ
  45. ϞοΫ   ϥΠϒϥϦ Ξαʔγϣϯ   ϥΠϒϥϦ ςεςΟϯά   ϑϨʔϜϫʔΫ ϦϞʔτ

      ςετϥϯφʔ ࣮ߦ   ؀ڥ Jasmine Sinon.JS QUnit,   JsUnit expect.js   Chai Mocha   Testem  /  Karma JsTestDriver   Buster.JS ࣮ϒϥ΢β   IE,  Chrome,   FirefoxͳͲ   ϔουϨεϒϥ΢β   PhantomJS   ϒϥ΢βγϛϡϨʔλ   Node.js  +  jsdom   Rhino  +  Envjs  
  46. ϞοΫ   ϥΠϒϥϦ Ξαʔγϣϯ   ϥΠϒϥϦ ςεςΟϯά   ϑϨʔϜϫʔΫ ϦϞʔτ

      ςετϥϯφʔ ࣮ߦ   ؀ڥ Jasmine Sinon.JS QUnit,   JsUnit expect.js   Chai Mocha   Testem  /  Karma JsTestDriver   Buster.JS ࣮ϒϥ΢β   IE,  Chrome,   FirefoxͳͲ   ϔουϨεϒϥ΢β   PhantomJS   ϒϥ΢βγϛϡϨʔλ   Node.js  +  jsdom   Rhino  +  Envjs  
  47. ςεςΟϯάϑϨʔϜϫʔΫ •  #%%ελΠϧ͕ਓؾ Լ͸+BTNJOF  describe('Controller:  TodoCtrl',  function  ()  {

         beforeEach(module('angularApp'));      var  TodoCtrl,  scope;        beforeEach(inject(function($controller,  $rootScope)  {          scope  =  $rootScope.$new();          TodoCtrl  =  $controller('TodoCtrl',  {              $scope:  scope          });      }));        it('should  attach  a  list  of  todos  to  the  scope',  function  ()  {          expect(scope.todo_list.length).toBe(1);      });   });  
  48. +BTNJOF .PDIB •  શ෦ೖΓͷ+BTNJOF •  BHOPTUJDͳ.PDIB – ϞοΫελϒ4JOPO+4 – ΞαʔγϣϯFYQFDUKTɺ$IBJ ࣗ෼͸NPDIB FYQFDUKT

    4JOPO+4Λ࢖ͬͯ·͢
  49. ϦϞʔτςετϥϯφʔ •  ίʔυߋ৽ͷͨͼɺ࣮ϒϥ΢β΍ 1IBOUPN+4Ͱςετ – LBSNB چ5FTUBDVMBS  – UFTUFN ͲͪΒ΋/PEFKTϕʔεͰಉ͡Α͏ͳػೳΛఏڙɻ5FTUBDVMBS͸ͦ ΋ͦ΋"OHVMBS+4ͷͨΊʹ࡞ΒΕͨͷͰɺ"OHVMBS+4ͱηοτͰ

    ࢖ΘΕΔ͜ͱ͕ଟ͍ɺ͔΋ɻ
  50. LBSNB

  51. UFTUFN

  52. LBSNB 5SBWJT$*

  53. USBWJTZNM language:  node_js   node_js:      -­‐  '0.8'  

       -­‐  '0.10'   before_script:      -­‐  'npm  install  -­‐g  bower  grunt-­‐cli'      -­‐  'bower  install'      -­‐  export  DISPLAY=:99.0      -­‐  sh  -­‐e  /etc/init.d/xvfb  start   script:      -­‐  karma  start  -­‐-­‐reporters  dots  -­‐-­‐browsers  Firefox,PhantomJS   -­‐-­‐single-­‐run  
  54. LBSNB JTUBOCVM •  LBSNB͸JTUBOCVM࿈ܞͰΧόϨοδϨϙʔτ Λ؆୯ʹ௥ՃͰ͖Δ

  55. Ϣχοτςετͱ&&ςετ •  Ϣχοτςετ – \LBSNB UFTUFN^ \+BTNJOF .PDIB^ – ϑϨʔϜϫʔΫͷ͓͔͛ͰϞσϧͷςετॻ ͚Δ͠ॻ͘ɻ7JFX͸૬มΘΒͣগ͠೉͍͠ Ͱ͢Ͷ

    •  &&ςετ – ŋŋŋ
  56. None
  57. +4ͷ&&ςετ΋ׂͱΧ δϡΞϧʹॻ͘Έ͍ͨͰ͢ ೝࣝΛվΊ·ͨ͠ŋŋŋ

  58. &&ςετ •  LBSNB Կ͔ – "OHVMBS+4ŋŋŋ&&ςετϑϨʔϜϫʔΫ Λ಺แ •  $BTQFS+4 – 1IBOUPN+4ͷάουϥούʔ – +4ͷ&&ςετ͕+4͚ͩͰ؆୯ʹॻ͚Δŋŋŋ

    •  ςετϑϨʔϜϫʔΫɺΞαʔγϣϯ΋ఏڙͯ͠ ͍Δ •  ϩάΠϯͷ͋ΔςετͳͲ΋؆୯
  59. $BTQFS+4 casper  =  require('casper').create()     ##  amazlet  top  page

      casper.start  'http://app.amazlet.com/',  ()  -­‐>      @echo  @getCurrentUrl()      @echo  @getTitle()      @fill  'form',  keyword:  casper.cli.args[0]      @click  'form  input[type="submit"]'     ##  search  result   casper.then  -­‐>      @echo  @getCurrentUrl()      #  click  on  1st  result  link      @click  'a.minibutton'     ##  get  affiliate  tag  for  first  item   casper.then  -­‐>      @echo  @getCurrentUrl()      @echo  @evaluate  -­‐>          document.getElementById('standard').value     do  casper.run
  60. $BTQFS+4Ͱ&&ςετ casper.test.begin  'トップページから検索して貼り付けHTMLを取得',  7,  (test)  -­‐>      casper.start  'http://app.amazlet.com/',

     -­‐>          test.assertHttpStatus  200          test.assertTitleMatch  /^amazlet/,  "タイトル文字列が期待通り"          test.assertExists  'form',  "メインフォームがある"            @fill  'form',  keyword:  "chef  solo"          @click  'form  input[type="submit"]'        casper.then  -­‐>          test.assertHttpStatus  200          test.assertExists  'p.title',  '検索結果が一つ以上ある'            @click  'a.minibutton'        casper.then  -­‐>          test.assertHttpStatus  200          result  =  @evaluate  -­‐>  document.getElementById('standard').value          test.assertMatch  result,  /^<div/,  'HTMLタグが取得できた'        casper.run  -­‐>          do  test.done  
  61. None
  62. $BTQFS+4Ͱ$* •  $BTQFS+4Ͱ΋$*Մೳ – $BTQFS+4ࣗ৴͸1IBOUPN+4ʹ͔͠ґଘ ͍ͯ͠ͳ͍ – 5SBWJT$*ʹ΋1IBOUPN+4͸ೖͬͯΔ – ΋ͪΖΜ+FOLJOTͰ΋0,

  63. ʮͰ΋Πϯετʔϧͱ͔໘౗ͳΜ Ͱ͠ΐ͏ ʯ $  brew  install  casperjs  -­‐-­‐ devel

  64. ࣮ײ •  :FPNBO৔߹ʹΑΔ •  (SVOUඞਢ •  #PXFSSFRVJSFKT৔߹ʹΑΔ •  ϑϨʔϜϫʔΫجຊ࢖͏ • 

    ςετ – ϦϞʔτςετϥϯφʔඞਢ – Ϣχοτςετ.पΓඞਢ •  .͕ෳࡶͰͳ͍৔߹͸&&͋Ε͹ͦΕͰ͍͍͔ – $*ඞਢ – &&ςετ؆୯ʹͳͬͨ͠ॻ͍ͨํ͕ಘ
  65. ·ͱΊ •  :FPNBO΍#VSODIJP͔ΒτϨϯυ •  /PEFKT͕ࢧ͑Δ •  ϑϨʔϜϫʔΫ͸σʔλόΠϯσΟϯάॏཁ •  +4΋ςετΛॻ͍ͯ$*͢Δ • 

    &&ςετ΋ݱ࣮తʹ –  ͜Μͳʹ؆୯ʹॻ͚Δͱ͸ŋŋŋ •  ϑϩϯτΤϯυ։ൃ͸੒ख़ظʹ –  ͍ͣΕͷπʔϧ؀ڥ΋೉ͳ͘࢖͑·͢