Menggunakan Vue di Rails
Kebetulan hari ini saya baru saja melakukan migrasi teknologi javascript pada proyek saya yang menggunakan vue.js.
Sebelumnya saya menggunakan gem vuejs-rails dan terdapat kendala pada testnya, yaitu ketika saya menggunakan fitur component pada vue.js, kode test saya tidak bisa membaca isi dalam dari component yang bersangkutan.
Maka daripada itu saya melakukan migrasi untuk menggunakan gem webpacker, webpacker adalah teknologi baru di rails untuk bekerja pada moderen javascript. Webpacker ini juga rencananya akan dimuat secara default menggantikan asset pipeline pada Rails 6 yang akan di rilis 30 April nanti.
Maka sekarang mungkin waktu yang tepat untuk menggunakan ini legacy sistem anda.
Tulisan ini akan membahas langkah-langkah bagaimana menggunakan webpacker(vue) pada legacy sistem, namun bisa juga pada sistem yang baru.
Langkah Pertama: Menghapus Turbolinks
Langkah pertama adalah menghapus penggunaan turbolinks.
Turbolink adalah sebuah paket yang dibuat oleh Basecamp yang memfasilitasi teknologi PWA pada website anda. Namun, nyatanya paket ini dapat membuat kompleks kode anda dan pengalaman saya banyak error-error yang terjadi yang mungkin sulit untuk ditangani, karena masalah low-level dari paket ini.
Bagi saya javascript ini sudah cukup kompleks, dan penggunaan turbolinks dapat membuat kodenya menjadi makin kompleks lagi, sehingga menurut saya penggunaan turbolinks ini tidak terlalu relevan.
Cara menghapus turbolink, langkah-langkahnya adalah:
-
Menghapus gem
turbolinkspadaGemfileanda:# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks gem 'turbolinks', '~> 5' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 2.5' # Use Redis adapter to run Action Cable in production # gem 'redis', '~> 4.0'Jika anda menggunakan masih menggunakan
coffee-railssebaiknya juga dihapus saja, lebih baik gunakanes6. - Jalankan perintah
$> bundle -
Lalu hapus
require turbolinkspadaapplication.jsanda.//= require rails-ujs //= require activestorage //= require turbolinks //= require_tree . -
Setelah itu pada file
application.html.erbhilangkan turbolinks padajavscript<!-- Ganti --> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload'%> <!-- Menjadi --> <%= javascript_include_tag 'application' %> - Lalu restart server anda, dan selesai.
Langkah Kedua: Install webpacker
Setelah turbolinksnya dihapus maka anda sekarang mulai menginstall gem Webpacker-nya, langkah-langkahnya:
-
Tambahkan kode ini pada file
Gemfileanda.gem 'webpacker', '~> 4.xLalu, jalankan perintah (secara berurutan):
$> bundle $> bundle exec rails webpacker:install $> yarn upgrade -
Setelah webpacker telah terinstall, langkah selanjutnya anda bisa melakukan installasi vue-nya, dengan menjalankan perintah:
$> bundle exec rails webpacker:install:vueSelesai.
Lebih lanjut mengenai installasi ini anda bisa lihat di https://github.com/rails/webpacker
Setelah instalasi anda akan dibuatkan folder yang berisi file-file di app/javascript. Dimana sekarang kode development kita sudah berada di folder ini, bukan di app/assets/javascript lagi.
Development frontend tanpa assets javascript ini sebenernya sudah memungkinkan, namun jika anda berada pada proyek legacy saya tidak menganjurkan untuk menghapusnya.
Langkah Terakhir: Setup Vue Component
Ok, sekarang kita sudah berada di tahap terakhir.
Sebelumnya mari kita melihat kode di dalam app/javascript/packs/hello_vue.js yang berisi kode untuk menampilkan component App(dari file app.vue) pada akhir element dari body tag. Sekarang kita mencoba untuk menjalankan file ini di rails kita untuk melihat apakah vue sudah berjalan seperti yang kita ekspektasikan.
Untuk menjalankannya anda hanya tinggal menambahkan kode ini di dalam <head> tag.
<head>
<title>RailsVueWebpackerExample</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload'
<!-- Tambahkan baris kode dibawah ini -->
<%= javascript_pack_tag 'hello_vue' %>
</head>
Silahkan buat satu file controller untuk melihat hasilnya:
$> rails g controller home index
Silahkan buka halaman /home/index dan anda akan melihat hasilnya disana.
Namun pada produksi kita tidak menggunakan file ini, melainkan kita akan menggunakan application.js.
Untuk mengakhiri tulisan ini kita akan membuat dua buah component di dua halaman yang berbeda, yaitu home/index dan dashboard/index.
Jika sebelumnya home/index sudah dibuat, sekarang kita membuat dashboard/index.
$> rails g controller dashboard/index
Dan pada viewsnya masing-masing kita menulis tagnya seperti ini:
<!-- app/views/dashboard/index.html.erb -->
<h1>Dashboard#index</h1>
<app-dashboard></app-dashboard>
<!-- app/views/home/index.html.erb -->
<h1>Home#index</h1>
<app-home></app-home>
Kita akan membuat dua component yaitu: app-home dan app-dashboard.
Maka buatlah file baru: app/javascript/app-home.vue dan tulis kode seperti dibawah ini:
<template>
<div id="app-home">
<p></p>
</div>
</template>
<script>
export default {
data: function() {
return {
message: "Pesan dari app-home"
};
}
};
</script>
<style>
p {
color: deeppink;
}
</style>
Lalu, buatlah file baru juga: app/javascript/app-dashboard.vue dan tulis kode sama seperti dibawah ini:
<template>
<div id="app-dashboard">
<p></p>
</div>
</template>
<script>
export default {
data: function() {
return {
message: "Pesan dari app-dashboard"
};
}
};
</script>
<style>
p {
color: darkblue;
}
</style>
Lalu terakhir, daftarkan kedua file(component) diatas pada file app/javascripts/packs/application.js, seperti kode dibawah ini:
import Vue from "vue/dist/vue.esm";
import AppHome from "../app-home.vue";
import AppDashboard from "../app-dashboard.vue";
document.addEventListener("DOMContentLoaded", () => {
const app = new Vue({
el: "#app",
data: {},
components: { AppHome, AppDashboard }
});
});
Jika kita liat kode diatas, kedua komponent itu didaftarkan ke dalam salah satu id tertentu, pada kode diatas yaitu #app. Maka pada file app/views/application.html.erb kita ubah kodenya menjadi seperti ini:
<body>
<div id="app">
<%= yield %>
</div>
</body>
Kita apit <%= yield %>-nya di dalam div#app.
Dan jangan lupa untuk memodifikasi file config/initializers/content_security_policy.rb yang sebelumnya sudah dibuat ketika kita install webpackernya menjadi:
Rails.application.config.content_security_policy do |policy|
if Rails.env.development?
policy.script_src :self, :https, :unsafe_eval, :unsafe_inline
else
policy.script_src :self, :https
end
end
Lalu restart ulang rails servernya dan tambahkan terminalnya untuk menjalankan webpack-server dengan perintah $> bin/webpack-dev-server.
Ketika bekerja dengan webpack, kita membutuhkan dua port server, jika anda ingin flexibilitas, anda bisa gunakan foreman. Penggunakan forman diluar scope tulisan ini, anda bisa baca dokumentasi pada link yang bersangkutan.
Setelah kedua port tersebut jalan, maka anda bisa melihat pesannya tampil di kedua halaman tersebut.
Begitu juga dengan test-nya. Anda bisa menggunan system-spec untuk melakukan pengujian pada kedua halaman tersebut dengan mudah:
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'Home index', type: :system, js: true do
it 'returns expected message' do
visit home_index_path
expect(page).to have_content 'Pesan dari app-home'
end
end
RSpec.describe 'Dashboard index', type: :system, js: true do
it 'returns expected message' do
visit dashboard_index_path
expect(page).to have_content 'Pesan dari app-dashboard'
end
end
Untuk setting configuration pada system-spec ini anda bisa ikuti panduan ini
Sekiranya sampai sini saja tulisan ini, untuk lebih kompleks mengenai vue.js mungkin akan saya tulis di tulisan yang lain,
Sampai bertemu lagi.