jshitaの日記

勉強したことを書いていきます。

nginx + php-fpm 環境を Docker で構築する時に参考にした記事

シンプルな構成を作ってくれている方がいたので下記リポジトリからクローンする

https://github.com/mochizukikotaro/docker-nginx-phpfpm/tree/simple

nginx の設定は公式を参考に都度、読んでいけば(今の所は)何とかなってる。
よく読むページは以下の4つ。

公式マニュアル(コア関連)
http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files

公式マニュアル(ディレクティブ)
http://nginx.org/en/docs/dirindex.html

公式マニュアル(環境変数
http://nginx.org/en/docs/varindex.html

公式マニュアル(FastCGI関連)
http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html

react + redux の勉強2:コンポーネント

Functional Component と Class Component

React はコンポーネントベースでUIを作成する。
コンポーネントは Functional Component と Class Component という2種類の記述方法がある。

例えば、画面に Hello World を表示するためのコンポーネントを Functional Component で記述すると、以下のようになる。

import React from 'react';

function App(props){
  return (<div>Hello World</div>);
}

export default App;

これを Class Component で記述すると以下のようになる。

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (<div>Hello from functional App</div>);
  }
}

export default App;

状態(state)とプロパティ(props)

this.state.<state-name> でコンポーネントに状態を持たせる事が可能。

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'Bob',
    };
  }
  render() {
    return (
      <div>
        <Greeting name="this.state.name" />
      </div>
    );
  }
}

this.props.<prop-name> で親コンポーネントからデータを取得可能。

import React from 'react';

import PropTypes from 'prop-types';

function Greeting(props) {
  return (<div>Hi {props.name}</div>);  
}

Greeting.propTypes = {
  name: PropTypes.string.isRequired,
};

export default Greeting;

イベントハンドラ

コンポーネントイベントハンドラを付けたい場合には、通常のJSと同様にイベント名に対して関数を渡す。 例えば入力フォームに change イベントを付与したい場合は以下のように onChange に関数を渡す。

import React, { Component } from 'react';
import Greeting from './greeting';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'unknown',
    };
  }
  nameChange(name) {
    this.setState({ name });
  }
  render() {
    return (
      <div>
        <input type="text" value={this.state.name} onChange={(e) => { this.nameChange(e.target.value); }} />
        <Greeting name={this.state.name} />
      </div>
    );
  }
}

export default App;

react + redux の勉強1:環境構築

勉強した内容をメモ。

作業内容

es2016 (ES6) + Webpack + React の開発環境を作成する。

環境構築のためのパッケージ導入

react の開発で利用するパッケージは以下の通り。

名称 説明
webpack webpack本体
webpack-serve webpack 開発サーバー。webSocket に依存しているので、古いブラウザには対応していない。
babel-core es2016 を利用するためのパッケージ
babel-loader es2016 を利用するためのローダー
babel-preset-react react で es2016 を利用するためのパッケージ

これらを yarn を使ってインストールする。

# プロジェクトフォルダを作成
mkdir react_sample
cd react_sample
# package.json を作成
yarn init
# 開発と本番で利用するパッケージを導入
yarn add webpack babel-core babel-loader babel-preset-react
# 開発でのみ利用するパッケージを導入
yarn add webpack-serve webpack-cli --dev

次に プロジェクトルートに webpack.config.js という名前で以下のファイルを作成する。

var docRoot = __dirname + '/public';

// module.exports に代入したオブジェクトは別ファイルから参照可能になる。
module.exports = {
  // mode は 開発の場合には "development"、本番では "production" を設定する。  
  mode: 'development',
  // エントリポイント(プログラムの開始時に呼び出されるコード)を指定する。
  entry: [
    './src/index.js',
  ],
  // コンパイル後の JS ファイルの出力先を指定
  output: {
    path: docRoot,
    publicPath: '/',
    filename: 'bundle.js'
  },
  // ローダーモジュールによる前処理などを記述
  module: {
    rules: [{
      exclude: /node_modules/,
      // ローダーの処理対象を正規表現で指定
      test: /\.jsx?$/,
      // ローダー名の指定やオプションなどの設定
      use: [{
        // babel ( ES6 ) で react のコードを書く。と言う設定を記述
        loader: 'babel-loader',
        options:{
          presets: ['react', 'es2015']
        }
      }]
    }],
  }
  // require 構文で指定するファイルの拡張子を設定する
  resolve: {
    extensions: ['.js', '.jsx'],
  },
};

