ベースブランチ以外のブランチで`git clone`する

大抵はこれで持ってくるはずです。

git clone <remote-url>

これに、-bオプションと保存先ディレクトリを指定してあげるだけです。

git clone -b <branch-name> <remote-url> <branch-name>

そのブランチ情報だけ持ってくる

--single-branchを指定するとリモート上のブランチなどを取ってこなくなります。 これでクローンしてくると、.git/configファイルが以下のようになっています。

[remote "origin"]
        url = <remote-url>
        fetch = +refs/heads/fix/<branch-name>:refs/remotes/origin/fix/<branch-name>

これが作業ブランチだとして、masterブランチだけは定期的に取り込むために参照したいような場合は、このファイルのfetchを追加します。

[remote "origin"]
        url = <remote-url>
        fetch = +refs/heads/<branch-name>:refs/remotes/origin/<branch-name>
        fetch = +refs/heads/master:refs/remotes/origin/master

これでfetchすれば取ってこれると思います。

$ git fetch
$ git branch -a
* <branch-name>
  remotes/origin/<branch-name>
  remotes/origin/master

Conditional Types

基本

このような形です。

/**
 * P(arent), C(hild)
 */
type T<U, V> = C extends P ? U : V;

これはCPの拡張形式ならU型に、違うならV型になるという意味になります。

同じプロパティを持ってればtrueな感じ、なので継承はtrue

class P {}
class C {}
// type T = U

class P {
  foo: any;
}
class C extends P {}
// type T = U

class P {
  foo: any;
}
class C {}
// type T = V

Generics で複数の型を提供する

if-else-if-elseのように 2 つ以上の条件も設定できます。

これは属すからtrueな感じ

enum StatusCode {
  BadRequest = 400,
  NotFound = 404,
  InternalServerError = 500
}
/**
 * @alias
 */
type Code = StatusCode;

interface BadRequestResponse {
  code: Code.BadRequest;
  fields: any[];
}

interface NotFoundResponse {
  code: Code.NotFound;
  errors: any[];
}

interface InternalServerErrorResponse {
  code: Code.InternalServerError;
  message: any;
}

type Response<C extends Code> = Code.BadRequest extends C
  ? BadRequestResponse
  : Code.NotFound extends C
  ? NotFoundResponse
  : InternalServerErrorResponse;

type A = Response<Code.NotFound>;
// type A = NotFoundResponse
type B = Response<Code.InternalServerError>;
// type B = InternalServerErrorResponse

infer で一部分の型を取得する

以下は関数の戻り値を取得できます。inferはパターンマッチみたく、その場の型を条件結果の部分で使うことができます。

type ReturnType<T extends Function> = T extends (...args: any[]) => infer F
  ? F
  : never;
type A = ReturnType<() => number>;
// type A = number;

実はReturnTypeは最初から定義されてるので実装はいりません。

type A = ReturnType<Fn>;

例えば、第 2 引数の型が取りたい場合は、引数の型指定部分でinferを使います。

// tslint:disable:no-unused
type SecondArg<T extends Function> = T extends (
  a1: any,
  //  F が [tslint] TypeParameter 'F' is unused. [no-unused]
  // になってしまうので tslint:disable してます
  a2: infer F,
  ...args: any[]
) => any
  ? F
  : never;
// tslint:enable:no-unused
type A = SecondArg<(_a: number, _b: string, _c: boolean) => {}>;
// type A = string

Dart を Mac にインストール

homebrew で入れます。

$ brew tap dart-lang/dart
$ brew install dart
==> Installing dart from dart-lang/dart
==> Downloading https://storage.googleapis.com/dart-archive/channels/stable/release/2.1.0/sdk/dartsdk-macos-x64-release.zip
######################################################################## 100.0%
==> Caveats
Please note the path to the Dart SDK:
  /usr/local/opt/dart/libexec
==> Summary
🍺  /usr/local/Cellar/dart/2.1.0: 339 files, 300.1MB, built in 33 seconds

