サイト立ち上げをいかに効率化しつつ、品質も確保していくか

SKIYAKIクリエイティブチームのヒトミと申します。 私は主に新規サイト立ち上げ、特にフロントコーディング部分を担当しております。

クリエイティブチームは現在7名で、サイトのデザイン・コーディング・運用業務をメインで担当しており、日々の運営業務と平行しつつ、

前期には100を越えるアーティスト、タレント、事務所様のファンクラブ、オフィシャルサイト、ECサイトなどを立ち上げさせて頂きました。

これを、祝日+土日+年末年始/夏期休暇/GW休暇などを加味して、年間240日程度の稼働日数だったとすると、約2日に1サイトのペースで立ち上げさせて頂いた事になります。

このサイト数を立ち上げられた背景には、弊社の主力商品である「EXTRA」のシステム的な立て付けがエンタメ業界用に最適化されている事があげられますが、

システム的なバックエンド側の話はエンジニアチームにお譲りするとしてして、今回は我々クリエイティブチームが取り組んでいるサイト立ち上げ時のフロント側の効率化・最適化に関して記してみようと思います。

はじめに

まず、SKIYAKIの事業の1つとして「アーティスト支援」を掲げておりますので、"より多くの" アーティスト、タレントさんなどのサイトを立ち上げさせて頂き、

「WEBでの情報発信の場」や「ファンクラブや専用ストア設立に伴う活動資源の調達の場」「ファンサービスの拡充の場」などをご提供させて頂きたいという思いで日々の業務に取り組んでおります。

"より多くの"というところがポイントで、それを実現するには限られたリソースと限られた時間の中で効率よくサイトを立ち上げていく必要があります。

それには、日々の業務内容を細かく洗い出し、パターン化しておき、ムダを省いていくというのがまず大切だと考えております。

それに加え、アーティストやタレントさんの世界観の表現や、サイト内の誤表記・誤作動などを極限にゼロになるようにも努めなければいけません。

そこでクリエイティブチームでは、以下のような取り組みを行い、サイト立ち上げの効率化・最適化を進めています。

サイト立ち上げの必要項目をリスト化

これはクリエイティブには関係ないのではないかと思われるかもしれませんが、基本的な事でとても大切です。

サイトを構築する際に、必要となる情報を予めリスト化して、プロデューサーにはそのリストに沿って情報を予めまとめてもらいます。 言ってみれば仕様書ですね。

仮にこの仕様が決まっていなくて、仮の内容やデータで作業を進めるとします。 そうした時に、仕様が想定のものから変わってしまってページの修正が出てしまったり、仮データがそのままサイト内に残ってしまっている事に気付けずミスに発展する危険性もあります。

それを予めリスト化して洗い出しておくことで、そういった作業の巻き戻りの時間ロスや、誤ったデータの混入というのを未然に防ぐ事ができます。

そして、プロデューサーもサイトを構築する際に何を確認すればいいのかが一目でわかりますし、構築する側としてもそのリストを元に必要なページやデータを用意すればいいので、作業が進めやすく、作業漏れも極限に無くすことができます。

レスポンシブデザインの採用

今となっては一般的な技術ですので真新しい事ではありませんが、弊社でもできる限り再現可能なものは「レスポンシブデザイン」で構築しております。

仮にPCとスマートフォンタブレットの記述を別々にしていく場合、テンプレート、CSS、JS...など、広域に渡ってそれぞれの記述をする必要が出てきてしまうため、 約2倍(厳密には2倍ではないと思いますが...)程度の構築時間を要してしまう事があります。

そこを1ソースで各デバイスに対応できるレスポンシブデザインの技術を採用すれば、そこでも構築時間を短縮できます。

またレスポンシブサイトの場合、特に運用フェーズに入ってからもPC、スマートフォンタブレットの記述が1ソース内にされているので、修正などの対応もしやすくなり事故の軽減にも役立ちます。

サイトのデザインテンプレート化

予め弊社独自のサイトの骨組みを複数パターン用意しておき、その中からお好みのデザインパターンを選んで頂くという手法を取っております。 (※もちろんテンプレートではなく、フルスクラッチでデザイン・構築させて頂く場合もございます)

