2017/05/31

[JavaScript]オブジェクトの無効なプロパティをすべて削除する

とあるツールにJSONを渡すとき、極力ツールのデフォルトの値を使いたかった。しかし、空文字やnull、undefinedなどのプロパティがあるとデフォルト値がうまく設定されなかった。
そのため、オブジェクトに含まれる無効なプロパティ(空文字、null、undefinedなど)など任意の条件でプロパティを削除する関数をつくった。

2017/05/30

ES6のObject.assignがシャローコピーなのでディープコピーする方法を考える

ES6(ES2015)で実装されたObject.assignでディープコピーできると思っていた時期が私にもあった。
Object.assignでディープコピーして(した気になって)、プロパティの値を変更したとき、元のオブジェクトにも影響していることに気づいた。

// Object.assign.js
const obj1 = {
  hoge: 'hoge',
  fuga: {
    foo: 'foo'
  }
};

// ディープコピーのつもり
const obj2 = Object.assign({}, obj1);

obj2.hoge = 'hogehoge';

// obj1.hoge: 'hoge'  obj2.hoge: 'hogehoge' ← ディープコピーされてる?
console.log('obj1.hoge:', obj1.hoge, 'obj2.hoge:', obj2.hoge);


obj2.fuga.foo = 'foofoo';

// obj1.fuga.foo: 'foofoo'  obj2.fuga.foo: 'foofoo' ←?!?! 
console.log('obj1.fuga.foo:', obj1.fuga.foo, 'obj2.fuga.foo:', obj2.fuga.foo);

プリミティブ型はコピーされているのだが、参照型(上記の例ではObject)では参照先がコピーされていた。

2017/05/25

[JavaScript]動的なテキストの幅を取得し、スタイルを適用する

動的に生成されるテキストを、その幅にあわせてスタイルを適用したいときがある。
しかし、文字数による判定では英語や日本語による違い、等幅フォントやプロポーショナルフォントによる違いを考慮しなければならない。
バイト数による判定も、同様の違いや文字コードによる違いがある。

「テキストが表示されたときの幅」を取得し、その「幅」で判定できれば、それが一番正確だろう。
ということで、動的に表示されるテキストの幅(width)を取得し、幅にあわせてスタイルを適用できるようにする。

2017/05/23

Sortable.jsでD&Dしたときに:hoverのスタイルが残るバグの対処法

jQuery不要でドラッグ&ドロップで要素の並べ替えができるSortable.jsを使っていたのだが、Chromeで不可解なバグを見つけてしまったのでその対処法をまとめる。(※詳しくは後述するがSortable.jsのバグではない)

2017/05/22

Karma+mocha+chaiでNode.jsとブラウザで同じコードでテストする

Node.jsでもブラウザでも使えるライブラリを作っているときに、「どちらも同じテストコード(同一ファイル)を使って実行できないかなぁ?」と思い、いろいろ調べた。

Karmaがフロントエンドのテストツールで有名なので、これを使ってみる。
また、テストコードについては使い慣れているmocha+chaiのセットで書く。
(mocha+power-assertとかJasmineとかでもできるけど…)

2017/05/17

ロード中に表示するシマー効果付きスケルトンスクリーンを実装する

ロード中にユーザの離脱を防ぐためには、プログレスバーやスピナーを表示する手法が定番だ。フリーズしているわけではなくて、ちゃんと処理してますよと示すことにより、ユーザのストレスを軽減できる。

4秒未満ならスピナー、それ以上ならプログレスバー。
所要時間がわかるならプログレスバー、わからないならスピナー。

など使い分けもされている。


しかし、ここ1〜2年くらいでプログレスバーやスピナーのかわりに、スケルトンスクリーンを使っているアプリやサービスが増えた。有名どころでは、FacebookやSlack、Mediumなどだ。

今回は、スケルトンスクリーンの実装方法を紹介する。

2017/05/15

[JavaScript]外部URLから画像を読み込んで表示する(+クロスドメインを突破する)

アイコン登録機能があるWebサービスをつくっていた。
基本的な操作方法は、以下のとおり。

  1. アイコン画像を用意する
  2. 画像を選択する(<input type="file">を使う)
  3. 画像を読み込み、エンコードして表示する
  4. base64エンコードした文字列をDBに保存する

これでも必要十分な機能はあるのだが面倒くさい。
できれば画像のURLを指定したら、それを読み込んでほしい。

ということで、「URLから画像を登録」機能を実現するためにいろいろ考えてみた。

2017/05/12

TypeScript + express-openapiでOpenAPI(Swagger)準拠のRESTful APIをつくる

仕事でOpen API(旧Swagger)について調べる機会があった。せっかくなのでNode.jsでOpen APIに準拠したRESTful APIをつくろうと思う。

今回はexpress-openapiというフレームワークを使う。Express.jsを拡張し、スキーマのバリデーションをしてくれたり、コードを管理しやすくしてくれたりする。また、標準でTypeScriptをサポートしているので、チーム開発にも向いている。

使う環境やフレームワークは以下のとおり。

  • Node.js: 6.10.2
  • TypeScript: 2.2.2
  • express: 4.15.2
  • express-openapi: 0.35.0

2017/05/11

ORMをTypeScriptでサクッと実装するならtypeormがオススメ

久しぶりにTypeScriptを書いて型のある喜びを感じていた。そして以前使っていたSequelizeをTypeScriptで使ってみようと思ったのだが、深淵を覗いてしまったようだ。

Sequelizeは高機能で便利なのだが、これをTypeScriptで書こうとするとかなりツライそうだ。実際の使い方は以下の記事を参照ください。


TypeScriptで素直に書けるORMはないかな?と探したところ、typeormを見つけた。

typeormは、MySQLをはじめ、PostgreSQL、MariaDB、SQLite3、MS SQL Server、Oracle、WebSQL databaseと主要なデータベースをカバーしている。
また、ライブラリ自体がTypeScriptで書かれているため、デコレータなどを使ってサクッと実装することができる。

今回は、手っ取り早く試したいのでSQLite3で使ってみる。

2017/05/01

SlackのEmojiアイコンでスロットを作ってCSSスプライトを学ぶ

Googleのトップアイコンや、Twitterのいいねボタンのアイコン、SlackのEmojiなどで、CSSスプライトがつかわれている。複数のアイコンを1枚の画像にすることで、読み込み回数を減らしパフォーマンス向上を図る手法だ。

ということで、CSSスプライトの勉強も兼ねて、SlackのEmoji画像を利用してスロットをつくろうと思う。