เริ่มต้นกับ Meteor

2

แปลไปแล้ว

ในบทนี้ คุณจะได้

  • ติดตั้ง Meteor
  • รู้จักกับแพ็คเกจ Meteor แบบต่างๆ
  • จัดโครงสร้างโฟลเดอร์ให้แอพ Meteor ของคุณ.
  • Meteor จะทำให้คุณประทับใจตั้งแต่แรกพบ ขั้นตอนการติดตั้งทำได้ง่ายๆ เพียงไม่เกินห้านาที คุณก็พร้อมใช้งานได้แล้ว

    ถ้าคุณใช้ Mac หรือ Linux คุณสามารถติดตั้ง Meteor โดยเปิดโปรแกรมเทอร์มินัล และป้อนคำสั่งนี้

    curl https://install.meteor.com | sh
    

    แต่ถ้าคุณใช้ Windows ให้คุณทำตาม คำแนะนำการติดตั้ง จากเว็บไซต์ Meteor ได้เลย

    เมื่อทำเสร็จแล้ว คุณก็จะได้โปรแกรม meteor ที่พร้อมใช้งานบนเครื่องของคุณ

    ใช้ Meteor โดยไม่ต้องติดตั้ง

    ถ้าหากคุณไม่สามารถติดตั้ง (หรือไม่ต้องการติดตั้ง) Meteor ลงบนเครื่อง คุณก็น่าจะลองใช้ Nitrous.io ดูนะ

    Nitrous.io เป็นบริการที่ช่วยให้คุณสามารถรันแอพและแก้ไขโค้ดจากเบราว์เซอร์ได้โดยตรง ซึ่งทางเราได้เตรียม คู่มือการใช้งานฉบับย่อ ไว้ให้แล้ว

    คุณก็แค่ทำตามคู่มือนั้นจนจบหัวข้อ “Installing Meteor” แล้วกลับมาอ่านต่อที่ “ลองสร้างแอพแบบง่ายๆกัน” ในบทนี้ได้เลย

    ลองสร้างแอพแบบง่ายๆกัน

    เมื่อ Meteor พร้อมแล้ว ก็ถึงเวลาที่เราจะมาสร้างแอพกัน เริ่มต้นด้วยการเรียกใช้คำสั่ง meteor ดังนี้

    meteor create microscope
    

    คำสั่งนี้เป็นการบอกให้ Meteor ทำการดาวน์โหลดไฟล์ที่จำเป็นและสร้างแอพพื้นฐานให้เรา เมื่อเสร็จเรียบร้อยคุณก็จะได้โฟลเดอร์ microscope/ ที่ประกอบด้วยไฟล์ต่อไปนี้

    .meteor
    microscope.css  
    microscope.html 
    microscope.js   
    

    โดยแอพที่ Meteor สร้างให้เรานั้น เป็นแอพตัวอย่างที่มีการทำงานแบบง่ายๆ

    ถึงแม้ว่ามันจะทำงานอะไรได้ไม่มากนัก เราก็ยังสามารถรันมันได้ ที่คุณต้องทำก็แค่ป้อนคำสั่งต่อไปนี้ที่หน้าต่างเทอร์มินัล

    cd microscope
    meteor
    

    จากนั้นก็เปิดเบราว์เซอร์ไปที่ http://localhost:3000/ (หรือที่ http://0.0.0.0:3000) คุณก็น่าจะเห็นอะไรคล้ายๆแบบนี้

    Meteor's Hello World.
    Meteor’s Hello World.

    คอมมิท 2-1

    Created basic microscope project.

    ยินดีด้วย ! คุณได้สร้างแอพ Meteor ตัวแรกที่ใช้งานได้แล้ว ถ้าจะปิดมันคุณก็แค่กด ctrl+c ในหน้าต่างเทอร์มินัลที่คุณรันมันไว้ ก็เรียบร้อย

    และถ้าคุณใช้ Git อยู่ ก็ถึงเวลาที่คุณควรสร้าง repository ด้วยคำสั่ง git init ได้แล้ว

    ลาก่อนนะ Meteorite

    ก่อนหน้านี้การใช้งาน Meteor ยังต้องพึ่งพาโปรแกรมจัดการแพ็คเกจที่เราเรียกว่า Meteorite แต่หลังจากเวอร์ชัน 0.9.0 เป็นต้นมา ก็ไม่จำเป็นอีกต่อไป เนื่องจากคุณสมบัติต่างๆของ Meteorite ได้ถูกรวมเข้าเป็นส่วนหนึ่งของ Meteor แล้ว

    ถ้าคุณเผอิญไปเจอตรงไหนในหนังสือหรือในเอกสารที่เกี่ยวข้องกับ Meteor ที่อ้างถึงคำสั่ง mrt ของ Meteorite แล้วล่ะก็ ให้คุณใช้คำสั่ง meteor แทนได้เลย

    การเพิ่มแพ็คเกจ

    ขั้นตอนต่อไป เราจะลองใช้ระบบจัดการแพ็คเกจของ Meteor เพิ่มเฟรมเวิร์ก Bootstrap เข้าไปในแอพของเรา

    ซึ่งอันที่จริงแล้ว ก็ไม่แตกต่างอะไรกับการที่เราจะก๊อปไฟล์ CSS และ JavaScript จาก Bootstrap มาลงเอง เว้นเสียแต่ว่าในกรณีนี้เรามีผู้ดูแลแพ็คเกจที่คอยอัพเดทแพ็คเกจนี้ให้เราอยู่เสมอ

    ยังมีแพ็คเกจอีกตัวที่เราจะเพิ่มเข้าไปในแอพคือ Underscore ซึ่งเป็นแพคเกจรวบรวมฟังก์ชันสำคัญๆ เอาไว้ใช้จัดการกับข้อมูลแบบต่างๆของจาวาสคริปต์

    โดยแพ็คเกจ bootstrap ตัวนี้ สร้างและดูแลโดยผู้ใช้ชื่อ twbs มีชื่อเต็มของแพ็คเกจว่า twbs:bootstrap

    ส่วนแพคเกจ underscore ก็เป็นส่วนหนึ่งของแพคเกจอย่างเป็นทางการของ Meteor และมาพร้อมกับเฟรมเวิร์กอยู่แล้ว จึงไม่ระบุชื่อผู้สร้าง

    meteor add twbs:bootstrap
    meteor add underscore
    

    ให้สังเกตว่าแพคเกจที่เราเพิ่มเป็น Bootstrap 3 แต่ภาพหน้าจอในหนังสือบางภาพได้มาจาก Microscope เวอร์ชันเก่าที่ยังใช้ Bootstrap 2 อยู่ จึงอาจจะมีความแตกต่างกันอยู่บ้าง

    คอมมิท 2-2

    Added bootstrap and underscore packages.

    หลังจากที่คุณเพิ่มแพคเกจ Bootstrap เข้ามา คุณก็จะสังเกตเห็นความเปลี่ยนแปลงของแอพได้ ดังภาพ

    With Bootstrap.
    With Bootstrap.

    สิ่งที่ไม่เหมือนกับวิธีการเดิมๆ ที่เราเคยทำหลังจากเพิ่มไฟล์ต่างๆเข้ามาในแอพแล้ว ก็คือเราไม่ต้องผูกทั้งไฟล์ CSS และไฟล์จาวาสคริปต์เข้ากับแอพแต่อย่างใด ทั้งนี้เพราะ Meteor จัดการเรื่องทั้งหมดให้เรา ! และนี่ก็คือข้อดีข้อหนึ่งของการใช้แพ็คเกจใน Meteor

    รู้จักกับแพ็คเกจชนิดต่างๆ

    เมื่อพูดถึงแพ็คเกจในโลกของ Meteor จะพบว่าสามารถแบ่งออกได้เป็น 5 ประเภทด้วยกัน คือ

    • แพ็คเกจหลัก (Platform package) คือกลุ่มแพ็คเกจที่ประกอบกันขึ้นเป็น Meteor และบรรจุไว้ในแอพ Meteor ทุกตัว โดยที่คุณไม่ต้องจัดการอะไรเพิ่มเติม
    • แพ็คเกจปกติ (Regular package) หรือที่รู้จักกันในชื่อ “ไอโซแพ็ค (isopacks)” คือแพ็คเกจที่สามารถใช้งานได้กับโค้ดทั้งฝั่งไคลเอนต์และฝั่งเซิร์ฟเวอร์ เราเรียกไอโซแพคที่พัฒนาโดยทีมงาน Meteor และมาพร้อมกับ Meteor ว่า แพ็คเกจ First-party เช่น accounts-ui หรือ appcache
    • ส่วน แพ็คเกจ Third-party ก็คือไอโซแพ็คอีกแบบหนึ่ง ที่พัฒนาโดยผู้ใช้รายอื่นและส่งขึ้นไปเก็บไว้ที่เซิร์ฟเวอร์จัดการแพ็คเกจของ Meteor ที่คุณสามารถเข้าไปค้นหาได้จากเว็บ Atmosphere หรือจากคำสัั่ง meteor search
    • แพ็คเกจ Local คือ แพ็คเกจที่คุณสร้างขึ้นใช้เองและเก็บไว้ในโฟลเดอร์ /packages
    • แพ็คเกจ NPM (Node.js Packaged Module) คือแพ็คเกจของ Node.js ซึ่งแม้ว่าเราจะไม่สามารถเรียกใช้งานจาก Meteor ได้โดยตรง แต่ก็สามารถเรียกใช้ได้จากแพ็คเกจแบบอื่นๆข้างต้นได้

    โครงสร้างโฟลเดอร์ของแอพ Meteor

    ก่อนจะเริ่มเขียนโค้ดกัน เราควรจัดการแอพให้เข้าที่เข้าทางซะก่อน และเพื่อให้มั่นใจว่า จะไม่มีส่วนเกินอะไรติดมา ให้เราเปิดโฟลเดอร์ microscope และลบไฟล์ microscope.html microscope.js และ microscope.css ทั้งหมดทิ้งไปซะ

    จากนั้นให้สร้างโฟลเดอร์ย่อยขึ้นใน /microscope ทั้งหมด 4 โฟลเดอร์ คือ /client /server /public และ /lib

    ต่อมา ให้สร้างไฟล์ว่างๆชื่อ main.html และ main.js ในโฟลเดอร์ /client โดยไม่ต้องกลัวว่าแอพจะรันไม่ได้ เพราะในบทต่อไปเราก็จะเริ่มเขียนโค้ดลงในไฟล์สองตัวนี้

    สิ่งที่เราคงต้องพูดถึงก่อน คือความพิเศษของโฟลเดอร์บางตัว ที่มีผลต่อการทำงานของแอพ โดย Meteor มีกฎเบื้องต้นดังนี้

    • โค้ดในโฟลเดอร์ /server จะทำงานที่ฝั่งเซิร์ฟเวอร์เท่านั้น
    • โค้ดในโฟลเดอร์ /client จะทำงานที่ฝั่งไคลเอนต์เท่านั้น
    • โค้ดในที่อื่นๆ จะทำงานได้ทั้งบนฝั่งเซิร์ฟเวอร์และฝั่งไคลเอนต์
    • ไฟล์อื่นๆ (ฟอนต์ ภาพ ฯลฯ) ต้องเก็บไว้ที่โฟลเดอร์ /public

    และที่เราควรรู้คือ ลำดับการโหลดไฟล์ของ Meteor จะเป็นไปดังนี้

    • ไฟล์ใน /lib จะถูกโหลด ก่อน ไฟล์อื่น
    • ไฟล์ main.* จะถูกโหลด หลัง ไฟล์อื่น
    • ไฟล์อื่นๆนอกจากนี้ จะถูกโหลดตามลำดับของตัวอักษรในชื่อไฟล์

    ถึงแม้ว่าจะมีกฎเกณฑ์แบบนี้ แต่ Meteor ก็ไม่ได้บังคับให้คุณต้องใช้โครงสร้างโฟลเดอร์ตามที่กำหนดหากคุณไม่ต้องการ อีกทั้งรูปแบบที่เราแนะนำไป ก็เป็นแค่วิธีที่เราใช้ ไม่ใช่อะไรที่ตายตัว

    ถ้าคุณยังต้องการรายละเอียดที่มากกว่านี้ เราอยากให้คุณไปดูที่ หน้าเอกสารของ Meteor

    Meteor เป็น MVC มั้ย

    ถ้าคุณเคยใช้เฟรมเวิร์กอื่นเช่น Ruby on Rails มาก่อน แล้วเพิ่งมาใช้ Meteor คุณคงสงสัยว่า Meteor ได้นำรูปแบบ MVC (Model View Controller) มาใช้ในแอพหรือไม่

    คำตอบสั้นๆ ก็คือ ไม่

    ที่ไม่เหมือน Rails ก็คือ Meteor ไม่ได้กำหนดโครงสร้างอะไรกับแอพของคุณ และในหนังสือเล่มนี้ เราก็แค่วางรูปแบบโค้ดที่มันสมเหตุสมผล โดยไม่ต้องมีตัวย่อต่างๆมาทำให้เราวุ่นวาย

    ไม่มีโฟลเดอร์ public เลย

    จริงๆแล้ว เราหลอกคุณ

    เหตุผลง่ายๆ ที่ไม่จำเป็นต้องมีโฟลเดอร์ public/ ก็เพราะว่า Microscope ไม่มีไฟล์แบบอื่นๆเลย แต่เนื่องจากแอพของ Meteor ส่วนมากจะต้องมีภาพบ้างอย่างน้อยก็หนึ่งภาพ เราเลยคิดว่า มีไว้ก็น่าจะดีกว่าไม่มี

    ก่อนที่จะลืม คุณอาจสังเกตเห็นโฟลเดอร์ .meteor ที่ซ่อนอยู่ ซึ่ง Meteor ใช้เก็บโค้ดของตัวมันเอง เราจึงไม่ควรแก้ไขอะไรข้างในนั้น ว่าไปแล้วคุณไม่จำเป็นต้องสนใจมันเลยก็ได้ จะมีก็แต่ไฟล์ .meteor/packages และ .meteor/release ที่ใช้เก็บรายชื่อแพ็คเกจ และเวอร์ชันของ Meteor ที่ใช้อยู่ เมื่อไรก็ตามที่คุณเพิ่มแพ็คเกจและปรับรุ่น Meteor แล้วละก็ คุณอาจจำเป็นต้องตรวจสอบการเปลี่ยนแปลงในไฟล์พวกนี้

    Underscores กับ CamelCase

    สิ่งเดียวที่เราจะพูดถึงเกี่ยวกับการตั้งชื่อตัวแปร ทั้งแบบ underscore (my_variable) และแบบ camelCase (myVariable) ก็คือ ไม่ว่าคุณจะใช้แบบไหน มันก็ไม่มีผลอะไร ตราบใดที่คุณยังคงใช้แบบนั้นอยู่

    ในหนังสือเล่มนี้ เราใช้ camelCase ก็เพราะว่ามันเป็นเรื่องปกติในจาวาสคริปต์ (ที่เห็นชัดๆ ก็คือ คงไม่มีใครเขียน JavaScript ว่า java_script แน่ๆ !)

    แต่มีข้อยกเว้นเพียงประการเดียวกับกฎเกณฑ์นี้ก็คือ ชื่อไฟล์เราจะใช้ ตัวอักษรขีดล่าง (เช่น my_file.js) ส่วนคลาสใน CSS เราจะใช้ เครื่องหมายลบ (เช่น .my-class) เหตุผลก็คือ ตัวอักษรขีดล่างถูกใช้กับระบบไฟล์มากที่สุด ในขณะที่ CSS เองก็ใช้เครื่องหมายลบกันอยู่แล้ว (font-family text-align ฯลฯ)

    ใส่ใจกับ CSS

    หนังสือเล่มนี้ไม่เกี่ยวกับ CSS ดังนั้นเพื่อไม่ให้คุณเสียเวลา เราจึงตัดสินใจสร้าง stylesheet ทั้งหมดให้พร้อมใช้ไว้ตั้งแต่แรก เพื่อที่คุณจะได้ไม่ต้องกังวลกับมันอีก

    โดยไฟล์ CSS นั้นจะถูกโหลดและทำให้เล็กลงอย่างอัตโนมัติด้วย Meteor และคุณควรเก็บมันไว้ในโฟลเดอร์ /client ไม่ใช่ใน /public เหมือนกับไฟล์ชนิดอื่นๆ

    ที่คุณต้องทำต่อคือ สร้างโฟลเดอร์ client/stylesheets/ และวางไฟล์ style.css ที่มีข้อมูลตามที่แสดงนี้ไว้ข้างใน

    .grid-block, .main, .post, .comments li, .comment-form {
      background: #fff;
      border-radius: 3px;
      padding: 10px;
      margin-bottom: 10px;
      -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
      -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
      box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15); }
    
    body {
      background: #eee;
      color: #666666; }
    
    #main {
      position: relative;
    }
    .page {
      position: absolute;
      top: 0px;
      width: 100%;
    }
    
    .navbar {
      margin-bottom: 10px; }
      /* line 32, ../sass/style.scss */
      .navbar .navbar-inner {
        border-radius: 0px 0px 3px 3px; }
    
    #spinner {
      height: 300px; }
    
    .post {
      /* For modern browsers */
      /* For IE 6/7 (trigger hasLayout) */
      *zoom: 1;
      position: relative;
      opacity: 1; }
      .post:before, .post:after {
        content: "";
        display: table; }
      .post:after {
        clear: both; }
      .post.invisible {
        opacity: 0; }
      .post.instant {
        -webkit-transition: none;
        -moz-transition: none;
        -o-transition: none;
        transition: none; }
      .post.animate{
        -webkit-transition: all 300ms 0ms;
        -moz-transition: all 300ms 0ms ease-in;
        -o-transition: all 300ms 0ms ease-in;
        transition: all 300ms 0ms ease-in; }
      .post .upvote {
        display: block;
        margin: 7px 12px 0 0;
        float: left; }
      .post .post-content {
        float: left; }
        .post .post-content h3 {
          margin: 0;
          line-height: 1.4;
          font-size: 18px; }
          .post .post-content h3 a {
            display: inline-block;
            margin-right: 5px; }
          .post .post-content h3 span {
            font-weight: normal;
            font-size: 14px;
            display: inline-block;
            color: #aaaaaa; }
        .post .post-content p {
          margin: 0; }
      .post .discuss {
        display: block;
        float: right;
        margin-top: 7px; }
    
    .comments {
      list-style-type: none;
      margin: 0; }
      .comments li h4 {
        font-size: 16px;
        margin: 0; }
        .comments li h4 .date {
          font-size: 12px;
          font-weight: normal; }
        .comments li h4 a {
          font-size: 12px; }
      .comments li p:last-child {
        margin-bottom: 0; }
    
    .dropdown-menu span {
      display: block;
      padding: 3px 20px;
      clear: both;
      line-height: 20px;
      color: #bbb;
      white-space: nowrap; }
    
    .load-more {
      display: block;
      border-radius: 3px;
      background: rgba(0, 0, 0, 0.05);
      text-align: center;
      height: 60px;
      line-height: 60px;
      margin-bottom: 10px; }
      .load-more:hover {
        text-decoration: none;
        background: rgba(0, 0, 0, 0.1); }
    
    .posts .spinner-container{
      position: relative;
      height: 100px;
    }
    
    .jumbotron{
      text-align: center;
    }
    .jumbotron h2{
      font-size: 60px;
      font-weight: 100;
    }
    
    @-webkit-keyframes fadeOut {
      0% {opacity: 0;}
      10% {opacity: 1;}
      90% {opacity: 1;}
      100% {opacity: 0;}
    }
    
    @keyframes fadeOut {
      0% {opacity: 0;}
      10% {opacity: 1;}
      90% {opacity: 1;}
      100% {opacity: 0;}
    }
    
    .errors{
      position: fixed;
      z-index: 10000;
      padding: 10px;
      top: 0px;
      left: 0px;
      right: 0px;
      bottom: 0px;
      pointer-events: none;
    }
    .alert {
              animation: fadeOut 2700ms ease-in 0s 1 forwards;
      -webkit-animation: fadeOut 2700ms ease-in 0s 1 forwards;
         -moz-animation: fadeOut 2700ms ease-in 0s 1 forwards;
      width: 250px;
      float: right;
      clear: both;
      margin-bottom: 5px;
      pointer-events: auto;
    }
    
    client/stylesheets/style.css

    คอมมิท 2-3

    Re-arranged file structure.

    ใช้ CoffeeScript ได้มั้ย

    ในหนังสือเล่มนี้ เราจะเขียนแอพกันด้วยจาวาสคริปต์ แต่ถ้าคุณต้องการใช้ CoffeeScript ก็สามารถทำได้โดยเพิ่มแพ็คเกจ CoffeeScript เข้าไปในแอพตามคำสั่งข้างล่างนี้ จากนั้นคุณก็ลุยต่อได้เลย

    meteor add coffeescript