各アーティストさんやタレントさんによって世界感は異なってきますので、大枠の骨組みだけはテンプレートを使用して頂き、サイト全体の色味や使用フォントなどは、都度デザイナーが各アーティストさんやタレントさんにマッチするデザインをデザインをご提案させて頂いております。

そうさせていただく事で、 ・骨組みを一定化させて頂く事でサイトの構築スピードをあげられる ・デザイナーが都度デザインする事で各アーティストやタレントさんの世界感を表現できる

といった事が実現でき、見た目と構築スピードを保ちつつサイトを構築する事ができます。

また、フォントの指定に関してもできる限りWebフォントを採用させて頂くようにご相談させて頂くなど、細かい部分でも時間軽減できるように努めております。

デザインパーツのコンポーネント

例えばですが、News記事をリスト表示させる時に、「サムネイルを出したい」「サムネイルはいらないけど本文はちょっとだけ見せておきたい」などなど、 サイトに応じて要望が異なってくる事があります。

その場合、都度テンプレート上の記述とCSSを調整する必要が出てきますので、ここでも時間のロスが生まれる可能性があります。

そこで弊社では過去の経験を元に、予め複数パターンのコンポーネントを用意しておく事で、サムネイルありバージョンならこのコンポーネントを使うといったように対応し、構築時間の短縮に取り組んでいます。

また、コンポーネント化のメリットはソースレビューでも活かされます。

弊社のコンポーネントは、テンプレート、CSS、JSが1セットになっていますので、ソースの記述が一定で、書くスタッフによって記述の差がなくなります。

そのため、ソースレビューの時間を軽減できると共に、一定品質の表示を短時間で実現する事ができます。

最後に

今回の内容以外にも、開発環境面やツール面などなど、まだまだ構築の効率化に関する事項はありますが、今回は私が特に意識している点をピックアップさせて頂きました。

今後もスタイルガイドを作り込んでソースを全体的に一定化していったり、テンプレートパターンを追加していくなど、より、効率的に高品質のサイトをご納品できるようにチーム一丸で取り組んでいこうと思います。

nightmare.js で E2E テストをする足がかりを探る

はじめに

弊社で稼働中のプラットフォームでは、rspec によるテストを流していますが、End to End テストと呼ばれているレベルのテストはまだ動いていません。 そこで、nightmare.js を使って、E2E テストをしつつ、稼働中の 154 サイトすべてのスクリーンショットを撮ってみたいと思います。

ディレクトリを作って package.json を生成する

適当にディレクトリを作ります

mkdir myfirste2etest && cd myfirste2etest

node の バージョンを指定して npm init します。今回は現時点の stable である v4.0.0 を利用しました。

nvm use v4.0.0
npm init

いろいろ尋ねられるので以下のように答えました。

This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (myfirste2etest)
version: (1.0.0) 0.0.1
description: My First End to End Test
entry point: (index.js)
test command:
git repository:
keywords: nightmare.js
author: okamoto-skiyaki
license: (ISC)
About to write to /Users/motchang/src/myfirste2etest/package.json:

{
  "name": "myfirste2etest",
  "version": "0.0.1",
  "description": "My First End to End Test",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "nightmare.js"
  ],
  "author": "okamoto-skiyaki",
  "license": "ISC"
}


Is this ok? (yes) yes

ここで一応 git init しておきます。.gitignore の生成に gibo を使用してみました。便利!

参考:気付いたら.gitignoreはgiboで自動生成する時代になっていた

git init
brew install gibo
gibo node osx emacs > .gitignore
git add .
git commit -m 'initial commit'

nightmare.js, そして普段 coffee script で開発を行っているので、coffee script も入れます。 また、運用中のサイト情報が mysql にありますので、mysql もついでに入れてしまいます。

npm install --save-dev nightmare
npm install --save-dev coffee-script
npm install --save-dev mysql

スクリーンショット保存用のディレクトリを作る

mkdir screenshots