次に、webpack.config.js で指定している入力先と出力先を作成する。

cd ./react_sample
# src を作成
mkdir src
# src/index.js には alert 関数を呼び出す処理を記述
echo 'alert("Hello World!");' > src/index.js
# public を作成
mkdir public

public/index.html には、以下のHTMLファイルを作成する。

<!DOCTYPE html5>
<html>
  <head>
    <title>Hello World</title>
    <meta charset='UTF-8'>
    <script type="text/javascript" src="./bundle.js"></script>
  </head>

  <body>
    <p>react_sample</p>
  </body>
</html>

これで webpack の使用準備が整ったので、あとは package.json に起動用の scripts 記述を追加する。
以下の記述の scripts 部分を追加する。

{
  "name": "react_sample",
  "dependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.4",
    "babel-preset-react": "^6.24.1",
    "webpack": "^4.6.0"
  },
  "devDependencies": {
    "webpack-cli": "^2.0.14",
    "webpack-serve": "^0.3.1"
  },
  "scripts": {
    "build": "webpack",
    "serve": "webpack-serve --config webpack.config.js --open-path ./public"
  }
}

package.json に scripts を記述しておけば、npm run <script-name> で scripts 記述の右辺側のコマンドを実行してくれる。
例えば、npm run serve とすれば、"webpack-serve --config webpack.config.js --open-path ./public" が実行される。

# webpack-serve を起動する
npm run serve

これで localhost:8080 でローカルサーバーが立ち上がる。
また、webpack-serve は live-reload という機能がついており、src/index.js を編集すると、自動的に再コンパイルされて結果が更新される。

これで開発サーバーの立ち上げは出来たが、webpack-serve は public/bundle.js を生成しない。
bundle.js を生成したい場合は webpack コマンドを実行する必要がある。

npm run build

eslint の導入

JavaScript の構文チェックツール eslint を導入する。

#  eslint と react 用の eslint プラグインをインストール
yarn add --dev eslint eslint-plugin-react
# 設定ファイルを作成する
eslint --init

eslint --init を実行すると対話コンソールが表示される。

あとは ./node_modules/.bin/eslint で検査対象のファイルに構文チェックを実行できるようになる。

ただし、init直後では console.log や document.onload など、ブラウザでの実行を想定した変数が全てエラーになるので
.eslintrc.json を開き、module.exports で外部公開する連想配列に以下の内容を追加する。

"env": {
  "browser": true,
}

sass の導入

sassも導入する。
2018年4月の段階では、extract-text-webpack-plugin の安定板は webpack v4 に対応していないので、 開発版の next バージョンをインストールする必要がある。

yarn add --dev node-sass style-loader css-loader sass-loader import-glob-loader extract-text-webpack-plugin@next

次に、webpack.config.js で module.exports している連想配列に以下を追加する。

  {
    mode: 'development',
    entry: [
      './stylesheets/index.scss',
    ],
    output: {
      path: docRoot,
      publicPath: '/',
      filename: 'bundle.css',
    },
    module: {
      rules: [
        { 
          //
          test: /\.css$/,
          use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' }),
        },
        {
          test: /\.scss$/,
          use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader!sass-loader' }),
        },
      ],
    },
    plugins: [
      new ExtractTextPlugin('bundle.css'),
    ],
  },

これで stylesheets/index.scss を public/bundle.css に変換できるようになる。

react の導入

最後に React を導入する。

yarn add react react-dom  

react は web向けやモバイル向けのものが存在しており、react プラグインは共通で利用されるパッケージ、react-dom はweb で利用されるパッケージになっている。

Linux環境でのユーザディレクトリの英語化

Linux 環境の日本語化は xdg-user-dirs-gtk-update をデフォルトロケールで実行すれば良い。

LANG=C xdg-user-dirs-gtk-update

先頭の LANG=C は、デフォルトロケールでコマンドを実行するという意味になっている。
あとは "デスクトップ" や "ダウンロード" などの日本語ディレクトリの中身を英語版のディレクトリに移し、再起動すれば完了。

ちなみに、現在のユーザディレクトリ設定を確認したい場合は以下のコマンドで可能。

xdg-user-dir DESKTOP
xdg-user-dir DOWNLOAD
xdg-user-dir TEMPLATES
xdg-user-dir PUBLICSHARE
xdg-user-dir DOCUMENTS
xdg-user-dir MUSIC
xdg-user-dir PICTURES
xdg-user-dir VIDEOS

