Merhaba, kendi blogumda bir kaç ay önce rails/webpacker desteğine kavuştuğu zaman yazdığım yazıyı paylaşmak istiyorum. Orijinali şurada.
Öncelikle - Rails 5.1 Loving JavaScript
Merhaba yukarıda linkini verdiğim yazıda da görebileceğiniz gibi Rails 5.1 versiyonundan itibaren rails/webpacker aracılığıyla projelerimizi React, Angular, Elm ve ya Vuejs yazabileceğimiz şekilde oluşturma imkanına sahibiz. Bu yazımda vuejs ile basit bir proje oluşturarak öğrendiklerimi anlatacağım. Aklımda örnek proje olarak github api v3 kullanarak repo arayan basit bir uygulama yapmak var.
Projeyi oluşturalım...
$ rails new webpacker-vue-example --webpack=vue -B
$ cd webpacker-vue-example
Kısa şekilde anlatmak gerekirse —webpack=vue ile projemizde vuejs kullanacağımızı söyledik ve webpacker bizim için gerekli tüm konfigurasyonları yaptı. Proje dizininde npm install
ve ya yarn install
diyerek webpacker'ın oluşturduğu package.json
dosyasındaki bağımlılıkları kurduk.
$ bundle install
$ rails g controller root home --skip-helper --skip-assets
Örnek uygulamamızın giriş sayfası için root adında bir controller oluşturduk. Bu giriş sayfasında repo aramamızı sağlayan bir autocomplete componenti olacak. config/routes.rb
dosyamıza uygulamamızın evini söyleyelim.
Rails.application.routes.draw do
root 'root#home'
end
Packimizi hazırlayalım...
Rails uygulamamızın app dizininde javascript/packs
diye bir dizin var. Packlerimiz burada duracak. Örnek olarak hello_world packini inceleyebilirsiniz. Ben pack dizinimi aşağıdaki şekile getiriyorum.
$ tree app/javascript
app/javascript
├── app.sass
└── packs
├── App.vue
├── Card.vue
└── app.js
packs/app.js
dosyamızda aşağıdaki gibi vue instance oluşturuyoruz.
import Vue from 'vue/dist/vue.esm'
import App from './App.vue'
import '../app' // sass dosyamız
Vue.config.productionTip = false;
document.addEventListener('DOMContentLoaded', () => {
/* eslint-disable no-new */
new Vue({
el: '#app',
template: '<App/>',
components: { App }
})
})
Vue #app elementine mount edilecek ve App.vue dosyasındaki template'i render edecek. App componentimiz bir autocomplete ve bir de card componenti render edecek. Autocomplete remote search ile github v3 api den repositories endpointine request atıp repository listesini çekecek ve seçtiğimiz repository card componenti ile render edilecek.
Autocomplete için element ui kullanacağım...
$ yarn add element-ui
$ yarn add babel-plugin-component -D
Element UI içinde tonla component barındıran bir UI paketi. Ama biz sadece autocomplete componentini kullanacağımız için .babelrc dosyamızda plugins e aşağıdaki eklemeyi yapıyoruz.
{
...
"plugins": [
...
["component", [
{
"libraryName": "element-ui",
"styleLibraryName": "theme-default"
}
]]
...
]
...
}
packs/app.js
dosyamıza da aşağıdakileri ekleyerek element ui den istediğimiz componentleri import ediyoruz.
...
import { Autocomplete } from 'element-ui'
...
Vue.component(Autocomplete.name, Autocomplete)
...
Request göndermek için axios kullanacağım..
$ yarn add axios
packs/App.vue
dosyama aşağıdaki gibi bir template yazıyorum.
<template>
<div id="app">
<el-autocomplete v-model="value"
@select="select"
:fetch-suggestions="querySearch"
placeholder="Please enter a keyword">
</el-autocomplete>
<card v-if="selected" :repo="selected"></card>
</div>
</template>
<script>
import axios from 'axios'
import Card from './card'
export default {
name: 'App',
components: { Card },
data() {
return {
value: '',
repositories: [],
selected: null
}
},
methods: {
querySearch(queryString, cb) {
const that = this
this.repositories = []
if (queryString) {
axios.get(`https://api.github.com/search/repositories?sort=name&order=asc&q=${queryString}`)
.then((response) => {
response.data.items.map((v) => {
return Object.assign(v, {
value: v.name,
label: v.id,
})
}).forEach((v) => {
that.repositories.push(v)
cb(that.repositories)
})
})
}
},
select(item) {
this.selected = this.repositories.filter(v => v.id === item.label)
}
}
}
</script>
Ve card template'imizi yazalım.
<template>
<div class="card">
<div class="item" v-for="item in repo">
<h3><a :href="item.owner.html_url" target="_blank">{{item.owner.login}}</a> / <a :href="item.html_url" target="_blank">{{item.name}}</a></h3>
<p>{{item.description}}</p>
<span class="meta" v-if="item.language">
<span class="language-icon" style="color: #4C5E99;">●</span> {{item.language}}
</span>
<span class="meta">
<icon name="star"></icon>
<span>
{{item.stargazers_count}}
</span>
</span>
<span class="meta">
<icon name="code-fork"></icon>
<span>
{{item.forks_count}}
</span>
</span>
</div>
</div>
</template>
<script>
export default {
name: 'Card',
props: ['repo']
}
</script>
Ve artık çalıştırabiliriz...
Fakat packlerin ve rails server ın aynı anda çalışıyor olması gerek o yüzden bir sekmede rails s
bir sekmede ./bin/webpack-dev-server
çalışmalı. Bu işi foreman ile kolaylıştırabiliriz. Bu yüzden foreman kurduktan sonra( gem install foreman
) proje dizininde bir Procfile
oluşturup içine aşağıdakileri yazıyoruz.
web: bundle exec rails s
webpacker: ./bin/webpack-dev-server
Şimdi proje dizininde;
$ foreman start
Ve http://localhost:5000 üzerinden projenin durumunu görebilirsiniz.
Dipnot:
Sorusu olan fm yoruma ve ya kendi sitemdeki disqus'a, projeyi klonlayıp incelemek isteyen github reposuna buyursun. Kalın sağlıcakla ✋