コピペコードで快適生活

明日使えるソースを自分のために

webpack+reactの環境構築メモ

npm install

$ cd my_project
$ npm init
$ npm install webpack -g
$ npm install --save react react-dom
$ npm install --save-dev webpack webpack-dev-server
$ npm install --save-dev babel-loader babel-core babel-preset-react babel-preset-es2015

webpack.config.js

const webpack = require("webpack");

module.exports = {
  // minify
  // plugins: [
  //   new webpack.optimize.UglifyJsPlugin()
  // ],

  context: __dirname + '/src',

  entry: {
    js: './js/index.js'
  },

  output: {
    path: __dirname + '/dist',
    filename: './js/app.js'
  },

  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015']
        }
      },
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015', 'react']
        }
      }
    ]
  },

  devServer: {
    // contentBase: 'dist',
    host: '127.0.0.1',
    port: 8080
  },
};

ビルド

webpack

開発サーバ起動
package.jsonのscriptsに

 "start": "webpack-dev-server"

追加して

npm run start

参考
http://uraway.hatenablog.com/entry/2015/12/25/Webpack_%2B_React_%2B_ES6%E3%81%AE%E6%9C%80%E5%B0%8F%E6%A7%8B%E6%88%90%E3%82%92%E8%80%83%E3%81%88%E3%81%A6%E3%81%BF%E3%82%8B%E3%80%82

http://dackdive.hateblo.jp/entry/2016/04/13/123000#webpackconfigjs-の例

http://dackdive.hateblo.jp/entry/2016/05/07/183335

Elasticsearchことはじめ

仕事でElasticsearch使う必要があったので、GettingStarted!

これはなに?

分散型RESTful検索/分析エンジン
https://www.elastic.co/jp/products/elasticsearch

特徴

  • 速い
  • スケールが容易(クラスタ構成)
  • RESTful APIで全ての入出力が可能

検索時は条件との完全一致ではなく"関連性が高いもの"を返す
http://gihyo.jp/dev/serial/01/js-foundation/0008

RDBとの用語対応表

ElasticSearch
Index > MappingType > Document

RDB
database > Table > record

インストール

rpm -ivh https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.2.1.rpm
chkconfig --add elasticsearch
service elasticsearch start

基本操作

https://www.elastic.co/guide/en/elasticsearch/reference/5.2/getting-started.html

起動確認
curl -X GET http://localhost:9200
{
  "name" : "Ovee1U6",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "_-CFvUxgRFy_4Q4lwKWMjw",
  "version" : {
    "number" : "5.2.1",
    "build_hash" : "db0d481",
    "build_date" : "2017-02-09T22:05:32.386Z",
    "build_snapshot" : false,
    "lucene_version" : "6.4.1"
  },
  "tagline" : "You Know, for Search"
}
インデックスの登録
curl -X PUT http://localhost:9200/customer?pretty
{
  "acknowledged" : true,
  "shards_acknowledged" : true
}
インデックス一覧
curl -X GET http://localhost:9200/_cat/indices?v
health status index    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   customer nXJXYUdyRpG_yxh-qTp7_w   5   1          0            0       650b           650b
ドキュメント登録
curl -X PUT http://localhost:9200/customer/external/1?pretty -d '
{
  "name": "John Doe"
}
'

インデックス/タイプが未作成の場合は一緒に作成される。
ID未指定の場合はPOSTメソッドを指定する。

ドキュメント確認
curl -X GET http://localhost:9200/customer/external/1
{
  "name": "John Doe"
}
インデックス削除
curl -X DELETE http://localhost:9200/customer?pretty
{
  "acknowledged" : true
}

更新操作

変更
curl -X POST http://localhost:9200/customer/external/1/_update?pretty -d '
{
  "doc": {"age": 20}
}
'

ageカラムがある場合は上書き、ない場合は追加される。
他のカラムに影響はない。
メソッドはPUTではなくPOSTなのに注意。

スクリプト使った変更
curl -X GET http://localhost:9200/customer/external/1?pretty -d '
{
  "script": "ctx._source.age += 5"
}
'
ドキュメント削除
curl -X DELETE http://localhost:9200/customer/external/1?pretty
一括登録
curl -XPOST 'localhost:9200/customer/external/_bulk?pretty&pretty' -H 'Content-Type: application/json' -d'
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }

検索&集計

テストデータ登録
curl -X POST 'localhost:9200/bank/account/_bulk?pretty&refresh' --data-binary "@accounts.json"
curl http://localhost:9200/_cat/indices?v