$ dart --version
Dart VM version: 2.1.0 (Tue Nov 13 18:22:02 2018 +0100) on "macos_x64"

brew コマンドがない人は以下で入れます。

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

関数の静的プロパティの型付け

こんな感じで静的プロパティに値を定義しているような値を想定します。

function foo() {
  /* ... */
}
foo.hoge = '...';
foo.fuga = () => {
  /* ... */
};

依存パッケージの型付け

上のfoofooパッケージで提供されていて、型ファイルが提供されていない時はこのように定義できます。

declare module 'foo' {
  function foo(): any;
  namespace foo {
    export let hoge: string;
    export let fuga: () => any;
  }

  export = foo;
}

これをどこかプロジェクトにfoo/index.d.tsとして作成します。そのモジュールを読み込むと型が効いているはずです。

import foo from 'foo';

foo();
foo.hoge = 'ads';
foo.fuga();

ソースコードの中で

同じようにコードの中で定義すればいいです。
functionで定義するものはそのまま値を入れることで型が付きます。

function foo() {}
foo.hoge = 'string';
// `foo.hoge` は `string`
foo.hoge = 123;
// `foo.hoge` は `string | number`

厳密にしたいならnamespaceを使います。

function foo() {}
namespace hoge {
  export let paths: string;
}
foo.hoge = 'string';
// `foo.hoge = 123` は型エラー

しかし、この方法は関数の中で定義する関数には効きません。
やっぱり、変数に置いて変数の型を設定してあげるといいです。

const foo: {(): void; hoge: string} = function() {};
foo.hoge = 'string';

const createFn = () => {
  const fn: {(): void; hoge: string} = function() {};
  fn.hoge = 'string';

  return fn;
};

gitプロジェクトのルートディレクトリの絶対Pathを取得

プロジェクト以下ならどこからでも実行できるコマンドなどで、ルートディレクトリからの相対 Path で決まったディレクトリやファイルを取得したい時があったりしました。

$ git rev-parse --show-toplevel
/Users/user/dirname

リモートでは削除済みだけどローカルでは参照中のリモートブランチを削除

誰か他の人が削除したか何かでローカルにリモートブランチへの参照が残ってしまった場合。

 git fetch --prune
 # or git remote prune origin

常にそういう参照を削除するようにする

以下のように設定するとfetchだけでfetch --pruneと同じことがされるようになります。

git config --global fetch.prune true

1番新しく付けたタグ名を表示する

これで取得できます。

git tag --sort=-taggerdate | sed -n 1p

--sort=-taggerdateでタグを付けた日が新しい→古い順に並び替えができます。それをsedで最初の1行目だけにしているだけです。

$ git tag 1
$ git tag 2
$ git tag 2
$
$ git tag
1
2
3
$ git tag --sort=-taggerdate
3
2
1
$ git tag --sort=-taggerdate | sed -n 1p
3

シェルスクリプトファイルの作り方

1. ファイル名

.shという拡張子を付けます。

2. 頭にshebang(シバン)コメントを付ける

#!で始まるコメントのことです。#!/bin/shと1行目に書きます。

#!/bin/sh

echo 1

これをecho.shと名付けて保存したとします。

nodejsなら#!/usr/bin/env nodeだったり色々あります。

3. 実行権限を与える

chmod +x echo.shを実行します。

4. 使う

以下のように使います。

./echo.sh
# 1

オプション付きのシェルスクリプトを書く

Mac のgetoptsではロングオプションが使えないみたいなので、そういうの使いたい場合は他の言語つかいましょう。

getopts

-a-bなどハイフンで始まる cli オプションを解析してくれるコマンドです

while getopts <条件> <変数名>; do ...; doneという書き方で書けて、すべてのオプションを繰り返し処理できます。また、このブロックの中では$OPTARGという名前でオプションの値を使うことができます。

条件

オプションでどの文字を使うか設定します。aと書くと-a単体で使うオプションだと設定でき、a:とコロンを置くと-a fooのようにオプション値が必要なオプションだと設定できます。

