せらぴんブログ

サークル「せらぴん」のうのはな透です。やっぱり眼鏡っ娘が好き!!

素人が3日でMMDモデル改造してみた

unohanat.hatenablog.com

さて、マイMMDモデルを作成することに成功したうのはな。
次にやるのは――


そう!
衣装の挿げ替えだ!!

というわけでブルナポ春菜モデルを作っていきます。

続きを読む

素人が一週間でMMDモデル作ってみた③

unohanat.hatenablog.com

前回は、血の滲むような思いをしながらモーフをつけたv.0.2.0モデルを作成しました。
v.0.2.0の段階でMMDモデルとして最低限の体裁は整ったので、
いよいよ公開用のv.1.0.0モデルの作成に着手していきます。

続きを読む

素人が一週間でMMDモデル作ってみた①

Blender楽しいですね(挨拶)

www.nicovideo.jp

というわけで、こちらのMMDモデルを制作した際の話をします。
今回はモデルv.0.1.0(非公開)作成完了まで。

続きを読む

Sinatraで肥大化したファイルを分割する

Sinatraを使ったPJ*1で、あまりにも一つのファイルに色々突っ込みすぎていたので、ファイル分割をメインとしたリファクタリングを実施した。
その際の備忘録。

ディレクトリ構成は長くなるので割愛。

やったこと

バッチファイル

  • cronで実行するバッチファイルがappディレクトリ直下に置かれまくっていたので、app/batchディレクトリを作ってそこに全部つっこむ
  • バッチファイル用の独立したライブラリファイルがあったので、新設するapp/src/modelsディレクトリに統合
  • バッチファイル内に独立したクラスが書かれていた💢ので、それもapp/src/modelsディレクトリに移行(バッチファイルは処理のみを書く)

モデルファイル

  • appディレクトリ内に2~3のモデルファイルが散逸していたため、app/src/modelsディレクトリを作ってそこに全部つっこむ
  • モデルファイルが肥大化(一番ひどいもので80KB!)していたため、1ファイル1クラス形式になるようファイル分割
  • 複数のサブクラスを抱えている肥大クラスがあったので、サブクラスをすべてファイル分割
  • それでも肥大だったため、さらに一部機能をモジュール化して別ファイルに退避

ヘルパー

  • app/src/helperディレクトリに移動
  • helper do~endを用いていたので、ヘルパークラス化

コントローラ

  • コントローラファイルが肥大化(合わせて45KB!)していたため、サブコントローラとしてファイル分割し、app/src/controllerディレクトリに移動

*1:まぁ要するに同人秘書なんだけど

続きを読む

SinatraとVueの黒魔術化

お前が○○んだよ?ジェネレータ

次なる実験場はこのジェネレータ。
ベースにSinatraを使っているので、そこに乗っける形でVueによるSPA化を施していく。

ぶっちゃけ、下記ページに必要なことは8割方書いてある。

qiita.com
qiita.com

以下、備忘録

index.htmlの返し方

上記ページでは「フロントエンドサーバがnpm、バックエンドサーバがsinatra」となっていたりして
そいつらの橋渡しをするようにしているようだが、
「別にSinatraあるんだから、そこで全部やっちゃえばよくね?」ということで今回はSinatraのみで対処した。
要するに、"/"にアクセスされたらSinatraで拾って"/index.html"を内部的に返せばよいわけである。
これは、Sinatraのreadmeにある「別ルーティングの誘発」を利用することで実現できる。

Sinatra: README (Japanese)

Ajaxどうするの?

axiosでやる。

qiita.com

axiosを使ってPOSTするとデータが渡ってないようだったので、下記ページを参照しながら直した。

qiita.com

プログラム内でページ遷移

this.$router.pushを使う。
ちなみに、動的ルーティングのパラメータはthis.$route.params、こいつはthis.$router
めちゃめちゃ紛らわしい💢

yarn