サンプルjsonはここから
https://raw.githubusercontent.com/elastic/elasticsearch/master/docs/src/test/resources/accounts.json
ファイル名の前に@をつける必要がある。

書き方1
curl -XGET 'localhost:9200/bank/_search?q=*&sort=account_number:asc&pretty'
{
  "took" : 83,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1000,
    "max_score" : null,
    "hits" : [
      {
        "_index" : "bank",
        "_type" : "account",
        "_id" : "0",
        "_score" : null,
        "_source" : {
          "account_number" : 0,
          "balance" : 16623,
          "firstname" : "Bradshaw",
          "lastname" : "Mckenzie",
          "age" : 29,
          "gender" : "F",
          "address" : "244 Columbus Place",
          "employer" : "Euron",
          "email" : "bradshawmckenzie@euron.com",
          "city" : "Hobucken",
          "state" : "CO"
        },
        "sort" : [
          0
        ]
      }, ...
    ]
  }
}

q=* -> すべてを指定
sort=account_number:asc -> ソート指定

書き方2
curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" }
  ]
}
'
取得件数指定
curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" }
  ],
  "from": 10,
  "size": 10
}
'
取得カラム指定
curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": { "match_all": {} },
  "_source": ["account_number", "balance"]
}
'
完全一致検索
curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": { "match": { "address": "mill" } }
}
'
bool queryを用いた複数条件指定
curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": {
    "bool": {
      "must": [
        { "match": { "age": "40" } }
      ],
      "must_not": [
        { "match": { "state": "ID" } }
      ],
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}
'
集計
curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      }
    }
  }
}
'

aggs は aggregations(集計) の略。
SQLでいうとこんな感じ。

SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC
集計(平均値を出す)
curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword",
        "order": {
          "average_balance": "desc"
        }
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}
'

ざっとこんな感じで。

JavaScript(ES5)でクラスベースっぽくオブジェクト思考する

JavaScript(ES5)でクラスベースっぽくオブジェクト思考したかったので簡単な書き方をメモ。

var MyObject = function(a){
  // アクセサっぽく
  this.a = a;

  // privateメソッドっぽく
  var privateFunction = function(){
    alert('private function! arg is ' + a);
  }

  // publicメソッドっぽく
  var publicFunction = function() {
    alert('public function! arg is ' + a);
  }
  this.publicFunction = publicFunction;
};


// 使い方
var obj = new MyObject("hoge");
obj.a                 // => "hoge";
obj.a = "fuga";
obj.a                 // => "fuga";
obj.publicFunction(); // => public function! arg is fuga

WindowsでAndroid開発環境を整える

仕事でAndroidアプリを扱うことになったけど、開発環境構築で色々とハマった。同じことを繰り返さないように設定メモを残しておく。

インストール

JDK

ここからダウンロードしてインストールする。
http://www.oracle.com/technetwork/jp/java/javase/downloads/index.html

AndrodiStudio

ここからダウンロードしてインストールする。
https://developer.android.com/studio/index.html

JDKの参照設定

AndroidStudioがJDKを参照できるように設定する。

環境変数

JAVA_HOME に jdkのインストールディレクトリを設定。
 (例: C:\Program Files\Java\jdk1.8.0_112)

・PATH に jdkインストールディレクトリ直下のbin を設定。
 (例: C:\Program Files\Java\jdk1.8.0_112\bin)

AndroidStudioのJDK Location

File -> Project Structureを開いて SDK LocationのJDK location に JDKのインストールディレクトリを設定。

Gitの設定

AndroidStudioは内部でgitコマンドを打つっぽい。コマンドプロンプトでgitコマンドが使えるように設定する。Cygwinっ子の僕はこんな感じで。
http://kinosuke.hatenablog.jp/entry/2016/12/02/151109

開発チュートリアル

Googleから初心者向けのチュートリアルが公開されている。ありがたい。
https://developer.android.com/training/basics/firstapp/index.html

AARファイルの作り方&取り込み方

Googleにドキュメントがある。ありがたい。
https://developer.android.com/studio/projects/android-library.html

なお、AARファイルを取り込むときに modules:aarファイル名 とすると、modulesディレクトリの下にモジュールが保存されるみたい。

実機テスト

こちらをご参考に。
https://blog.codecamp.jp/android_test

コマンドプロンプトでCygwinのシェルを使う

DLLコピー

C:\app\cygwin\bin\cygwin1.dll

C:\Windows\System32

配下にコピーする。