#!/bin/sh

show_list() {
  # 何か
  return 0
}

show_help() {
  echo 'command'
  echo '  何かコマンド'
  echo ''
  echo 'options'
  echo '  -l <arg>  一覧を表示'
  echo '  -h        ヘルプを表示'
  return 0
}

while getopts hl: option
do
  case "$option" in
    "l" ) show_list $OPTARG ;;
    "h" ) show_help ;;
  esac
done

例外処理

起こす

throwを使うと、その部分で「何かしら変な事が起きた」ことが返せます。

throw new Error('エラーメッセージ');

コメント

JDOC コメントを残すと他の人の助けになるかもです。

/**
 * @throws {Error} こんなの時
 */
function foo() {
  /* ... */
}

起こったエラーを扱う

try-catchを使います。
tryブロックにはエラーが起こりそうな処理を書きます。もし起きた時、throwされたErrorcatchブロックの引数で受け取れます。

try {
  foo();
} catch (err) {
  console.log(err);
  // Error: エラーメッセージ
  //   at Object.<anonymous>

  // ここで扱えないなら再度 throw したり
  // throw err;
}

よく使うエラー

最低限Errorにだけはして返すといいと思います。

TypeError

TypeError オブジェクトは、値が期待される型でない場合のエラーを表します。 TypeError - JavaScript | MDN

引数の型などに想定外の型を渡された時などに使います。

/**
 * @throws {TypeError} num が数値じゃない時
 */
const plusOne = num => {
  if (typeof num !== 'number') {
    throw new TypeError('数値を渡してください');
  }

  return num + 1;
};

SyntaxError

構文的に不正なコードを解釈しようとした場合のエラーを表します。 SyntaxError - JavaScript | MDN

渡された文字列をパースする関数などで、想定外の形の文字列を渡された時などに使います。

const parse = str => {
  const re = /* 正規表現 */;
  if (!re.test(str)) {
    throw new SyntaxError('文字列の形が不正です')
  }

  return Foo.parse(str);
}

自分で作る

Errorクラスを継承して自分のErrorクラスを作ることができます。
Error.captureStackTraceはスタックトレースから無駄を減らしてくれます。

class MyError extends Error {
  constructor(message) {
    super(message);
    Error.captureStackTrace(this, MyError);
  }
}

const foo = () => {
  /* ... */
  throw new MyError('エラー!!');
  /* ... */
};

try {
  foo();
} catch (err) {
  console.log(err instanceof MyError); // true
}

async-await 構文

async-awaitは、「いつ完了するか分からない処理」だけど「順番に実行したい」な事をするために使います。「コールバック地獄」と呼ばれていたような読みづらいコードをシンプルに書けます。

構文