composer 使い方メモ

基本

# composer.json を作成
composer init

# パッケージ追加
composer install --save パッケージ名

# パッケージ追加(開発環境のみ)
composer install --save-dev パッケージ名

composer 高速化

# リポジトリを国内サーバー packagist.jp に変更可能
composer config -g repos.packagist composer https://packagist.jp

# 以下のコマンドで repositories.packagist.org.url の設定が変更されていれば成功
composer global config --list

scripts

例えば "Hello World!" を echo するコマンドを composer.json に追加する場合は以下のように記述する。

{       
    "scripts": {
      "hello" : "echo 'Hello World!'"
    }
}

上記 scripts は "composer hello" とコンソールに入力することで呼び出し可能。

> echo 'Hello World!'
Hello World!

CoffeeScript 基礎

ドットインストールでCoffeeScript を勉強したので内容をメモ。

公式 http://coffeescript.org/

コメントの書き方

# 単体コメント

###
複数行の
コメント
###

JavaScript との構文の違い

  • var は省略可能
  • 文末の ; は省略可能
  • ブレース {} はインデントで表現する
  • () は可能であれば省略可能

例えば、以下の JavaScript コード

var say = true;
if (say) {
    console.log("Hello world");
}

これを CoffeeScript で書くと以下のようになる。

say = true
if say
    console.log "Hello World"

