Vue3、Rails7系を使って、何かアプリを作ってみたいなぁと思い、環境構築の段階で
学んだことを備忘録として残そうと思いました。
環境
ruby 3.1.0
Rails 7.0.4
vue@3.2.41
railsの初期化
railsの初期化(アプリ作成)
raiils new sample_app
vueの初期化
次にvueを導入していくが、いきなりつまりポイント
railsの標準に搭載されているwebpackerでvueを導入していくつもりが・・・
rails webpacker:install: vue
=> Don't know how to build task 'webpacker:install:vue'
コマンドが使えない・・・
曰く rails7系 では、vueのインストールコマンドがなくなっているっぽい。
というか、引退宣言がされており、そもそもRails7系では非推奨になっている...。
webpackerのコマンドを確認したところ、確かにwebpacker:install:vueは存在しない。
なんてこった・・・
rails -T | grep webpacker
Ruby on Rails 7, importmap and VueJS 3, no more webpacker を参考にさせていただいたところrails7系では、webpackerではなく、importmapという仕組みを使ってフロント側(vue、javascriptとか)の実装を行えるそう。
公式ドキュメントにも書かれている通り、インポートマップはインポートするファイルの場所をブラウザに教えることができるそう。
ただ、ブラウザのバージョン規定によるとインポートマップに対応しているブラウザも結構多い見たいです。そこで、
rails7系では、大多数のブラウザで使用されている ES Module Shims を使用することで、ある程度のブラウザには対応できるようにしているそうです。
※ IE には救いがないようだ・・・
使い方はRails 7: importmap-rails gem README(翻訳)を参考にしながら進めていきます。
Gemfileに以下を追記して、bundle:install
gem 'importmap-rails'
そうするとconfig/importmap.rbやapp/javascript/application.js.などのファイルが生成されます。
Vueのインストール方法
次にVueのインストールについてですが公式ドキュメント ES モジュール ビルドの使用を参考にしながら進めていきました。
ところで、ESモジュールってなに?
色々な記事を読むたびに出てくるESモジュールとはなんぞや。
以下の記事を参考に理解を深めていく
JavaScriptでモジュールを使う時代
ES Modulesとは
ESモジュールとは、「ES2015で策定されたJSファイルから別のJSファイルを読み込む仕組み」
ES2015とはJavaScriptの標準仕様のことで、いわゆるバージョンのこと。
ブラウザの世界では、
JSファイルを読み込むためにはscriptタグを利用するが、
ES Modulesが実装されている環境では、
・import文を利用することで、外部ファイルのJSファイルを読み込むことができる。
・外部ファイルのJSファイルではexport宣言されたものが他のJSファイルから読み込まれる。
ほぇー
何気なしに使ってたimport文について知れて感激
インストール方法
Vue.js を使う場合、CDN を利用するのが一番簡単そうです (下記)。
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
</script>
しかし、ネットに繋がっていない場合や、サーバーが落ちた時に使用できなくなるデメリットが
あるのでローカルにインストールして、そこから読み込む方法をとりました。
以下--downloadコマンドでvender/javascriptディレクトリにダウンロードします。
./bin/importmap pin "vue/dist/vue.esm-browser.js" --download
次に、先ほど生成したconfig/importmap.rbに以下を追記
ついでにpin "application", preload: trueと
pin_all_from "app/javascript/controllers", under: "controllers"も追加します。
pin "application", preload: true # application.js を読み込みたい
pin "vue", to: "vue--dist--vue.esm-browser.js.js" # @3.2.41
# app/javascript/controllers 配下を読み込みたい
pin_all_from "app/javascript/controllers", under: "controllers"
これで「venderフォルダにあるvue--dist--vue.esm-browser.js.jsファイルをvueというパッケージ名として読み込む」という意味になり、import Vue from "vue"として書けるようになります。
次にconfig/importmap.rbを読み込めるように
layoutファイルにjavascript_importmap_tagsを追記します。
<!DOCTYPE html>
<html>
<head>
<title>CodeSnippet</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<!--以下を追加-->
<%= javascript_importmap_tags %>
<!--controllers/application 配下を読み込む-->
<%= javascript_import_module_tag 'controllers/application' %>
</head>
<body id="app">
<%= yield %>
</body>
</html>
Hello Vue を表示させてみる
routes.rbに以下を追加
Rails.application.routes.draw do
root to: 'home#index'
end
app/controllers/home_controller.rb に以下を追加
class HomeController < ApplicationController
def index; end
end
view/home/index.html.erb に以下を追加
<div>
{{ text }}
</div>
app/javascript/controllers/application.js に以下を追加
import * as Vue from "vue";
const App = Vue.createApp({
data(){
return {
text: 'Hello Vue'
}
},
})
App.mount("#app");
ではrails sでサーバーを立ち上げてlocalhost:3000にアクセスすると、以下の表示が見られます。DOM上に一瞬 {{ text }} が表示された後、id="app" にアタッチし、文字列を置き換えているのがわかります。
importmapがhead内に展開され、vueがマッピングされた場所からインポートされていることが分かりました。webpackerだとアセットコンパイルによってJSファイルを一つのファイルにギュッと圧縮してからブラウザに教えているところを、importmapでは、importを使って、使用するファイルを一つずつブラウザに教えているようです。
結局 importmap で何が嬉しくなったのか
JSのビルドがなくなる
例えば、Webpackerを使用した場合、複数のJSファイルを1つの大きなJSにまとめているため、複数JSファイルの内、1つでも変更があると、出来上がる大きなJSも変わってきます。つまり、JSファイルをちょろっと変更しただけなのに、1から作り直すため時間が掛かってしまいました。
一方、importmapを使用した場合、JSファイルを個別で読み込んでいます。つまり、変更のないファイルはキャッシュを利用し、変更のあったファイルだけ読み込むので、効率的。
importmapを導入して困りそうなこと
・ブラウザのバージョンが低いと使用できない可能性がある。
・IEは100%使用できない
最後に
こうして振り返るとそんなに難しいことはやっておらず、なんなら Ruby on Rails 7, importmap and VueJS 3, no more webpacker に必要なことが全部書いてあるのも拘らず、変な回り道をして、それなりの時間がかかってしまいました。
ほんと、環境構築をサクッとこなしてしまう方々はすごいなぁと感じます。
