tacamy--blog

JavaScriptを勉強中の人のブログです。

gulpfile.jsをES6で書いてみよう

なぜgulpfile.jsをES6で書くの?

ES6にとりあえず触れて慣れてみたいという場合に、まずはgulpfile.jsで試してみるとよさそうという風潮があるみたい。理由はたぶん次のような感じかなと思ってる。

  • 他への影響が少ない
  • コードの分量が少ない
  • 実装にあまり頭を使わないで書ける
  • 環境によってはbabel等のトランスパイラをインストールせずにES6がそのまま使える

環境を準備する

gulpfile.jsでES6を使えるようにするには、gulp側で対応するか、Node.js側で対応するかどちらかになります。

gulp側でES6に対応する

gulpはv3.9.0からbabelを標準サポートするようになったので、babelを介してES6構文を利用できるようになりました。

ただし、ES6構文を使う場合は、ファイル名をgulpfile.babel.jsにする必要があります

  • gulpのバージョンを3.9.0以上にupdate
  • gulpfile.jsのファイル名を、gulpfile.babel.jsに変更

Node.js側でES6に対応する

Node.jsはv4.0.0からES6に(一部)対応したので、Node.jsのバージョンが4.0.0以上であれば、そのままES6の構文を使うことができます。

  • Node.jsのバージョンを4.0.0以上にupdate
  • ファイル名はgulpfile.jsのままでよい