最近ではnpmの代わりにyarnを使うのが流儀らしい。

www.webprofessional.jp

早いらしいが体感的にそこまで違いを感じなかった。
実際に数値で比べてみないとわかんないものだししょうがないね。

感想

  • SinatraAPI(&index.htmlレスポンス)に徹し、フロントエンドはVueに集約することができた
  • npm(yarn)周りはデプロイした時点で役目を終え、herokuのwebプロセスではSinatraのみが走っている。美しい
  • nodeのモジュールとrubyのgemが両方Slugとして固められるため、容量としては若干不安要素がある(このアプリも大したことはしてないけどSlugが71MBになってる)

以上。

Vueいじってみた

せらぴん

jp.vuejs.org

今更ながら「Vue.jsを使いたい」という欲求を満たすため、自分のサイトをゴリゴリ改造しました。
従来mithril.js(in livescript)だったものを、Vue.js+Vue-router(in javascript)に変更してます。
以下、備忘録。

開発の流れ/詰まった点

Vue-router

最初はメインのページをindex.htmlにゴリゴリ書いていったんだが、
うちのサイトはメインページの他に本用のページがある。
この2種類のページを使い分けるために、メインページが一段落ついてからVue-routerを用いてSPA化に着手した。

Introduction · vue-router

Vue-routerはrouter-viewタグ以下にページ個別の内容を記述する。
その”ページ個別の内容”は、通常コンポーネントとして提供する。
つまり、現状からSPA化するためには、下記のようなフローを辿ることになる。

  • index.htmlは、router-viewを書くだけの質素なページにする
  • (今までindex.htmlに書いていた)メインページの部分をコンポーネント化する
  • 本用のページを新たにコンポーネントとして作成する

単一ファイルコンポーネント

コンポーネント — Vue.js
Vueのコンポーネントは気の遠くなるくらい多機能だけど、ここではごく基本的な機能のみを利用する。
問題は、コンポーネント化するためにはtemplateにJSの文字列リテラルとして持たせないといけない点。
できれば、リテラルでなく純粋なhtmlとして記述したい。
その欲求を解決してくれるのが単一ファイルコンポーネントである。
これは、例えばhome.vueというファイルを作って、そこのtemplateタグ内にコンポーネント化したいhtmlを記述するというものである。
単一ファイルコンポーネントであれば、ほぼ純粋なhtmlとしてページを記述できる。

単一ファイルコンポーネント — Vue.js
vue.jsのcomponentをwebpackで.vueにして単一ファイルコンポーネントにする - Qiita

ここでの注意点は2つ。
templateタグ直下の要素は必ず1個のみにするという点*1と、
単一ファイルコンポーネントを使うためには、.vueファイルのコンパイルが必要であるという点だ。

Webpack

vueファイルはそのままでは使えない。コンパイルしてJS(VDOM)化しないといけない。
モジュールバンドラが必要になる。
私はモジュールバンドラといえばbrowserifyしか知らなかったのだが、
Webで調べたところ、WebpackというものがVueとよく併用されているようなので、そちらを利用してみることにした。

webpack
webpack 入門 (v3系 対応) - Qiita

vueファイルのコンパイルには、通常の設定に加えて、vue-loaderを使うよう設定する必要がある。
vue-loaderはnpmでインストールする。

Vue.jsを使った大規模開発に必要なもの - Qiita
Introduction · vue-loader

また、vue-template-complierもあわせてインストールする必要がある。

vue-template-compiler

このあたりは、vue-cliをインストールしている場合は一緒にインストールされている……と思う*2

ページが切り替わらない(1)

本用のページは一つ前のページと一つ後ろのページにそれぞれ遷移できる。
最初、ページを切り替えようとすると白いページに遷移してしまうことがあった。

理由は単純で、aタグを使っていたから。
Vue-routerでの遷移はrouter-linkタグを使う必要がある。
遷移先もhrefでなくtoで指定する必要があるため注意。