functionの前、アロー関数なら(の前にasyncと書きます。

async function foo() {
  /* ... */
}
const bar = async () => {
  /* ... */
};

そして、中でPromiseを返す関数の実行前にawaitと書けば、処理が終わるまでその場で待ってくれます。

/**
 * 1病待つ
 * (`async`と書くと`Promise`だなとわかるのでオススメしたい)
 */
const delay = async () => new Promise(r => setTimeout(r, 1000));

(async () => {
  console.log('すぐ表示');
  await delay();
  console.log('1秒後表示');
  await delay();
  console.log('さらに1秒後');
})();

エラー処理

await文の例外はtry-catchで扱えるようになります。

class OversleepError extends Error {
  constructor() {
    super('寝坊した');
    Error.captureStackTrace(this, OversleepError);
  }
}

/**
 * 寝る
 */
const sleep = async () => {
  /* ... */
  throw new OversleepError();
  /* ... */
};

(async () => {
  try {
    await sleep();
  } catch (err) {
    console.log(err instanceof OversleepError); // true
  }
})();

また、扱うのはPromiseなのでcatchで一旦受け取ってできるだけ処理するといったことも。

/* 上の関数定義そのまま */

const eatBreakfast = async () => {
  /* 食べる */
};

(async () => {
  const task = {
    breakfast: true
  };

  await sleep().catch(err => {
    if (err instanceof OversleepError) {
      task.breakfast = false;
      return;
    }

    // error が OversleepError じゃない場合、ここでは扱えないので
    // 再度 `catch` か `try-catch` で扱える形にして
    // 親スコープなどで処理する
    throw err;
  });

  if (task.breakfast) {
    await eatBreakfast();
  }
})().catch(err => {
  /* OversleepError 以外のエラーを扱う */
});

関数

1 つ前の記事でpadding: ...だけを返す Mixin を作りましたが、もしかしたらそういう関数を使用したほうが適任かもしれません。関数を使うと値を加工することができます。

関数は@functionを使って定義できます。また@returnを使って何かしら値を返すようにする必要があります。(JavaScript などに似てます)

@function gutter($type) {
  // 他で使わないなら入れちゃっても
  $gutters: (
    sp: 0 0.3em,
    pc: 0 1em
  );

  // not + $gutters に @type (spかpc) が定義されているか
  // -> $type が sp と pc 以外の値の時
  @if not map-has-key($gutters, $type) {
    @error "#{map-keys($gutters)}を指定してください";
  }

  @return map-get($gutters, $type);
}

div {
  padding: gutter('sp');
}

@media screen and (min-width: 768px) {
  div {
    padding: gutter('pc');
  }
}

制御構文

@if

状態には真偽値(boolean)を返すようにします。また、@else if@elseは両略できます。

@if 状態 {
  // ...
} @else if 状態 {
  // ...
} @else {
  // ...
}

@each

連想配列などを回したりできます。汎用セレクタを量産する時とか。

$colors: (
  success: #018952,
  danger: #ed5e6b
);

@each $key, $color in $colors {
  .button-#{$key} {
    background: $color;
  }
}
/* 結果 */
.button-success {
  background: #018952;
}

.button-danger {
  background: #ed5e6b;
}

@for

同じように色々返す時。

@for $i from 1 through 3 {
  .mt-${i} {
    margin-top: $ipx
  }
}
/* 結果 */
.mt-1 {
  margin-top: 1px;
}

.mt-2 {
  margin-top: 2px;
}

.mt-3 {
  margin-top: 3px;
}

値を決めたいようなものは@function化すると Mixin の巨大化も防げるかもしれません。

役に立つカラー関数

Sass ではいくつか便利な関数が最初から定義されているので、それらを簡単に使うことができます。
むしろ関数の為に Sass を使っているようなものなのでぜひ使いましょう。

mix($color1, $color2, [$weight])

2つの色を混ぜます