ちなみに、この記事はNode.js 5.0.0で動作確認しているので、それ以下のバージョンの場合は動かないものもあるかも?(参考:Node.jsでサポートしているES6の構文の一覧

gulpfile.jsで使いそうなES6構文いろいろ

ES6の構文を使うと言っても、gulpfile.jsでは簡単なものしか使う機会はなさそうですが、実際に使いそうな構文をいくつか挙げておきます。

const / let

varconstまたはletに置き換えられます。

ただし、letはあまり使う箇所はなさそう。

今までの書き方

var gulp = require('gulp');

ES6の書き方

const gulp = require('gulp');

Arrow Functions

function ()() =>と書けるようになります。

本来の外側のthisが使えるという機能はgulpfile.jsの場合あまり関係なさそうで、単にタイプ数が少し減ったり、見た目がスッキリするといったメリットくらいかな。

今までの書き方

gulp.task('copy', function () {
  return gulp.src('src/favicon.ico')
    .pipe(gulp.dest('dist'));
});

ES6の書き方

gulp.task('copy', () => {
  return gulp.src('src/favicon.ico')
    .pipe(gulp.dest('dist'));
});

Template Strings

文字列と変数を結合するような場合に、'string' + fooのように+を用いていた部分を、string#{foo}のように書けるようになります。

今までの書き方

gulp.task('sprite', function () {
  var spriteData = gulp.src('images/*.png').pipe(spritesmith({
    cssVarMap: function(item) {
      item.name = 'b-icon--' + item.name;
    }
  }));
  return spriteData.pipe(gulp.dest('path/to/output/'));
});

ES6の書き方

gulp.task('sprite', () => {
  const spriteData = gulp.src('images/*.png').pipe(spritesmith({
    cssVarMap: item => {
      item.name = `b-icon--${item.name}`;
    }
  }));
  return spriteData.pipe(gulp.dest('path/to/output/'));
});

注意点

gulpfile.babel.jsの場合はbabelを使うのでimportが使えるけれど、gulpfile.jsの場合はimportが使えません。

Node.js(v5.0.0時点)ではimportがサポートされていないからです。そのため、ES6をどうやって実行するかによって(ファイル名によって)、次のように記述が変わります。

ややこしいのでどっちの場合でもimportは使わない方がいいのかもしれません。

gulpfile.babel.js

import gulp from 'gulp'

gulpfile.js

const gulp = require('gulp');

まとめ

とくに問題なく使えたので、これからgulpfile.jsを新たに書く場合はES6の構文でよさそう。

CSSではみ出した文字を省略する「text-overflow: ellipsis;」がいつの間にかPCでも使えるようになってた!

領域をはみ出したときに三点リーダー(…)で省略するtext-overflow: ellipsis;は、スマホサイトでは普通に使っていたけど、PCでは数年前に使おうとしてなんかのブラウザでダメだった記憶があって、使えないものとばかり思い込んでいた。

でも、ふとCan I use CSS3 Text-overflowをみたら、めっちゃ対応してた!IEなんて6から対応してるし、Firefoxも7から使えるようになってた。

実際に書いてみたら、いつものこんな感じのコードで普通に使えました。

overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;

昔、JSでなんとかそれっぽくできないかみたいに、誰かががんばっていたのはなんだったのか。

わたしみたいに使えないと思い込んでて、意外としらない人いるかもしれないので、ブログに書いてみました。

楽天カンタン送料表示(Chrome拡張)を公開したよ!

今週の月曜に突如Chrome拡張機能に興味をもって、火曜に勉強を始めて、木曜の今日Chromeウェブストアに公開しました!(∩´∀`)∩ワーイ

f:id:tacamy:20140123143708p:plain

ウェブストアに出てる!!!感慨深い!!!Developer感アル。

どういう機能かというと、楽天の商品ページにいくと、画面左下に送料をすぐに見られるためのボタンが表示されるというものです。

楽天の送料ページは、http://www.rakuten.co.jp/shopName/info2.htmlで見られるのですが、いろいろ面倒です。

  • 送料を見るために、商品ページから画面遷移が必要
  • 送料以外の情報も一緒に書かれている
  • 長すぎてどこを見ればいいのかぱっと見で分からない
  • ショップによって送料ページへのリンクの位置がバラバラ

これらのことを解決したくて、送料の部分のHTMLだけをスクレイピングして取得してきて、商品ページ内で送料をすぐに見られる機能がほしかったのでつくりました。

オススメの勉強方法

Chrome拡張機能についての勉強は実質2時間くらいしかしてないけど、すごくお手軽につくれてしまった。

事前知識ゼロからだったので、まずはドットインストールで勉強しました。1時間くらい。

これだけでかなり概要がわかって、私が作りたいものはカンタンそうだったので、勉強とかいいからとりあえずすぐにつくろうと思って、ほかにはとくに勉強してないです。

公式サイトには、マニフェストの書き方とか、パーミッションの与え方とか、APIの使い方とかぜんぶここに書いてあるのですが、英語なので困ったら見る程度しか使ってない・・。

技術的なこと

ソースコードGitHub上で公開してます。

jQuery使ってるし、とくに大したことは何もしてないのでアレですけど、次のようなことをしています。

パーミッションの設定

楽天の商品ページのURLはhttp://item.rakuten.co.jp/*なのですが、送料ページはhttp://www.rakuten.co.jp/*ドメインが異なるので、manifestにpermissionsの指定が必要でした。

"permissions": [
  "http://www.rakuten.co.jp/*"
],

スクレイピング

送料部分のHTMLにクラス名なりID名がついてればカンタンだったのですが、案の定テーブルレイアウトでそんなものなかったので、下記のような感じで、見出しにあたる部分の文字列を拾ってきて、そこから次のhrまでの部分をとってくるみたいなことしてます・・。

var $data = $(data)
  .find('font:contains("配送について")')
  .parent()
  .nextUntil('hr');

ショップによって、なぜか微妙にこのへんが違う場合があって、たまにこれで取得できない場合もあります。その場合は、ボタン自体出ないようにしました。

われながらめちゃ便利だと思うので、ぜひ使ってみてください!

手っ取り早く Mac でローカルサーバーを立てる方法

ローカルサーバーを立てると、同じネットワークにつながってる別の端末から簡単にアクセスできるようになるから、スマホの表示確認とかに便利。でもいちいち httpd.conf とかいじるのはダルい。このやり方なら一瞬でできるからちょう楽ちん。

ターミナルでサーバー起動

サーバーのルートにしたいディレクトリまで cd コマンドで移動したら、下記コマンドを実行。

$ python -m SimpleHTTPServer 8888

最後の数字はポート番号で、他に使われていなさそうな番号に適当に変えれば、複数のサーバーを同時に起動できる。

ブラウザで表示確認

localhost で確認

ブラウザのアドレスバーに http://localhost:8888/{ファイル名} と入力して表示確認。

表示できてるなら、ローカルサーバーを立てるのが成功してる。表示できなかったら、ターミナルを見て、さっきのサーバー起動時になんかエラー出てないか確認してググろう。

IP アドレスで確認

localhost だと他の端末からアクセスできないので、IP アドレスを使ってアクセスします。

  1. ターミナルで ifconfig と打つか、ネットワーク環境設定の画面を見て、自分の IP アドレスを調べる。
  2. ブラウザのアドレスバーに http://{IP アドレス}:8888/{ファイル名} と入力して表示確認。

これで見れてれば、同じネットワークにいる別の端末から、IP アドレス経由でアクセスできます。

CTO に教えてもろた。

input type=”email” のバリデーションチェックを止めたい

input type=”email” とすると、対応ブラウザの場合、ブラウザ側でバリデーションチェックをして、Email の形式じゃなかった場合はエラーメッセージを表示してくれる。

でもこれがジャマになって止めたいときもある。その場合は form タグに novalidate 属性をつければ抑止できるらしい。

<form>
<input type="email">
</form>

これを、

<form novalidate>
<input type="email">
</form>

こうするだけ。

Chrome のみで確認。

thx @yomotsu 先生

ssh の公開鍵認証のいろは

CTO が分かりやすく教えてくれたので、メモ。

公開鍵の基本

公開鍵とは、github や beanstalk、Heroku などの git を使うサービスを利用するときに必要な、~/.ssh 以下につくられるファイル。

公開鍵と秘密鍵

ファイル名の最後に .pub がついている方が公開鍵、ついていない方が秘密鍵。

公開鍵とは、例えるなら家の鍵穴みたいなもので、誰でも見ることができる。 秘密鍵とは、例えるなら家の鍵で、自分しか持ってないもの。 公開鍵(鍵穴)と秘密鍵(鍵)が一致することで認証される仕組み。 だから、秘密鍵は絶対に公開してはいけない。

rsa と dsa

rsa と dsa の違いは、暗号化方式の違い。

利用するサービスの公開キー登録方法の説明を読んでみて、書いてある方を使えばOK。

公開鍵の使い回し

サービス間での使い回し

サービスごとに別々に鍵を用意して分けてもいいけれど、使いまわすこともできる。

そのサービスで登録しているメールアドレスとは違うメールアドレスが記述されている鍵でも関係なく使い回しができる。サービスの説明ページで、ssh-keygen コマンドで鍵を作成するように書いてあったとしても、すでに別のサービスで作成済みであれば新たに作成する必要はない。

マシン間での使い回し

普通、鍵はマシン固有のものなので、複数のマシンを使うなら、それぞれで鍵をつくらないといけない。 その場合はマシンを買い換えたときも、鍵を新たに作りなおす必要がある。

複数のマシンで鍵を使い回す場合は、~/.ssh 以下のファイルをごっそり別マシンにコピーして、鍵照合すれば使える(?)。

感想

鍵穴と鍵の説明わかりやすくて、CTO さすが CTO。もうこれで怖くない!

gem update --system したら gem update bundler もね!

Sass やら Compass やらの普及で、フロントエンドな人も Ruby や gem に触れることが増えたけど、こないだ調子こいて gem をアップデートしたら、rails server でエラーが出て、rails で作られたシステムが起動できなくなってしまった・・。

エラーの内容はこんな感じだけど、bundler のバージョンはちょっと違ったかも(メモしてなかった)。

/usr/local/rvm/gems/ruby-1.9.3-p385@global/gems/bundler-1.1.5/lib/bundler/rubygems_integration.rb:187:in `stub_source_index170': uninitialized constant Gem::SourceIndex (NameError)

ぜんぜん分からなくて泣いていたら、ほ神ら先生が助けてくれたので、忘れないようにメモします。

やったこと

gem のバージョン確認

$ gem -v
2.0.3

gem のバージョンは、2.0.3 で新しい。むしろエラー出てない人より新しい。これのせい?

bundler もアップデート

$ gem update bundler

いろいろインストールされました。

bundler のバージョン確認

$ bundle -v
Bundler version 1.3.4

新しくなった。そして rails server できるようになりました!

解説

gem の bundler が何かを、Node.js に例えて分かりやすく教えてもらえました。

  1. Ruby の gem は、パッケージ管理ツールで、Node.js だと npm みたいなもの。
  2. npm の場合はプロジェクトごとに管理できるし、-g でグローバルにもできる。
  3. でも gem はグローバルしかできない(Node.js で言う -g だけ)。
  4. プロジェクトごとの管理は、bundler が行う。
  5. gem と bundler の 2 つを合わせて、Node.js の npm みたいに使える。

分かりやすい・・!ほかちゃんは説明の天才か。

まとめ

gem update --system

したら、

gem update bundler

もした方が安全。特に gem がメジャーアップデートとかしてたら、やった方がいいかも。