LoginSignup
31
31

More than 5 years have passed since last update.

Rails+Vue.js+TypeScriptな環境を構築する

Last updated at Posted at 2018-01-30

はじめに

Rails + Vue.js + TypeScriptで趣味プログラミングしてみようと思って開発環境を構築していたら思いの外ハマったので備忘録として残しておきます。

RailsやWebpackerのバージョンが変わったら設定もまた変わりそうなので(Webpacker3.0系と3.2系でもconfigファイルの書き方が微妙に違うようでした)、以下のバージョンにおいて動作確認しているということをお見知りおきください。

環境

  • Ruby 2.5.0
  • Rails 5.1.4
  • Webpacker 3.2.1

プロジェクトを作成してVue.jsが動くようにする

まずはrailsプロジェクトを作ります。今回はオプション無しでやります。

$ rails new sample

エディタでGemfileを開きwebpacker gemを追記した上で bundle install します。成功したら webpacker:install しましょう。

$ emacs Gemfile

# webpackerを追記
gem 'webpacker', '~> 3.0'

$ bundle

# bundle installできたらwebpackerをインストール
$ bundle exec rails webpacker:install

問題なければそのままwebpackerでVue.jsをインストールします。

$ bundle exec rails webpacker:install:vue

インストールがうまくいったら、Vue.jsの動作確認のためcontroller、view、routesに以下のように追記(もしくは新規追加)します。

app/controllers/home_controller.rb
class HomeController < ApplicationController
  def index
  end
end
app/views/home/index.html.erb
<%= stylesheet_pack_tag 'hello_vue' %>
<%= javascript_pack_tag 'hello_vue' %>
config/routes.rb
Rails.application.routes.draw do
  root to: 'home#index'
end

サーバを立ち上げて確認してみます。

$ bundle exec rails s

image.png

ここで bin/webpack-dev-server も立ち上げてみようとするとエラーになるので、エラー文に書いてあるとおり実行します。

# エラーになる
$ bin/webpack-dev-server
Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.

# エラーに書いてあるとおり実行
$ bundle binstubs bundler --force

# 今度はOK
$ bin/webpack-dev-server
 10% building modules 2/2 modules 0 active
Project is running at http://localhost:3035/
webpack output is served from /packs/
(中略)
webpack: Compiled successfully.

TypeScriptのインストールと設定

Vue.jsは動くようになったので今度はwebpackerでTypeScriptをインストールします。

$ bundle exec rails webpacker:install:typescript

TypeScriptが使えるようになったはずなので以下の二箇所に変更を加えてみましょう。

  1. Rename: app/javascript/packs/hello_vue.js -> app/javascript/packs/hello_vue.ts
  2. app/javascript/app.vue のscript部分にTypeScriptを指定
app/javascript/app.vue
   </div>
 </template>

-<script>
+<script lang="ts">
 export default {
   data: function () {
     return {

これで bin/webpack-dev-server を動かしてみますが、次のようなエラーが出ると思います。

$ bin/webpack-dev-server
(中略)
Failed to compile.

./app/javascript/packs/hello_vue.ts
[tsl] ERROR in /path/to/project/app/javascript/packs/hello_vue.ts(9,17)
      TS2307: Cannot find module '../app.vue'.

これはTypeScriptから .vue ファイルが読めていないということなので ./config/webpack/loaders/typescript.js を以下のように編集します。

config/webpack/loaders/typescript.js
 module.exports = {
   test: /\.(ts|tsx)?(\.erb)?$/,
   use: [{
-    loader: 'ts-loader'
+    loader: 'ts-loader',
+    options: {
+      appendTsSuffixTo: [/\.vue$/]
+    }
   }]
 }

bin/webpack-dev-server を動かしてCompiled successfullyすればOKです。

$ bin/webpack-dev-server
(中略)
webpack: Compiled successfully.

Vue.jsの型定義ファイルの追加

今までの流れでRails + Vue.js + TypeScriptの設定はOKだと思ったのですが、適当にコンポーネントファイルでも追加するかと app/javascript/packs/components/header.vue のようなファイルを作成して hello_vue.ts でインポートしてみたところ

app/javascript/packs/components/header.vue
<template>
  <p>custom header</p>
</template>
app/javascript/packs/hello_vue.ts
 import Vue from 'vue'
 import App from '../app.vue'
+import Header from './components/header.vue'

 document.addEventListener('DOMContentLoaded', () => {
   const el = document.body.appendChild(document.createElement('hello'))

また Cannot find module のエラーが出ました。

$ bin/webpack-dev-server
(中略)
ERROR in ./app/javascript/packs/hello_vue.ts
[tsl] ERROR in /path/to/project/app/javascript/packs/hello_vue.ts(10,20)
      TS2307: Cannot find module './components/header.vue'.

この問題を解決するにはどうもVue.jsの型定義ファイルが必要とのことだったので app/javascript/types/vue.d.ts あたりに以下のような内容のファイルを追加します。

app/javascript/types/vue.d.ts
declare module "*.vue" {
    import Vue from 'vue'
    export default Vue
}

これで動くようになったはずです。

$ bin/webpack-dev-server
(中略)
webpack: Compiled successfully.

おわりに

というわけでRails + Vue.js + TypeScriptで開発できるようになりました、多分。

ただ、何故App.vueは型定義ファイルがなくてもhello_vue.tsから読み込めるのか…これが分からない :thinking:

誰かご教授いただけると幸いです :bow:

Reference

31
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
31