また、 <JSのコード> のように、` で囲めば直接 JavaScript を埋め込む事も可能

文字列

式展開

ダブルクォートで囲んだ文字列内に #{varname} と記述する場合、変数展開される

name = "takahashi"

# 出力:Hello takahashi
console.log "Hello #{name}"

複数行

文字列を複数行に記述してインデントした場合、インデントを自動的に除去した JavaScript に変換してくれる。

msg = "I
       am
       a
       japanese"

# 出力:I am a japanese
console.log msg

ヒアドキュメント

ダブルクォート3つで囲んだ文字列はヒアドキュメントとして解釈される。

html = """
       <div id="main">
         Hello World
       </div>
       """

# 出力:<div id=\"main\">\n  Hello World\n</div>
console.log html

配列の扱い

配列の要素をカンマ区切りではなく、改行にすることが可能。

a = [
    "taro"
    "joro"
    "saburo"
    "siro"
    "goro"
    ]

部分配列や部分文字列に範囲記法が使える。

# 配列の要素すべて
console.log a[..]

# a[3]〜最後の要素まで
console.log a[3..]

# 最初の要素〜a[3]まで
console.log a[..3]

# 部分文字列の取得も可能
console.log "japan"[1..3]

オブジェクトの記述

CoffeeScript の場合、オブジェクトの記述は yaml 形式でも可能。

例えば以下の JavaScript コードの場合

obj = {name: "taro", status: {age: 25, height: 172}}
console.log(obj)

CoffeeScript では以下の2種類の記述が可能

# CoffeeScript で書いた場合
obj = name: "taro", status: {age: 25, height: 172}
console.log(obj)

# CoffeeScript では yaml 形式の記述も可能
obj =
    name: "taro"
    status:
        age: 25
        height: 172

console.log(obj)

if 文

say = true

# 三項演算子 (say) ? ("foo") : ("bar") は使えないが、以下の記述が可能
if say then console.log "foo" else "bar"

# 後置記法が使える
console.log "foo" if say

条件分岐

CoffeeScript では、あいまいな比較は自動的に厳密な記述に変換される。

例. == -> === != -> !==

条件分岐の連結

例えば「 x が 10 ~ 20 の範囲に含まれるか」という記述は以下の表記法が可能

console.log "ok" if 10 < x < 20

条件分岐の記述方法

また、is, isnt や and, or のような条件分岐の記述も可能

=== -> is !== -> isnt

true -> yes on false -> no off

&& -> and || -> or ! -> not

要素の存在確認

in 要素を含むか判定

alert "ok" if 5 in [1, 3, 5]

of オブジェクトのキーを含むか判定

obj =
    name: "taro"
    age: 25
alert "exists" if "taro" of obj

switch 文

case ではなく when と記述し、コロンを記述しなくても良い。

JavaScript

var type = "red"

switch (type){
    case "red":
        console.log "赤"
        break;
    case "green":
        console.log "緑"
        break;
    case "blue":
        console.log "青"
        break;
    default:
        console.log "otherwise"

}

CoffeeScript

type = "red"

switch type
    when "red"
        console.log "赤"
    when "green"
        console.log "緑"
    when "blue"
        console.log "青"
    else
        console.log "otherwise"

# 以下のような記述も可能

switch type
    when "red" then console.log "赤"
    when "green" then console.log "緑"
    when "blue" then console.log "青"
    else console.log "otherwise"

繰り返し

for は以下の記述が可能

# for - in 構文
for i in [0..10]
  console.log i

# 後置 for 
console.log i for i in [0..10]

# 後置 for に

# インクリメントを2ずつ増加する for 
console.log i for i in [0..10] by 2

配列内包

for 文の結果を変数に代入する記法

values = (i for i in [0..10] by 2)
console.log values

while でも可能。

arr = while i < 10
    sum += i
    i++
console.log arr

オブジェクトの場合は以下の通り

obj =
    taro: 100
    jiro: 20
    saburo: 250

for name, score of obj
    console.log "#{name} = #{score}" 

# または console.log "#{name} = #{score}" for name, score of obj

関数

関数の書き方は以下の通り。

func = (name = "unknown") -> console.log "Hello #{name}"
func("taro")

また、即時関数という定義すると同時に実行する記述法も存在する

do -> console.log "foobar"

分割代入

値を複数変数に分割して代入する記法

[a, b, c] = [1, 10 ,100]
# 1 10 100 と表示
console.log a, b, c

# 変数値のスワップも1行で書ける
[a, b, c] = [c, b, a]

# 100 10 1 と表示
console.log a, b, c

オブジェクトの値を代入する場合はキーと同名の変数を渡せば良い

user =
    name: "taro"
    age: 25
    height: 172

# [ ] と違い、{ } で囲む点に注意
{name, height} = user

# taro 172 と表示される
console.log name, height

クラス

下記のような書き方ができる。 メンバ変数は先頭に @ と書く。

class User
  #
  # constructor: (@name, @email) -> 
  # というふうに1行で書くことも可能
  #
  constructor: (name, email) ->
    @name = name
    @email = email
  say: ()-> console.log "I am #{@name}"

taro = new User("taro", "taro@example.com");
# "I am taro" と表示される
taro.say()

継承の書き方は extends 句で行う。

class User
  constructor: (@name, @email) ->
  say: ()-> console.log "I am #{@name}"

class AdminUser extends User
  say: ()-> process.stdout.write "(Admin):"; super()

taro = new AdminUser("taro", "taro@example.com");
# "(Admin):I am taro" と表示される
taro.say()

存在演算子

CoffeeScriptでは ? という演算子で、変数や関数が定義されているかどうかを判定できる。

#
# 以下のコードの出力結果は
#
# found
# found
# not found
#   
# となる
#
for x in [0, false, undefined]
    if x? then console.log "found" else console.log "not found"

まとめ

全体的に RubyPython の構文に近いかたちで JavaScript が書けるから楽しい! あと後置 if とか for が地味に便利で楽しい。

pathogen で vim のプラグイン管理

vimプラグインを導入するために pathogen を導入したので手順をメモ

プラグイン管理について

vim プラグインの読み込み先ディレクトリは runtimepath 変数で管理されています。 pathogen を導入すれば bundle ディレクトリ配下のプラグインを自動的に runtimepath に設定してくれます。

GitHub - tpope/vim-pathogen: pathogen.vim: manage your runtimepath

導入方法

git 経由でインストールします。

cd
mkdir -p .vim/bundle
cd .vim/bundle
git clone git://github.com/tpope/vim-pathogen.git
mkdir ../autoload
cd ../autoload
ln -s ../bundle/vim-pathogen/autoload/pathogen.vim ./

echo "execute pathogen#infect()" >> ~/.vimrc                                                          
echo "syntax on" >> ~/.vimrc                                                                          
echo "filetype plugin indent on" >> ~/.vimrc

上記は、はじめに github から pathogen をクローンします。 次に、pathogen を起動するスクリプトのリンクを autoload フォルダに作成しています。 最後に、.vimrc に pathogen 利用に必要なコードを追記しています。

パッケージ追加方法

bundle フォルダに配置するだけで自動的に読み込んでくれます。 試しに NERDTree をインストールする場合は以下の通り。

cd ~/.vimrc/bundle
git clone https://github.com/scrooloose/nerdtree.git

今まで vim プラグインの導入をしたことが無かったのですが、意外と簡単に導入できますね!