環境変数設定

システム環境変数のPATHに下記を追加。

C:\app\cygwin\bin
C:\app\cygwin\usr\bin
C:\app\cygwin\usr\local\bin

最後に

再度ログインする。これで使える。

CygwinはC:\app\以下にインストールされている前提。
※参照:http://news.mynavi.jp/articles/2013/11/25/zerokaracygwin/

Gruntの基本をおさえておく

仕事でGrunt使う機会があったので、きちんと基本を押さえておくことにしました。

Gruntってなに?

WEBフロント開発で使うJavaScriptCSSの変換ツール
目的は、JSやCSSを書きやすい形で実装して、ブラウザで実行できる形に変換する環境を提供すること。
主にやることは下記。

  • CoffeScript/TypeScriptのJS変換
  • SCSS/LESSのCSS変換
  • JavaScript/CSSの圧縮(minify)

環境構築

例えばこんな感じで。nodejsが必要なのでnvmでインストール、gruntコマンドを使うためにgrunt-cliをインストールしています。

cd ~
curl -o- https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
export NVM_DIR="/home/vagrant/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm install 6.9.1
nvm alias default 6.9.1
npm update -g npm
npm install -g grunt-cli

プロジェクトつくる

my-projectというディレクトリにpackage.jsonを作成します。
package.jsonはこのプロジェクトで使用したいプラグインを記述するファイルです。

mkdir my-project
cd my-project/
npm init

Gruntをインストール

npm install grunt -save-dev
npm install grunt-contrib -save-dev
npm install grunt-contrib-concat -save-dev
npm install grunt-contrib-cssmin -save-dev
npm install grunt-contrib-uglify -save-dev
npm install grunt-contrib-watch -save-dev
npm install grunt-contrib-connect -save-dev

Gruntがインストールされます。-save-devオプションでpackage.jsonにも追記されます。
ついでにpluginもインストールしています。
※warning出まくるけど無視(していいのかわからんけど)。

Gruntfile.jsの作成

Grunt実行時の処理を記述するGruntfile.jsを作成します。
たとえばこんな感じ。

module.exports = function(grunt) {
  //Gruntの設定
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    // ファイル結合だけ
    concat: {
      js: {
        src: ['src/js/*.js'],
        dest: 'build/application.js'
      },
      css: {
        src: ['src/css/*.css'],
        dest: 'build/application.css'
      }
    },

    // CSSの結合+圧縮
    cssmin: {
      minify: {
        src: ['src/css/*.css'],
        dest: 'build/application.min.css'
      }
    },

    // JSの結合+圧縮
    uglify: {
      build: {
        src: ['src/js/*.js'],
        dest: 'build/application.min.js'
      }
    },

    // ファイル変更を感知して自動的にタスク実行する設定
    // いちいちgruntコマンド叩かなくてよくなる
    watch: {
      css: {
        files: ['src/css/*.css'],
        tasks: ['concat:css', 'cssmin']
      },
      js: {
        files: ['src/js/*.js'],
        tasks: ['concat:js', 'uglify']
      }
    },

    // 簡易サーバ
    // grunt connect で起動する
    connect: {
      local: {
        options: {
          port: 9998,
          livereload: true,
          keepalive: true,
        }
      }
    },
  });

  // プラグインを読み込む
  // usage: http://gruntjs.com/plugins
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-connect');

  // grunt 実行されるタスク
  grunt.registerTask('default', ['concat', 'cssmin', 'uglify']);

  // grunt dev で実行されるタスク
  grunt.registerTask('dev', ['concat', 'cssmin', 'uglify', 'watch']);
};

Grunt実行

あとは変換対象の src/js/*.js, src/css/*.css を配置してgrunt実行。

grunt         # => これでCSS/JSの変換処理
grunt dev     # => ファイル変更があったときに自動的に変換処理
grunt connect # => 簡易サーバ立ち上がる

ディレクトリの容量を表示する - duコマンド

書式

du [オプション] [ディレクトリ名|ファイル名]

主なオプション

-a # ディレクトリ内の各ファイルに対しても使用量を表示する
-b # 結果をバイト単位で表示する
-k # 結果をキロバイト単位で表示する(デフォルト)
-s # 合計サイズのみを表示する
-h # 人間に分かりやすい表記で出力する

容量を圧迫しているディレクトリ・ファイルを調査する

まずはおおよその見当をつけて調査。下記では、カレントディレクトリが対象。

$ du -sh *
16K Maildir
396K script
24M SRC
32K tartest