ניסוי ריילס - שימוש ב Vue בלי Build Step

07/12/2024

אחד הטרנדים של ריילס היום הוא לוותר על ה Build Step ולהשתמש רק ב JavaScript. בניסוי היום כתבתי פרויקט ריילס שמשלב את vue כדי לראות איך זה עובד ובמה זה שונה מפרויקט צד-לקוח רגיל.

1. איך Vue עובד ב JavaScript

אנחנו רגילים לכתוב vue בקבצי vue ולהריץ את vite כדי להפוך את הכל ל JavaScript רגיל. אם רוצים לוותר על ה Build Step זה אומר לוותר על קבצי ה vue ולעבור לכתוב קבצי js ו HTML. יצרתי פרויקט ריילס ובתוכו קונטרולר בשם HelloWorld וכתבתי את הקוד הבא בקובץ התבנית viesws/hello_world/index.html.erb:

<div id='app'>
  <h1>HelloWorld#index</h1>
  <p>{{message}}</p>
  <Counter />
  <p>The end</p>
</div>

<script type="module">
  import { createApp, ref } from 'vue'
  import Counter from 'controllers/counter';

  createApp({
    setup() {
      const message = ref('Hello Vue!')
      return {
        message
      }
    }
  })
  .component('counter', Counter)
  .mount('#app')
</script>

יש לנו קובץ HTML עם תגית div בשם app ובתוכה התבנית שהייתי רגיל לרשום בתגית template בקובץ vue. מתחתיו בבלוק הסקריפט אנחנו רואים את הקוד שמייצר את ה"אפליקציה", שזה בעצם קוד ה vue שמתלבש לתוך התבנית. המשתנה message שמוגדר בסקריפט יוזרק לעמוד במקום המחרוזת {{message}} שנמצאת ב HTML.

וכן בגלל שאנחנו ב Rails אפשר היה להשתמש בכל המנגנונים של ERB כדי ליצור את התבנית או לשתול משתנים מקוד צד השרת לתוך קוד הסקריפט שבתבנית.

2. פיתוח קומפוננטה

ב vue חלקים מהקוד שאפשר להשתמש בהם בכמה מקומות נקראים קומפוננטות. בדוגמה שלנו שימו לב לקומפוננטה counter שנשתלת בתוך התבנית אבל לא מוגדרת בקובץ הדוגמה. הקומפוננטה מוגדרת בקובץ JavaScript רגיל בשם app/javascript/controllers/counter.js ומיובאת בעזרת פקודת import. זה תוכן הקובץ:

import { ref } from 'vue';

export default {
  template: `
    <button @click="count++">{{count}}</button>
  `,
  setup() {
    const count = ref(0)
    return {
      count,
    }
  }
}

מדובר בקוד vue כמעט רגיל, רק שבמקום להשתמש בפורמט קובץ vue ותגית template אני מייצא אוביקט שיש לו מפתח בשם template. אין בעיה מתוך קומפוננטה כזו לקרוא לעוד קומפוננטות או להעביר פרמטרים לקומפוננטות בדיוק כמו ב vue רגיל. למעשה רוב הקוד של המערכת יהיה כנראה כתוב בקומפוננטות קטנות בקבצים כאלה, ובתוך סקריפט של כל דף (כל view) תהיה אפליקציית vue שתטען את הקומפוננטה או הקומפוננטות המרכזיות לאותו דף.

3. מה עוד צריך

הקובץ האחרון שמשחק תפקיד בניסוי הוא הקובץ config/importmap.rb שמגדיר את ה Import Maps, כלומר את המיפוי בין דברים שאני עושה להם import מתוך ה JavaScript לקבצי js אמיתיים על הדיסק. הוא נראה ככה:

# Pin npm packages by running ./bin/importmap

pin "application"
pin "@hotwired/turbo-rails", to: "turbo.min.js"
pin "@hotwired/stimulus", to: "stimulus.min.js"
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
pin "vue", to: "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
pin_all_from "app/javascript/controllers", under: "controllers"

וכאן אנחנו רואים את שם הספריה controllers ומבינים מאיפה זה הגיע (כן תבנית של פרויקט ריילס חדש משתמשת ב Stimulus ו controllers זה שם הספריה שבא משם).

סך הכל הקוד עובד ונראה לא רע. יכול לתת פיתרון טוב כשרוצים לשלב ספריית Vue בפרויקט ריילס או כשרוצים לגוון קצת מ Stimulus. מוזמנים למצוא את הקוד המלא של פרויקט הדוגמה בגיטהאב כאן:

https://github.com/ynonp/rails-vue-demo