みなさん、こんにちは。まどぎわです(・∀・)
今日は、RailsアプリにWebpackerを使って、フロントエンド環境を整えて少し開発してみたので、そのあたりをブログに整理しておこうと思います🙌
WebPackerとは?
WebPackerとは、RailsでWebpackをいい感じに扱うことができる機能です。
私もまだ全然理解が足りてない部分がありますが、公式ドキュメントや下記にまとまってますので、興味がある方は読んでみてくださいm( )m
今回やったこと
今回は私の開発している「Quizアプリ Quiq」に評価機能を作ってみました。
こんな感じ
下記から実際に触ることができます🙌
Webpackerの導入手順
Gemfileに書きを追記してbundle install
を実施
gem 'webpacker', github: 'rails/webpacker'
その後、webpacker
とvue
をinstallします。
bundle exec rails webpacker:install # 下記は導入したいフレームワークに合わせて修正してください。 bundle exec rails webpacker:install:vue
これで、bin/webpack
でwebpackのビルドが走るようになり、railsでvueを扱えるようになります(・∀・)
フロントエンドの実装
今回は下記のような機能をRails上にVue.jsを使って実装しました。
デフォルトのルールでは、下記のようなディレクトリ構成で実装していきます。
(vue.jsの実装の仕方等は、tutorial等が充実してますので、そちらをご確認ください。)
# viewから読み込むEndpoint app/javascript/packs # その他 app/javascript
実際に私が書いたコードが下記です(お見苦しいかもしれません。。。)
QuizLike.vue
ここでは、実際のVueコンポーネントを実装してます。rails側へのpost処理等を実装してます。
<template> <div style="text-align: right"> <button class="btn btn-success btn-sm" @click="create(1)"><i class="fas fa-thumbs-up"></i></button> <button class="btn btn-danger btn-sm" @click="create(-1)"><i class="fas fa-thumbs-down"></i></button> <span class="text-secondary">評価 : {{ like_count }} pt</span> </div> </template> <script> import axios from 'axios'; import { csrfToken } from 'rails-ujs' axios.defaults.headers.common['X-CSRF-Token'] = csrfToken() export default { data: function () { return { like_count: this.init_like_count } }, props: { init_like_count: { type: Number, required: true }, quiz_id: { type: Number, required: true } }, methods: { create: function (value) { this.like_count += value axios.post(`/quizzes/${this.quiz_id}/like`, { like: { value: this.like_count } }); } } } </script>
packs/quizzes.js
ここでは、作成したコンポーネントの読み込み、Vueインスタンスの作成を行うEndpointを定義してます。
import Vue from 'vue/dist/vue.esm' import QuizLike from '../QuizLike.vue'; new Vue({ el: '#like_area', components: { QuizLike }, })
result.html.haml
ここでは、javascript_pack_tag
を使って、Endpointの読み込みをおこなっています。
= javascript_pack_tag 'quizzes'
point
railsにpostする
railsにpostを送るときには、axios
を使用するの結構メジャーみたいです。
初めて使ってみましたが、下記のようにjsonでパラメーターを作成して簡単にpostがおくれました🙌
axios.post(`/quizzes/${this.quiz_id}/like`, { like: { value: this.like_count } });
postする際の注意点
特に何も考えずにpostメソッドを送ろうとすると、RailsのCSRF
対策に引っかかり、InvalidAuthenticityToken
が発生してしまいます。Vueコンポーネントからrailsにpostする場合は、下記のように明示的にTokenを作成し、headerに付与してあげる必要があります👀
import axios from 'axios'; import { csrfToken } from 'rails-ujs' axios.defaults.headers.common['X-CSRF-Token'] = csrfToken()
Tips
上でも少し触れましたが、いろいろハマったところをtipsとして、対応方法を軽くですがメモしておきますφ(・・
Uglifier::Error: Unexpected token
下記Issueを参考にproduction.rb
を修正して対応しました。
config.assets.js_compressor = Uglifier.new(harmony: true)
Module build failed: ReferenceError: Unknown plugin "@babel/plugin-transform-destructuring"
下記Issueを参考にyarn add https://github.com/rails/webpacker.git
を実行して対応しました。
herokuデプロイ時にnode系のmodule fetchで500Errorで落ちる
何回かリトライしたら正常終了しました。
おわりに
今回はWebpacker
使って、フロントエンド開発環境を作ってみました。
良いんだか悪いんだかわからないですが、webpack等フロントエンド関連技術をしらない自分でも結構簡単にフロントエンド環境を作ることができました🙌
これからはフロントエンド技術も学んで、よりユーザーに優しいサービスを作っていきたいです👀