webpack簡単まとめ

はじめに

  • react + echo でSPAを作るぞ、と意気込んだものの色々分からないので、ちょっとずつ進めていく。
  • 自分のレベルはcreate-react-appでTODOアプリくらいは作ってみたけど、なんで動いているのかよく分かっていないよ、くらい
    • node、npmはこの前簡単にまとめてみたのでなんとなく分かる
  • 公式ドキュメントのGuidesを進めていく中で、覚えときたいところ、よく分からなかったところ、忘れそうなところのメモ書き。
  • 具体的なコードは書かないのでモジュール名などでググるべし

Asset Management

  • webpack.config.jsにwebpackの設定を追加していく
  • npm管理されている各種loader(style-loaderなど)をconfig追加すると、各種ファイルをバンドルできる

Output Management

  • jsやcssファイルがバンドルされる際、ファイル名がハッシュになるが、htmlファイルが参照するファイル名は変わらないという問題が発生する
  • html-webpack-pluginを使おう
    • コンパイル毎にファイル名のハッシュが変更されてしまうのを解決してくれる
  • 使われないファイルが出力先フォルダに増えていく問題に対しては、clean-webpack-pluginを使うと、使わないやつを消してくれる。

Development

  • バンドルしたファイルでエラーが起こったとき、バンドル前のどのファイルでエラーが起こったか分からない?
    • webpackのinline-source-mapオプションを使うと、元ファイルのエラーを表示してくれる
  • ファイル変更する度にビルドし直すの面倒だよね?3つの解決方法がある
    1. webpackのwatchモードを使う
      • ファイルに変更があるとコンパイルし直してくれる
      • しかし、ブラウザで表示する場合にはリロードが必要
    2. webpack-dev-serverを使うと、webサーバーを立ち上げてくれて、ファイルに変更があると、コンパイル・リロードを自動でやってくれる
    3. webpack-dev-serverでは、webpack-dev-middlewareを内部的に使っている
      • webpack-dev-middlewareを切り出してカスタマイズして使うことも可能。
    4. とりあえず最初は2の方法でいいのではないかと思う。

Code Spliting

出力されるjsファイルを分割する方法は3つ。

  • ぱっと見は2が良さそう

  • Entry Pointsを分けること

    • webpack.config.jsファイルのentryを複数指定する
    • 簡単で直感的だが、複数ファイルで重複したモジュールがバンドルされる可能性がある
  • CommonsChunkPluginを使うこと

    • 重複したモジュールが1つの別ファイルに出力される
  • Dynamic imports で行うこと

    • インラインで読み込む

参考

React の Quick start の簡単なまとめ

はじめに

  • installなど、そのまま簡単に進められたものは省く
  • React公式ドキュメントを読み進める中で、覚えておきたいもののメモ。
  • github-pagesで動いていてて、コードはgithubにあるが、メモ程度に考えてもらった方が、、、

Rendering Elements

  • Reactで作られた作られたアプリケーションは、通常1つのrootDOMnodeからなる。
    • <div id="root"></div>しかないってこと。
    • 既存のアプリケーションに取り入れるなら、複数の独立したrootDOMを取り入れることになるみたい。
  • React Element(componentをクラスとするなら、elementはインスタンスみたいなもの?)はimmutableだ。
    • UIを変更するには、ReactDOM.render()に新たなelementを渡すしかない。
    • Reactは新旧のelementを比較して、変更部分だけを適用する
      • 仮想DOMといわれる仕組みで、部分的な再描画を行うのでコストが小さい

Components and Props

  • Reactのcomponentには2種類ある
    • functional componentsは、propsの受け取りはできるが、stateの変更は行えない。
    • class componentsは、propsの受け取りもstateの変更も行うことができる。
  • 描画の流れ(公式からそのままコードを持ってきている)
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);
  1. <Welcome name="Sara" /> element を持った、ReactDOM.render() が呼び出される。
  2. React が {name: 'Sara'} を props として持った Welcom component を呼び出す。
  3. Welcom component が結果として、<h1>Hello, Sara</h1> elementを結果として呼び出す。
  4. ReactDOM は効率的に受け取ったelementに合った形でDOMを更新する

  5. componentのpropsの命名は、呼び出されるcontextではなくcomponent単体から考えるべき

    • 再利用性も高まりやすい
  6. props は Read-Only なので、値の変更はできない。

State and Lifecycle

  • componentDidMount()
  • componentWillUnmount()
    • componentがDOMから消える前に呼び出される
  • stateの注意点
    • 直接stateに値を入れていいのはconstructorの中でだけ。
      変更はsetState()で行う
    • stateの更新は非同期に行われうるので、次の変更にその変更を依存してはダメ
      別変数に入れておくとかしましょう
    • stateの更新はマージされる

