Javascript
2017 04 09 daily
進捗ありません
この1週間、調子が悪かったり仕事に追われたりしていて何も勉強できていない。 少しだけReduxのサンプルを写経して動かない箇所を動くように修正した程度。
ES2015で理解が足りていない事
import Hoge from './hoge'; //hogeファイルの中でexport defaultされたものをHogeとなづけてimport
import * as Hoge from './hoge'; //hogeファイルの中でexportされたもの全てをHogeオブジェクトとしてimport
import { Hoge } from './hoge'; //hogeファイルの中でHogeという名でexportされたものをimport
という理解だったのだけれど、Reduxのサンプルで意図する挙動をしなくて困った。 最終的に記述ミスだったのか、勘違いだったのか、動くようになったけど。
いっぺん基礎を網羅的に勉強しないとダメですね。 しかし、ECMAScript2015のドキュメント原文を読むのはなー。。。
recent frontend circumstance
最近のフロントエンド事情はまるで発展途上国の交通事情ですか
ES6で書いてES5に変換したいだけなのに、なんなんですか?
ES6からES5に変換したいだけなんだ
Babel
Babelを使えば変換できる。。。
Babelを毎回実行するのだるいからWebpackでタスクランナー的に実行する。
考えはいい。それで十分だし、何も難しいことはなさそうだ。
でもいざ環境を揃えようとすると……
以下をインストールする。
- webpack
- webpack-dev-server
- babel-core
- babel-loader
- babel-preset-es2015
webpack.config.jsと.babelrcにも設定を書く。
これですむのならいい。
実行したら文法エラーが出た。
- babel-preset-stage-0
を追加したら解決した。
なんだよそれ!最初からbabel-coreだけで対応しろよ!
他にもbrowserify,babelifyとかいろいろプラグイン的なものがある。
自分の書いたES6のコードを動くようにするのにいったいどれを入れたら動くのか分からない!
BabelとWebpack
webpackの設定及び.babelrcにも何を変換処理に使うのか書かないとちゃんと変換されない。
webpackに書いただけじゃダメで.babelrcにも書かないといけない。という認識だけど、多分理解が足りなくて本当は綺麗な書き方があると信じてる。
まとめ
ES6で書いてES5に変換するの辛い。
早くブラウザが標準でES6対応してほしい。
think about redux
Reduxについて感化されたこと
Reduxについて不満に思っている部分について考察している記事を見かけた。
自分もReduxを少し触ってみて「?」と思っていたことなどが言語されていた。
理解して納得していること
Reactの場合は上からもらうプロパティはPropsで読み取り専用。
要素ごとにstateという読み書き可能なプロパティを持つ。
ReduxはFluxアーキテクチャの実装。
1つの状態を管理するStoreのみ。
Actionを呼びReducerが状態を更新する。それぞれはプレーンなjavacsriptで書く。
ここまではいい。とても素敵に感じた。
受け入れがたいところ
javascriptといえば、画面上の何かを触ったらイベントを拾って画面を変えたりとか、非同期で外からデータを持ってくるとかですよね。
その非同期処理をReduxではどう書くのか、実はActionは処理のオブジェクトを生成するだけだし、Reducerは更新結果の状態を同期処理で作るだけ。
ビジネスロジック的なものや非同期処理はどこに書くのか?
基本的には無い。なので後付け?でてきたMiddlewareてのを作る。
Reduxの思想では、非同期の処理前、処理中、処理結果(成功・失敗)をそれぞれ状態として更新する。
その処理をMiddlewareに書くのだけれど…書くのだけれど、これがすごく気持ち悪いと感じていた。
いろいろ他の書き方が無いのかとか本来自分はどう書きたいのかということを考えると、乖離が大きく、辛い。
その辺りをReducerの状態を更新する処理のところで非同期処理を呼び出して結果を入れる書き方を考えた方がいらっしゃって、外国のReduxのコミュニティに投稿したら、disられてた。
Reduxの基本設計に不備があって、それをごまかすためのMiddlewareは許されて、Reducerに非同期処理結果を突っ込むのは違うとかって言うの、どうなの?
まとめ
ReduxのMiddlewareがいまいち気に入らないので、非同期処理も考慮されたFluxアーキテクチャのオレオレ実装を作るしか無いのか。。。
fmxj.js のサーバーサイドをPHPじゃなくてPerl(Mojolicious)で試す
先日、SeedCodeの方がFileMakerのCustom Web Publishing の為のJavaScriptとServer side で使うPHPのサンプルをGithubで公開されてました。
https://github.com/seedcode/fmxj
概要としては、FileMaker Server の XML公開を使う。
Web公開エンジンにXML公開のためのリクエストをJavaScriptで生成してサーバーサイドスクリプト(SeedCodeのサンプルではPHP)にpostする。
◆ハマった事:サンプルPHPの内容
サンプルのPHPをよく読んでなかった。。。
JavaScriptからFileMakerのユーザーアカウントとパスワードをpost出来るようにキーバリューを元々のpostデータに加えている。それから本来のpostデータからおまけを除くための追加分のパラメータ文字数もpostに加えている。この辺りの仕様にもんりょりする。
-db=dbname&-lay=layname&-query=(q1)&-q1=Status&-q1.value=Vendor&-findquery みたいな通常のクエリデータに
u=undefined&p=undefined&l=コンテンツの文字数
ていうのがくっついてPHPにpostされてくる。
それをPHP側でphp://inputでリクエストのボディを取得して余計なパラメータを削ってpostデータを作り直してcurl使ってPOSTしてた。
そこに気づかずperlで再現しようとした時にpostデータを丸投げしてエラーになってしまっていた。
なんでpostデータをわざわざこねくり回してるんだろう?て思ってた。
サンプルって事でいろいろハードコーディングされてるけど、気にしない。
◆ハマった:Nginxの設定
欲をかいてPerlでサーバーサイド書くにあたって、FastCGIでさらっと書くじゃなくてMojolicious使うことにしたら
WebServer→Nginxでバーチャルホスト(hoge.sample.comみたいな)とmorboで127.0.0.1:3000で動くMojoliciousになって、何が起きたかって言うとクロスドメインの問題が発生してしまい、エラーになる。
これについてはNginxの設定でproxy_passでMojoliciousにリクエストがリバースプロキシされるようにして解決。
しかしNginx、デフォルトではContent-Typeの書き換えができず、JavaScriptにレスポンスされるデータがXMLになっていなくて、意図する結果に終わらない。既にあるヘッダーに値を追加する処理を行ってしまう。
※Nginxで add_header Content-Type ‘application/xml’してもmime-typeの設定ファイルに追記しても
Content-Type text/html;charset=UTF-8に application/xmlの値が追記されるだけになる。
その結果、fmxj.jsがXMLHttpRequestのresponseXMLに値がセットされない。そしてresponseXMLがあるの前提になっているXMLをパースする処理のところで結果が空欄になって処理が終わってしまう。
最初fmxj.js内部を書き換えて(responseTextをXMLに変換して)みたんだけど、コアのライブラリを触るのはよくないので、Nginxでちゃんとヘッダを書き換えられる方法を調べる、nginx-extrasを追加でインストールするとmore-set-headerというのが使えるようになり、ヘッダーの書き換えができるようになるとの事だったのでインストール。
自分はUbuntuの環境なので、
sudo apt-get install nginx-extras
後はNginxの設定ファイルに(厳密に言うとリクエストを受け付けるLocationディレクティブで)
more_set_headers ‘Content-Type: application/xml; charset=UTF8’;
を追記、more…がヘッダーの追記ではなく書き換えなのでcharsetも忘れずに書く!
これでようやく、Sample.html → fmxj.jsを使ってServerにpostリクエスト → 受けたリクエストをNginxがMojoliciousを動かしてるmorboにリバースプロキシ → MojoliciousがPOSTリクエスト受け取りXML公開のクエリパラメータ付きURLを生成して(生成しなおして)cURLをラップしたライブラリからPOST送信 → JavaScriptにレスポンスが返り、完成。
2014年を振り返る JavaScript編
今年を振り返ってみる。クライアントサイド、特にJavaScriptについて
JavaScriptについては今年、なるべくjQueryを使わないようにチャレンジする時期があった。
結局IEとの互換を維持するコードを書かないといけない事を考えるのが面倒になってjQuery使わないの諦めた。
document.getElementByIdとか使える場合は積極的に使ったほうがコストが抑えられるけど、中途半端に混ぜても他のオブジェクトとの兼ね合いで結局jQueryオブジェクトに変換しないといけなかったりして、もにょる。
jQueryでdata属性使うとキャッシュの関係で後から値の変更がうまくいかないとか、なんて地雷だよ!て憤ったよ。
ただ今後はBackbone.jsに手を出していきたいと考えているのでjQueryとは仲良くやっていきたいと思っている。
ただ、思ったよりはJavaScriptの学習や経験は積めなかったのが残念。
もっとCanvasとかSVGのコントロールとか挑戦したかったし、TypeScriptやClojureScriptにも挑戦したかった。
CoffeeScriptはちゃんと学習する前にオワコンになりそうだし、あんまりやらなくていいかなって考えている。
思い出せない
前回の投稿から1ヶ月以上過ぎていて、何か書こうと思ったけど、ここ1ヶ月何やってたか記憶がほぼない。
サーバー関係
ログローテーションの設定を行った。
yum install logrotate
/etc/logrotate.d/配下に追加の設定を行う
/var/log/httpd/_/_logとかやるとユーザーごとに設置したログ・ファイル全てを対象にしたローテーション設定ができる
Ansible
1台のサーバーでTomcat、Gitbucket、Jenkins、Redmineを動かす計画をしているのでVagrantで実験中
ついでにNginxをフロントにおいてGitbucket(Tomcat)、Jenkins、Redmine(Unicorn)、PHP(Apache)にリバースプロキシにする予定。
yumモジュールはnameでhttpでrepl指定してもインストールできるようだ。
後でNginxでリバースプロキシの設定する予定だからTomcatのデフォルトポートはそのままに、Jenknsは8010とか競合しない番号にポート変更。
Tomcatの自動起動スクリプト調べて作ったんだけど、何かよろしくなかったらしい。daemon化うまくいかなかった。
JavaScript
AWSのS3へのアップロード・ダウンロードがJSのみで出来ないか調査。サンプルがいろいろあって試していたら出来た。
マルチパートアップロードの場合はファイルをバッファ分割しながら送信するのがミソ。
AWSのS3のCORSで許可ヘッダーの設定が必要でした。
PHP
namespaceやautoloadをまだ理解しきれていない部分があるようで、読み込みで躓く
毎日ちゃんとメモとらないと駄目ですね。。
低レベルプログラマだからJavaScriptで知らなかった事
JavaScriptで知らないせいでハマったところなどなど
Chromeで確認した時に動いたせいで気付かなかったんだけど、イベントトリガの関数定義で引数にeventオブジェクトを明示して渡さないとIE系では正しく動かない。これはChromeが異常なのかも。
そらそうだという話なんですが、フォームの値は基本テキスト型だからJSで数字として扱って計算したい場合は数字型に変換が必要。そうしないと足し算しようとしたのに文字列連結になってしまう。
JS数字計算で2進数から10進数への変換誤差がでて死ぬる。
100+10.1とかやろうとすると物凄い小さい数字が誤差として丸められず残る。
JavaScriptで7の倍数と7のつく数字の時だけtrue
Javascriptてこんな書き方できるのか
◆7の倍数か7の付く数字の場合のみtrueを返す。
7の剰余が0ではない、もしくは7が含まれる数字が真なら論理値(true)、そうでなければ数値(i)
最初はおぉ?って思ったけれど、こうしてみるとさして不思議でもないか。
fizzbuzz
Javascriptでfizzbuzz
◆シンプルなやつ
=を使わないなら論理値を整数に戻すみたいな面倒なことやる。剰余を用いないならいろいろごちゃごちゃやる。
とりあえず可読性とシンプルさから考えるとこんな書き方になるのかな。