color: mix(#fff, #000); // #888

lighten($color, $amount)darken($color, $amount)

それぞれ白か黒と混ぜる関数です。ホバー時に色を白く(黒く)したい時に手っ取り早く使えます。

color: lighten(#000, 30%); // #4d4d4d;
color: darken(#fff, 20%); // #ccc;

adjust_hue($color, $degrees)

色相を回転させます。

color: adjust_hue(#f00, 90%); // #80ff00

complement($color)

補色を取得。

color: complement(blue); // yellow

saturate($color, $amount)desaturate($color, $amount)

鮮やかにするか、鈍くするか。

color: saturate(blue, 30%); // #0d0df3;
color: desaturate(blue, 100%); // #888;

// `grayscale` と同じ
color: grayscale(blue); // #888;

この辺に色々定義してあります。

共通ブロックの使い回し

Mixin

ブロック(スニペット)が定義できて、@mixinを使います。

@mixin reset {
  list-style: none;
  padding: 0;
  margin: 0;
}

ul {
  @include reset();
}

Mixin は@include mixin-name()のような形で、そのセレクタに取り込めます。

/* 変換後 */
ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

プレースホルダーセレクター

単純なブロックの時には、Mixin よりプレースホルダーセレクターがいいかもです。これは定義済セレクタを取り込めます。

%reset {
  list-style: none;
  padding: 0;
  margin: 0;
}

ul {
  @extend %reset;
}

@extendはセレクタをまとめる

@mixin foo {
  color: orange;
}
ul {
  @include foo();
}
ol {
  @include foo();
}

%foo {
  color: orange;
}
ul {
  @extend %foo;
}
ol {
  @extend %foo;
}

セレクタが、ul, olになってますね。

// @include
ul {
  color: orange;
}
ol {
  color: orange;
}
// @extend
ol,
ul {
  color: orange;
}

注意点

例えば1行のプレースホルダーセレクター 5 つを 100 個のセレクターで使うとどうなるか。これは 100 個のセレクタが 5 回再定義され、かな〜り長いセレクタになります。
3 行以上のものに制限したり、1,2 行なら汎用セレクターを HTML で使いましょう。

Mixin と引数

こっちにしかない機能です。その場で渡した値から、異なるかもしれないブロックを受け取ることができます。
例でget-gutterを定義しました。

$gutter: (
  sp: 0 0.3em,
  pc: 0 1em
);

@mixin get-gutter($type) {
  @if $type != 'sp' and $type != 'pc' {
    @error '`sp` か `pc` を指定してください';
  }

  padding: map-get($gutter, $type);
}

div {
  @include get-gutter('sp');
}

@media screen and (min-width: 768px) {
  div {
    @include get-gutter('pc');
  }
}

これには$typeという値を渡すことできます。(sppcに制限)正常なら$gutterから値を取得し、paddingで返します。

/* 変換後 */
div {
  padding: 0 0.3em;
}

@media screen and (min-width: 768px) {
  div {
    padding: 0 1em;
  }
}

ファイル分割

Sass では@import <file-path>;といいう構文で別の sass ファイルを取り込むことができます。

例えば、以下のような_base.scssindex.scssがあるとします。

// _base.scss

$font-size: 14px;
// index.scss
@import 'base';

body {
  color: $font-size;
}

最初に@import '_base';とすることでindex.scssでも_base.scssの内容が使えるようになります。baseで読み込んでいるのは入力ミスではなくそういう仕様で、別ファイルに読み込まれることを想定しているようなファイルは_をファイル名に付けるとディレクトリ構造が整えれます。

変数

変数を作る

Sass の変数は頭に$記号を付けて宣言します。以下は$colorという変数に#cf649aという値を定義する例です。

$color: #cf649a;

使う時は、単にその変数名を変わりに使うだけです。

a {
  color: $color;
}

連想配列

恐らく色情報というのは複数定義する必要がでてくるんじゃないかなと思います。例えば、ベースカラーやアクセントカラー、サブカラーみたいな具合に。
これは、-colorというような Suffix を色関連の変数には付けるようにしてもいいかもしれませんが、連想配列を使う方法もあります。これは()で囲んで定義します。

$colors: (
  base: #393939,
  accent: #cf649a,
  sub: #679999,
);

これからはmap-getという関数を使って値を取り出すことができます。

a {
  color: map-get($colors, 'accent');
}

React と AtomicDesign - Template編

atomic - template

Template は Webページの間取り

Templateは、間取りです。家で例えるならこの部屋はこういうことに使おう、あっちの部屋はああいうことに、と決めるような感じです。Webであれば、「header要素はこの中に」「メイン要素はこの中に」となると思います。

そしてベッドなら寝室に置くでしょうし、ブログ記事ならメイン要素に大抵は置くだろうと思いますが、Template層はそういうブログ記事をレイアウトを意識せずにメイン要素に配置できるようにするのが役割です。

Template は Abstract Class

僕は、abstract classを使う方法がお気に入りです。

abstract class DetailTemplate extends React.Component {
  abstract Header(): JSX.Element;
  abstract Main(): JSX.Element;

  render() {
    return (
      <ColumnLayout>
        {/* 上部に固定されるOrganism要素 */}
        <StickyMenu>
          <this.Header />
        </StickyMenu>

        <this.Main />
      </ColumnLayout>
    )
  }
}

継承したコンポーネントでHeaderを定義すると、それは勝手にColumnLayoutStickyMenuの下に配置されレイアウトのマークアップを意識せずに良くなります。 また、これを継承した時にHeaderMainを定義しなければコンパイルエラーにできるので、定義し忘れ防止もできます。

Page層ではこのように継承して使います。

class FooPage extends DetailTemplate {
  Header = () => <h1>タイトル</h1>;

  // `this.props.article` はreduxなどで渡ってきた値
  Main = () => <Article article={this.props.article} />;
}

ちょっとはシンプルになると思います。

`now alias`がおかしいので、正しく動作するシェルワンライナー

now alias がおかしい

保存していたキャプチャがどっかいってしまったので曖昧ですが、now2からnow aliasargument ...みたいなエラーになりnow alias <url> <alias>でやらないと効かなくなってしまいました。

その後、https://github.com/zeit/now-cli/issues/1701こういうものができたのでyarn global add nowで更新し、now aliasは治りましたが、対象のurlが何故か古いものになってしまいます。

解決シェルワンライナー

これです。

now -n appname \
&& sh -c 'now ls appname | while read line; do if echo \"$line\" | grep \"appname-\" > /dev/null; then set $line; echo \"$2\"; break; fi; done;' | xargs -I@ now ln @ appname \
&& now rm appname --safe --yes

1行目

これはただデプロイしてるだけです。ちなみに-nはアプリ名(appname)を指定してます。

2行目

now ls appnameでこのアプリの全部のurlを含む詳細一覧を出します。その一覧を1行ずつ見ていってappname-が含まれている部分が来たらそれが最新のurlを含む行なので、そこからurlを取り出しnow lnへ渡します。

3行目

最後にデプロイしたもの以外(過去にデプロイした古いアプリ)を全部削除します。

分割代入

「ある配列やオブジェクトの1部だけを使うからそれだけ取り出して使いたい」ような時に使えます。

Object

const {取り出したいプロパティ名} = ...とするだけです。

const {a, c} = {a: 1, b: 2, c: 3};
console.log(a); // 1
console.log(c); // 3

万が一同じ名前の変数がスコープ上にあるなら:で別名をつけることができます。

const {a: alias} = {a: 1};
console.log(alias); // 1

また=を使うことで、その値がundefinedの時にデフォルト値が入るようにできます。

const {c = 3} = {a: 1};
console.log(c); // 3

組み合わせると。

const {d: aliasOfD = 4} = {a: 1};
console.log(aliasOfD); // 4

Array

最初の要素だけ取りたい場合は、

const [first] = [1, 2, 3];
console.log(first); // 1

最後だけならカンマで頭の要素を飛び越えて取得します。

const [,,first] = [1, 2, 3];
console.log(first); // 1

またそれ以降の要素をすべて取得したいなら...を使います。

const [,...tail] = [1, 2, 3];
console.log(tail); // [2, 3]

ただ、これは最後の変数値にしか使えません。

const [...head,] = [1, 2, 3];
// これは駄目!

また配列も=でデフォルト値を設定できます。

const [first = 1] = [];
console.log(first); // 1

...の方には設定できません。

const [, ...tail = [2, 3]] = [1];
// SyntaxError: Invalid destructuring assignment target

Slack App で Event Subscriptions を使うための認証の仕方

まず指定したURLが404だったり、間違ったレスポンスの場合、以下の画像のようにエラーが表示されます。

認証前

これは「俺たちが送ったchallenge値をそのまま返してくれよな!」というような意味です。つまり、{challenge: string}の形で返します。

通すサーバーを建てる Express

以下のようなサーバーを建てて、エンドポイントに slack-event.now.sh/event のようなURLを指定した後再度認証すると通ります。

const express = require('express');
const bodyParser = require('body-parser');

app.post(
  '/event',
  bodyParser.json(),
  (req, res) => {
    res.json({challenge: req.body.challenge});
  }
)

app.listen();

認証完了

開発中はサーバーを、localtunnelngrokなどで一時的に晒したり、nowに上げたりすると楽です。