Conditional Rendering

  • 条件によって表示内容を変えたいときには、JSXの埋め込み表現内で
    • &&オペレーターを使う
    • 三項対立を使う
  • 特定条件でcomponentを表示したくない時には、propsの値によってnullを返す

Lists and Keys

  • component内でlistをレンダリングする場合には下の例のようにmap()を用いる
  • 下の例ではkeyというものを定義しているが、これはReactが要素の変更、追加、削除を特定するために使われる。
    • keyは、componentに渡されない。
const array = [1, 2, 3];
array.map( x => <li key={x.toString()}>x</li> );

Forms

  • formの入力値の制御・送信は、componentのstateで行う。
    • Controlled Componentと呼ばれる
    • onChangeonSubmitを使う
    • 複数のinput要素を扱う時には、それぞれのnameによって変更するstateを決める(handleChaneは共通でよい)

Lifiting State Up

  • 複数のcomponentの値を同期させたい時
    • 上位のcomponentのstateを使い、そのstateをhandleする関数を下位componentに渡す

Thinking in React

  • stateはinteractiveな値
  • stateアンチパターン
    • 親要素から渡されたpropsをstateにすること
    • 変化しない値をstateが変化しないこと
    • 別のstateやpropsから導き出されうる値である場合

次にやりたいこと

  • turorialをやる
  • apiサーバーと連携したアプリを作る
  • typescriptを導入する

npm install のオプションについて

最近はReact+echoでなんか作ろうプロジェクトを進めている!

npm install

  • オプション無し
    • ex) npm intall
    • カレントディレクトリに存在するpackage.jsonに応じて、./node_modules/ 以下にモジュールをインストールする
      • package.jsonとは、パッケージ名や、バージョン、モジュールの依存関係などを管理するファイル
        npm initで対話形式で作成可能
  • -g
    • ex) npm install -g パッケージ名
    • 指定したパッケージがグローバル領域にインストールされる
    • 通常プロジェクト毎にpackage.jsonを作るので、あまり使わないオプション
    • macだと通常 /usr/local/lib/node_modules/ 以下にインストールされる
  • --save
    • ex) npm install --save パッケージ名
    • 指定したパッケージをローカルインストールし、package.jsondependenciesに追記する
      • dependenciesはプロジェクトの実行に必要なものだけを入れるとよい
  • --save-dev
    • ex) npm install --save-dev パッケージ名
    • 指定したパッケージをローカルインストールし、package.jsondevDependenciesに追記する
      • テストモジュールとか

参考

s3の特定ディレクトリにファイルがあるか確認する

S3のバケットディレクトリにファイルが上がっているか、ファイルが空でないかを検知したい。 ので、検知する用のシェルスクリプトを書いた。 あまり綺麗な書き方ではないと思うのでもっといいやり方があれば知りたい。

ディレクトリの想定

特定バケット以下の指定ディレクトリのファイルを確認。 ディレクトリはこんな感じになっている想定。

nekootoko3_no_gohan/[matatabi | saba | catfood]/YYYYMMDDHH/ファイル

matatabi saba catfood ディレクトリ以下には毎時ファイルがアップロードされる。

スクリプト

現在時刻から3時間前に上げられているであろうファイルを確認するバッチ。

DATETIME=$(date -d '3 hours ago' '+%Y%m%d%H')
BUCKET_NAME='nekootoko3_no_gohan'
DIR_LIST="matatabi saba catfood"

ERR_MSG=''

for DIR_NAME in $DIR_LIST
do
    # 手動実行用に実行状況を出力
    echo "inspecting s3://$BUCKET_NAME/$DIR_NAME"

    RES=`/usr/local/bin/aws s3 ls s3://$BUCKET_NAME/$DIR_NAME --sum`
    if echo $RES | grep -sq 'Total Objects: 0'; then
        MSG="$DIR_NAME ni file ga naiyo!!\n"
        ERR_MSG=$ERR_MSG$MSG
    elif echo $RES | grep -sq 'Total Size: 0'; then
        MSG="$DIR_NAME no file size ga 0 dayo!!\n"
        ERR_MSG=$ERR_MSG$MSG
    fi
done

if [ -n "$ERR_MSG" ]; then
    echo -e $ERR_MSG >&2
fi

これをcron設定しよう。 標準エラー出力だけは出力するようにしないと、エラーメールが飛ばないので注意。

MAILTO=alert@alert.jp

5 * * * * /bin/sh どこかのディレクトリ/gohanchecker.sh 1> /dev/null

mysqlで複数カラムを追加・削除したい