以下蛇足

ちなみにaタグで単純に遷移できない理由は、SPAではルートが"/"でなく"/#/"や"/?/"などになり、ルートの変換が必要になるためである。
aタグで"/"を直接変更してしまったら、シングルページでなくなってしまうのでSPAでなくなってしまう。よくよく考えてみると自明の理であった。

ページが切り替わらない(2)

上記問題が解決したあとも、ページを切り替えようとするとURLは変更されるのにページの内容は変更されないことがあった。
これについては、下記ページが詳しい。

[vue-router] パラメーター違いのページリンクをクリックしても更新されない時は ? - atuweb : つながりを作るWebプログラマ

以下蛇足

公式のページにも「$routeをwatchしろ」と書いてはいるのだが、
watchで何をすればいいかはいまいちピンときてなかった。
上記ページのようにwatchメソッド内でto.params.idを引数としてdataの各変数を更新してしまうのが直感的でわかりやすい。
その場合、更新用メソッドが必要になる。初期読み込み時に更新用メソッドを読み込むためには、createdプロパティを利用する。

gulpとwebpack

今までgulpを使っていたので、引き続きメインのタスクランナーにはgulpを利用しwebpackはモジュールバンドラに徹してもらうことにする。
gulpとwebpackの連携については、下記ページが詳しい。

Gulpで始めるwebpack 3入門 - Qiita

以下蛇足

webpackを導入した際、webpackの実行でエラーが発生していた。
"=>"*3を認識していなかったようなので、決断的npmバージョンアップを実行。
(io.js 2.0.2→v8.9.4にバージョンアップ。かなり浦島太郎状態である……)
ところがバージョンアップ後、gulpの途中でよく止まるようになってしまった。

Installing node.js get error - after npm install - cannot find module internal/util/types (Windows 10 64bit) · Issue #19032 · npm/npm · GitHub

issueのページを見てもピンとこなかったので、古いnodeモジュールをすべて削除。
gulpfileを頼りに、必要最低限のモジュールを入れ直す羽目になった……。

デプロイ

とりあえず諸々整理して、npm startを実行すれば静的サーバが立ち上がるように設定し終わったので、ここでherokuにデプロイ。
しかしデプロイ後、アプリケーションエラーが発生するようになってしまった。

原因は、npm startで利用している一部のモジュールをdevDependenciesとしてインストールしていたため。
静的ファイルはすべてnpm startで生成していたため、heroku上でも同じモジュールが使えないといけないのだが、どうやらherokuではdepencenciesはインストールしてもdevDependenciesはインストールしてくれないようだ。
お行儀がいいとはいえないが、すべてdepencenciesに突っ込むことで解決した。

Vueの感想

  • VDOMをhtmlとして書けるのが嬉しい。それでいてコンパイルするから最終的にはVDOMとして動作しているのが面白い
  • 最初の動機は「vue.js+vue-loader.jsだけ使えばnpm非依存で作れるのでは……?」だったが、終わってみればnpmからは逃れられそうになかった
  • vueファイル内ではpugやstylusも使えるようなので、そっちも使ってみたい
  • 「『htmlとして書けるのが嬉しい』のにpug使うの?」って言われるかもしれないけど、JSのリテラルでない点が重要なのでhtml or pugはそこまで重要ではない。むしろvueファイルごとに使い分けられるので、そういう楽しみもある(と思う)
  • テンプレートは奥が深そう(親子関係とか)なので、もう少し勉強が必要そう
  • アニメーションさせたい
  • 既存のruby製サイト(Sinatraなど)に組み込めれば強そうなので、研究したい

以上。

*1:ただしv-if/v-elseを用いて”結果的に要素1個のみになる状況”にしても、許容される

*2:私はvue.jsをダウンロードして利用していたので、vue-cliはインストールしていない

*3:アロー関数( https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/arrow_functions