カカカッっとスクリプトを書く

MySQL からドメインの一覧を取得し、MSIE を名乗った時と iPhone を名乗った時のスクリーンショットを撮ってみました。

Nightmare = require('nightmare')
nightmare = Nightmare({show: true})

MySQL = require('mysql')

browsers = [
  {name: 'msie', ua: 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko', width: 1920, height: 1080},
  {name: 'iphone6', ua: 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_0 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13A344 Safari/601.12', width: 375, height: 627}
]

connection = MySQL.createConnection({
  host: process.env.MYSQL_HOST || 'localhost',
  user: process.env.MYSQL_USER || 'root',
  password: process.env.MYSQL_PASSWORD || '',
  database: process.env.MYSQL_DATABASE || 'test',
  port: process.env.MYSQL_PORT || 3306
})
connection.connect()

connection.query('SELECT * FROM sites WHERE closed_flag = 0;',
  (err, rows) ->
    if (err != null)
      console.log(err)
      throw err
    for row in rows
      url = "#{row.site_protocol}://#{row.site_domain}"
      for browser in browsers
        nightmare
          .viewport(browser.width, browser.height)
          .useragent(browser.ua)
          .goto(url)
          .wait()
          .wait(1000)
          .screenshot("screenshots/#{row.site_domain}_#{browser.name}.png")
          .end()
    nightmare.run()
)

connection.end()

以下のようにスクリーンショットの一覧が完成します。

f:id:system-skiyaki:20160229235206p:plain

f:id:system-skiyaki:20160229235234p:plain

f:id:system-skiyaki:20160229234753p:plain

本当はページ全体のスクリーンショットを撮ろうと考えていたのですが、付け焼き刃の nightmare 能力ではなんともなりませんでした…。それっぽいコメント を見つけたのですが、上手くいかず。これからの課題にしたいと思います。

pwgenを使って重複しない乱数を作ろう

SKIYAKIエンジニアのabeです。 重複しないパスワードだったりシリアルナンバーだったりが必要になる場面ありますよね。 そんなときはお手軽で柔軟なpwgenを使ってみては?

pwgen -s 16 10000 > hoge.txt

こんな感じで叩くと16桁のパスワードを10000個生成してくれます。 pwgenは覚えやすいパスワードを生成するツールですが、-sオプションをつけることで完全ランダムなパスワードにしてくれます。

sort hoge.txt | uniq -d

uniqコマンドで重複をチェックします。 何も表示されなければOK。


参考

historyをインクリメンタルサーチして実行したりする

SKIYAKIでエンジニアをしてるらしい kouno と申します。

普段は横須賀で提督業に勤しんだり、焼却された人理の復元をしてたりしますが、エンジニアブログに何かを書けと言われたので、少し書いてみようと思います。

今までは過去に実行したような気がするコマンドを探すのにhistory | grep hogeとかしていたのですが、peco というものに出合って割とこの辺の探し物とかが便利になったので以下つらつらと。

まずはpecoの導入

環境は MacOSX 10.11.13 とかです。

$ brew tap peco/peco
$ brew install peco

※homebrew導入済みのOSXにて brew tap peco/peco 不要かも?

次にシェルの準備

[~/.bash_profile]
shis () { #search shell history
  if grep -q '^[0-9]\+$' <<< "$1";then
    history $(($1 + 1))
  else
    history
  fi | sort -r | sed 1d | peco --prompt "Select history to copy:" | cut -d ' ' -f 5- | pbcopy
  pbpaste
}

rhis () { #run shell history
  eval "$(shis "$1")"
}

実践してみる

これで $ rhis とかすると、history コマンドの結果に対して、インクリメンタルサーチが出来るうえに、 画面上で実施したいコマンドを選択すると、その場で実行してくれます。 実行でなくて、ただ探したいだけの時は $ shis で探して選択する事が出来ます。 ザックリと使い方だけですが、詳細な仕様等は参考下記のURLをご参照下さい。

参考

参考URL

Git を自分仕様にして使いやすくしよう

SKIYAKI でエンジニアをしています、akaishi です。みなさま今日も git status していますか? わたしは事ある毎に git status をして現状確認しています。安全第一。

さてその Git を使う上でコマンドを毎日のように打つのですが、 よく打ち間違えたりしてはそんなコマンドねーよと言われたり、delete ボタンの押す回数が増えたりと typo マスターの名を欲しいままにしているわけなんですね。

なので少しでも自分なりの設定をしておくことでそんなことで使う時間を短縮できます。

alias の設定

alias の設定はとても簡単です。今回は git status を設定してみます。

git config --global alias.st status

はい、ドン!これだけで alias の設定が完了です。システム上の全ユーザー全リポジトリに設定する場合は --system にするだけでも可能です。 わたしは --global に設定して .gitconfig で管理する(後述)方式を採用しています。 他にもコマンドを複数渡したりもできるので

git config --global alias.st '!git status && git stash list'

status と stash の中身を同時にチェックできてとても便利です。

サブコマンドの設定

git ではブランチをお手軽に作成ができるのですが、使う上ではプロジェクト単位でブランチを作ったり 機能毎にブランチを作ったりとしているかとおもいます。その位の粒度だとブランチを見渡すことはそんなに苦労はしないのですが、 ブランチを事ある毎に作る癖があるとそのお手軽さ故についついブランチを切りすぎることがあるんですよね。

私がよくやるのが、 (あっ、これ作れそうだから試してみるか・・)git branch feature/a (これ途中だけど作りなおそうかな・・・)git branch feature/aa (既にブランチ名被ってるのか・・・じゃあ 2 を作るか)git branch feature/a2 などと考えなしに作り始めるとあら不思議、似たり寄ったりのブランチ名と増えるばかりのブランチの完成です。

  feature/a
  feature/a2
  feature/aa
* master
  sample/a
  sample/b
  sample/b2
  sample/c2

あー・・・つらいです。よし、機能っぽい名前を付けていこう!と考えなおすわけですね。

  feature/link_check
  feature/link_check2
  feature/link_check_renewal
* master
  sample/add_message_for_admin
  sample/coming_soon
  sample/csv_generate
  sample/remove_myself

よし、なんの機能かはなんとなく想像つくぞ!

とこのへんまではいいのですが、ブランチの切り替え時には補完をしてくれる git-completion.bash を頼りつつでも途中まではブランチ名を打つのが非常に面倒になります。 じゃあ選択してブランチ切り替え出来るサブコマンドを作成したらいいのでは??ということで作成してみました。

git-branch-list

やっていることはブランチ名を取得して番号で選択出来るようにしたサブコマンドです。ブランチ名を手で打つよりは楽出来るはずです。 次にこのサブコマンドをどこでも使えるように準備します。 準備の方法としては - コマンドが実行出来る場所にファイルを配置する - 好きな場所に配置してPATHを通す

のどちらかになるかと思います。今回は単純にコマンドが実行出来る場所にファイルをシンボリックリンクで配置します。

git clone git@gist.github.com:8f1cfe3a9c3e1eb8ead4.git
cd 8f1cfe3a9c3e1eb8ead4
echo `git --exec-path` && ln -s "$(pwd)/git-branch-list" $_

f:id:system-skiyaki:20160229115029g:plain

あとは git のコマンドが実行できるとこで git branch-list checkout などとすると利用が出来るようになります。 これをさらに alias に設定をするとさらに楽になります。

.gitconfig の管理

色々な alias やらサブコマンドを設定して指が慣れてくると、PCを変えた時に再設定が面倒になります。 そのため設定したものを git で管理をするようにしています。要は dotfiles のことですね。 まずはファイルの移動とシンボリックリンクの準備です。

cd ~
mkdir dotfiles
mv .gitconfig dotfiles
ln -sf ~/dotfiles/.gitconfig ~/.gitconfig

あとはよしなに git で管理しておくだけです。

こういった設定を少しずつして自分仕様にすることで打ち間違い防止や入力効率のUPになります。他にもコミットメッセージのテンプレなどのhook の設定もすると快適なGitライフが送れるようになりますね。