mysqlで同一テーブルに対して複数カラムの追加・削除する必要があるときに、
今まで複数のALTER文を発行していたけど、1クエリーで実行できるように書くようにした。

カラム追加

複数行で書くと普通にALTER文を何回か書く感じになる。

ALTER TABLE `table` ADD COLUMN `column1` decimal(11,2) NOT NULL DEFAULT `0`;
ALTER TABLE `table` ADD COLUMN `column2` varchar(255) NOT NULL DEFAULT 'neko';

これを1行で書くと

ALTER TABLE `table` ADD COLUMN `column1` decimal(11,2) NOT NULL DEFAULT `0`,
                    ADD COLUMN `column2` varchar(255) NOT NULL DEFAULT 'neko';

1回のクエリで実行できてなんかいい感じだ。

カラム削除

これも複数行で書くと

ALTER TABLE `table` DROP COLUMN `column1`;
ALTER TABLE `table` DROP COLUMN `column2`;

これを1行で書くと

ALTER TABLE `table` DROP COLUMN `column1`,
                    DROP COLUMN `column2`;

カラム変更をまとめて行う

ADDDROPCHANGEMODIFYはカンマ区切りで1つのクエリでまとめられる。

tableに対して、カラム追加・カラム削除・カラム名(とカラム定義)変更、カラム定義変更を1クエリで行う。

ALTER TABLE `table` ADD COLUMN `column1` decimal(11,2) NOT NULL DEFAULT `0`,
                    DROP COLUMN `exist_column1`,
                    CHANGE COLUMN `old_column_name` `new_column` int(11) NOT NULL DEFAULT '1',
                    MODIFY COLUMN `pi` decimal(11,2) NOT NULL DEFAULT '3.14';

node.js?npm?Javascriptとどんな関係が?

npmnode.jsJavascriptの関係性がよく分からない。

node.js

  • サーバーサイド用Javascript の言語処理系のこと。
    • サーバーサイド用Javascriptってなんやねん。
      • ブラウザで動くJavascript(いつもjsファイルに書いているやつ)と似てるようで実は違うJavascript
        • モジュールの読み込みができたりするんです。
      • nodeコマンドで実行でき、Browserfyを使ってブラウザで動くJavascriptに変換できる
    • 言語処理系ってそもそもなんやねん
      • プログラミング言語で記述されたプログラムをPCで実行するためのソフトウェア。
        .pyファイルはpythonの言語処理系、.goファイルはgolangの言語処理系で実行するよね。
    • nodeコマンドでREPL(Read Eval Print Loop: 対話的実行環境)が出て来るよ(pythonコマンドみたいな感じ)
$ node
> var name = 'nekootoko3';
undefined
> name
'nekootoko3'
> console.log(name);
nekootoko3
undefined
> .exit
$
  • 引数に.jsファイルを持って来ると。

nekootoko.js

var name = 'nekootoko3';
console.log('Soy ' + name + '!');
$ node nekootoko.js
Soy nakootoko3!

npm

  • パッケージ管理ツール
    • pythonでいうところのpip、rubyでいうところのgem
    • 例のnode.js(サーバーサイドJS)をブラウザで動くjsに変換するツールをインストールするぞ!
# パッケージをグローバルにインストール
$ npm install -g  browserify
/usr/local/bin/browserify -> /usr/local/lib/node_modules/browserify/bin/cmd.js
+ browserify@16.1.0
added 140 packages in 7.915s

おわりに

フロントやるぞお

参考

CentOS7にGoの最新版をインストールする

最新版のgoをインストールする流れをまとめてみた

全体の流れ

$ uname -m
x86_64
$ sudo su -
# cd /usr/local/src
# wget https://dl.google.com/go/go1.9.4.linux-amd64.tar.gz
# tar -zxvf go1.9.4.linux-amd64.tar.gz
# mv go /usr/local
# exit
$ vi ~/.bash_profile
下のようにPATHに/usr/local/go/bin を追加する

PATH=$PATH:$HOME/bin:/usr/local/go/bin
$ source ~/.bash_profile

各コマンドの説明

uname -m

$ uname
Linux
$ uname -m
x86_64

sudo su -

  • ルートユーザーになる
    • /usr は一般ユーザーに編集権限がないので

cd /usr/local/src

wget https://dl.google.com/go/go1.9.4.linux-amd64.tar.gz

tar -zxvf go1.9.4.linux-amd64.tar.gz

  • ファイルを解凍する
    • tar ファイルの解凍・圧縮を行うコマンド
      • -z gz対応
      • -x 解凍(extract)
      • -v 圧縮・解凍状況を表示(なくてもいい)(verbose)
      • -f ファイル名を指定(filename)

mv go /usr/local

vi ~/.bash_profile

  • パスを通す

参考