+3

SPA với Vue và Rails

Ứng dụng SPA đang ngày càng trở nên phổ biến bởi những ưu điểm mà nó mang lại. Có thể kể đến như tốc độ tải trang nhanh, trải nghiệm mượt mà, tách biệt logic frontend và backend, giúp chuyên môn hoá từng bộ phận trong dự án.

Khó khăn khi phát triển ứng dụng SPA nằm ở việc kết nối giữa và đảm bảo tính đồng bộ giữa hai server frontend và backend. Đây là những vấn đề mà bạn không bao giờ gặp ở một ứng dụng SSR. Chưa kể việc tạo ra nhiều server có thể gây lãng phí vì thực tế chỉ có server backend chịu tải chính, server frontend sẽ chỉ lưu các tài nguyên như html, css, js…

Có một hướng tiếp cận đơn giản hơn giúp bạn sử dụng SPA cho dự án của mình mà không phải lo lắng đến các vấn đề trên. Bài viết này sẽ giúp bạn thực hiện điều đó với Vue và Rails.

Setup Rails

Ý tưởng của việc kết hợp Vue và Rails trong bài viết này là sử dụng Vue thay thế cho phần frontend mặc định của Rails. Nghĩa là Rails sẽ chỉ cung cấp các APIs để phía frontend là Vue sẽ gọi và hiển thị kết quả lên màn hình.

Đầu tiên, bạn cần khởi tạo dự án Rails:

rails new rails-vue

Sau khi cài đặt hoàn tất, chạy Rails server bằng lệnh:

cd rails-vue

rails s

Kiểm tra đường dẫn localhost:3000:

alt text

Như đã nói ở trên, Rails sẽ không quản lý và render view. Ứng dụng chỉ cần một trang home duy nhất để nhúng toàn bộ code frontend vào. Bạn tạo HomeController như sau:

# app/controllers/home_controller.rb

class HomeController < ApplicationController
  def index
  end
end

Tạo file home index, đây sẽ là file chứa toàn bộ code của frontend:

# app/views/home/index.html.erb

<h1>Home page</h1>

Sửa lại layout mặc định:

# app/views/layouts/application.html.erb

<%= yield %>

Khi người dùng nhập một đường dẫn, Rails sẽ redirect request đó về home. Tại đây, Vue xác định page nào sẽ được hiển thị để gọi các APIs tương ứng. Bạn cần config route luôn redirect về home:

# config/routes.rb

Rails.application.routes.draw do
  root to: "home#index"

  get "*path", to: "home#index"
end

Bây giờ khi nhập bất kỳ đường dẫn nào:

alt text

Bạn sẽ luôn thấy màn hình trên hiển thị.

Setup Vue

Chúng ta sẽ sử dụng vue-cli để tạo một dự án Vue. Bạn có thể chạy lệnh sau để cài đặt:

yarn global add @vue/cli@next

Tại thư mục dự án, chạy lệnh dưới đây để tạo một dự án Vue:

vue create frontend

Thư mục frontend sẽ xuất hiện và bạn cần thêm config sau:

// frontend/vue.config.js

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  indexPath: '../../app/views/home/index.html.erb',
  outputDir: '../public/frontend',
  publicPath: '/frontend',
})

Chúng ta đã trỏ indexPath đến trang home. Mỗi lần build, Vue sẽ update nội dung vào file này. Bây giờ hãy thử build bằng lệnh:

cd frontend

yarn && yarn build --watch

Refresh lại page, nếu màn hình dưới đây hiển thị thì mọi thứ đã thành công:

alt text

Thử thay đổi nội dung template thành:

# frontend/src/App.vue

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Rails Vue - Everything work well!"/>
</template>

Bạn sẽ thấy màn hình đã được update:

alt text

Deploy

Do không sử dụng server riêng cho frontend nên việc deploy ứng dụng sẽ đơn giản hơn. Dưới đây sẽ là một số điều bạn cần lưu ý.

Đảm bảo vue-cli nằm trong phần dependencies:

// frontend/package.json

{
  // ...
  "dependencies": {
    // ...
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-service": "^5.0.8"
  },
}

Không tạo source map trên production với config:

// frontend/vue.config.js

module.exports = defineConfig({
  productionSourceMap: false,
  // ...
});

Nếu bạn sử dụng capistrano để deploy hãy thêm setting và rake task sau.

  • Setting role cho frontend:
# config/deploy.rb

set :yarn_role, :frontend
set :frontend_path, ->{release_path.join("frontend")}
  • Rake task build frontend:
# lib/capistrano/tasks/yarn.rake

namespace :yarn do
  desc "Build the frontend via yarn"
  task :build do
    on fetch(:yarn_role) do
      within fetch(:frontend_path) do
        execute :yarn, "install"
        execute :yarn, "build"
      end
    end
  end
end

before "deploy:updated", "yarn:build"

Conclusion

Như vậy chúng ta đã tích hợp thành công Vue vào trong Rails. Với cách tiếp cận như trên, việc phát triển một ứng dụng SPA trở nên dễ dàng hơn. Hi vọng bài viết hữu ích với bạn.

Blog: https://dongoclam.github.io/spa-with-vue-and-rails.html


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí