rails5.1がリリースされ、フロントエンド周りがかなり変わったということなので試してみました。
変更点の詳細は以下の記事が詳しいです
実行環境
- ruby v2.4.1
- node v7.8.0
- yarn v0.24.4
- rails v5.1.1
Railsアプリケーションの作成
webpack
オプションを指定してアプリケーションを作成します。
$ rails new rails-vue-ts-sample --webpack
完了すると、以下のようなwebpack関連のファイルが出力されています。
app/javascript
├── packs
│ └── application.js
bin
├── webpack
├── webpack-dev-server
config/webpack
├── configuration.js
├── development.js
├── loaders
│ ├── assets.js
│ ├── babel.js
│ ├── coffee.js
│ ├── erb.js
│ └── sass.js
├── production.js
├── shared.js
└── test.js
参考
Vueのインストール
以下のコマンドを実行してVueをインストールします。
$ bin/rails webpacker:install:vue
実行するとpackage.jsonが更新され、以下のファイルが追加されます。
- app/javascript/packs/app.vue
- app/javascript/packs/hello_vue.js
- config/webpack/loaders/vue.js
package.json差分
+ "vue": "^2.3.3",
+ "vue-loader": "^12.2.1",
+ "vue-template-compiler": "^2.3.3",
参考
コントローラの追加
確認のため、適当なコントローラを作成します。
$ rails g controller Home index
erbファイルを以下のように編集
- <h1>Home#index</h1>
- <p>Find me in app/views/home/index.html.erb</p>
+ <%= javascript_pack_tag 'hello_vue' %>
ビルド
以下のコマンドでビルドを実行します。
ビルドを忘れるとWebpacker::FileLoader::NotFoundError
が発生します。
$ bin/webpack
ビルドが完了したら、サーバを起動し動作を確認してみます。
$ bin/rails s
TypeScript+Pugを導入してみる
続いて、TypeScriptとPug(テンプレートエンジン)を追加してみます。
$ yarn add typescript ts-loader pug pug-loader
tsconfig.jsonを追加します。
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"es6",
"dom"
],
"module": "es6",
"moduleResolution": "node",
"sourceMap": true,
"target": "es5"
},
"exclude": [
"**/*.spec.ts",
"node_modules",
"vendor",
"public"
],
"compileOnSave": false
}
app/javascript/packs/app.vueを以下のように修正
-<template>
- <div id="app">
- <p>{{ message }}</p>
- </div>
+<template lang="pug">
+ #app
+ p {{ message }}
</template>
-<script>
+<script lang="ts">
export default {
data: function () {
return {
message: "Hello Vue!"
}
}
}
</script>
<style scoped>
p {
font-size: 2em;
text-align: center;
}
</style>
続いて、app/javascript/packs/hello_vue.js
をhello_vue.ts
にリネーム
$ mv app/javascript/packs/hello_vue.js app/javascript/packs/hello_vue.ts
ここで、ビルドを実行するとエラーが発生。
hello_vue.tsファイルからapp.vueファイルが読めないようです。
ERROR in ./app/javascript/packs/hello_vue.ts
(8,17): error TS2307: Cannot find module './app.vue'.
以下のファイルを追加して、ts-loaderの設定を追加します。
module.exports = {
test: /\.ts$/,
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/]
}
}
これでビルドが通るようになりました。
参考
eslintを導入する
せっかくなので、eslintも導入してみます。
$ yarn add babel-eslint eslint eslint-config-standard eslint-friendly-formatter eslint-loader eslint-plugin-html eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard --dev
.eslintrc.jsを追加します
module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
sourceType: 'module'
},
env: {
browser: true
},
extends: 'standard',
plugins: [
'html'
],
'rules': {
// allow paren-less arrow functions
'arrow-parens': 0,
// allow async-await
'generator-star-spacing': 0,
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
}
}
以下のファイルを追加して、eslint-loaderの設定を追加します。
module.exports = {
test: /\.(js|ts|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
options: {
formatter: require('eslint-friendly-formatter')
}
}
これでeslintの設定は完了です。
動作を確認してみます。
app.vueファイルを以下のように編集
<script lang="ts">
export default {
data: function () {
+ // 未使用の変数を追加
+ const foo:string = 'bar'
return {
message: 'Hello Vue!'
}
}
}
</script>
ビルドするとエラーが発生します。
ちゃんと動いているようです。
ERROR in ./app/javascript/packs/app.vue
✘ http://eslint.org/docs/rules/no-unused-vars 'foo' is assigned a value but never used
app/javascript/packs/app.vue:10:11
const foo :string = 'bar'
^
✘ 1 problem (1 error, 0 warnings)
vueファイルのstyleが適用されていない?
これで終わりと思いきや、vueファイルのstyleが適用されていないことに気づきました。
<template lang="pug">
#app
p {{ message }}
</template>
〜〜〜
<style scoped>
p {
font-size: 5em;
text-align: center;
}
</style>
vue-loaderのextractCSS
の設定によるものでした。
config/webpack/loaders/vue.js
を編集して、extractCSSをfalseとしても良いですが、以下のようにstylesheet_pack_tag
を追加することで
スタイルが適用されるようになりました。
+ <%= stylesheet_pack_tag 'hello_vue' %>
<%= javascript_pack_tag 'hello_vue' %>
参考
- https://github.com/rails/webpacker#inside-views
- https://github.com/vuejs/vue-loader/blob/master/docs/en/configurations/extract-css.md
終わりに
とりあえずですが、Vuejs+TypeScript+eslintな環境を作ることができました。
上記では都度bin/webpack
を実行していましたが、webpack-dev-serverを設定してあげれば変更時に自動でビルドが実行されるようになります。