eyecatch
Sun, Aug 19, 2018

React + Reduxアプリケーションプロジェクトのテンプレートを作る ― その1: Node.jsとYarnとBabelとwebpack

昔、Dojo Toolkitを使ってFlashなUIをJavaScriptに書き換えた時以来、仕事でWeb UIを触ることはなかったんだけど、最近になってWeb UIを書かなければいけなくなるような気がして再学習を始めた。 題材はReact (とRedux)。 今一番人気のフロントエンドフレームワークで、昔触ったこともあるので。 前回の記事でReactが生まれた経緯を学んだので、今回から実習に入る。 (adsbygoogle = window.adsbygoogle || []).push({}); プロジェクト作成 ちょっとCreate React Appを触ってみたけど使わないことにした。 すぐ開発始められるのはよかったんだけど、裏でなにが起こっているかわからな過ぎて肌に合わないし、使うライブラリが結構固定されちゃいそうだったし、トラブルシュート(特にライブラリのバグを踏んだ時)が大変そうだったので。 代わりに、公式で紹介されているブログ記事であるCreating a React App… From Scratch.を見ながら、スクラッチからプロジェクトを作ることにした。 環境はWindows 10 Home。 Node.jsインストール なにはともあれNode.js。 Node.jsのバージョン管理には以前はnodist使っていたんだけど、こいつは2年ほど前に開発が止まっているので、代わりにnvm for Windowsを入れた。 nvm installで任意のバージョンのNode.jsをインストール出来て、nvm useで使うNode.jsのバージョンを切り替えられる。 今回使うNode.jsのバージョンは、現時点でLTS版の最新である8.11.4にする。 C:\>nvm install 8.11.4 Downloading node.js version 8.11.4 (64-bit)... Complete Creating C:\Users\kaitoy\AppData\Roaming\nvm\temp Downloading npm version 5.6.0... Complete Installing npm v5.6.0... Installation complete. If you want to use this version, type nvm use 8.11.4 C:\>nvm use 8.11.4 Now using node v8.11.4 (64-bit) Yarnインストール パッケージマネージャにはYarnを使う。 Yarnちょっとバギーだとか、npm 5がlockファイルをサポートしてYarnの優位性が減ったとか、Yarnからnpmに戻るためのツールが出てきたりしてるけど、現時点では深く考えずにYarnでいいと思う。 YarnはWindows環境ではMSIファイルをダウンロードして実行すればインストールできる。 (npmでもインストールできるけど邪道。) Yarnはv1.7.0を使う。 package.json生成 プロジェクトの構成情報を記述するファイルであるpackage.jsonをYarnで生成する。 C:\>mkdir react-redux-scaffold C:\>cd react-redux-scaffold C:\react-redux-scaffold>yarn init yarn init v1.7.0 question name (react-redux-scaffold): question version (1.0.0): question description: React Redux Scaffold question entry point (index.js): src/index.jsx question repository url: https://github.com/kaitoy/react-redux-scaffold.git question author: kaitoy question license (MIT): question private: success Saved package.json Done in 40.38s.
eyecatch
Thu, Aug 16, 2018

Webアプリケーションフロントエンド年代記 - 2018年夏編

Webアプリケーションの、主にフロントエンド周りに関連する歴史をまとめた。 (adsbygoogle = window.adsbygoogle || []).push({}); 静的サイト まずは原初の話から。 1990年代前半、まだWebアプリケーションという言葉が無かった時代。 静的にHTMLファイルを配信するだけのWebサイト(静的サイト)だけがあった。 静的サイトでは、HTTPサーバーに複数のHTMLファイルを置いておいて、クライアントのHTTPリクエストのURLのパスによって配信するHTMLファイルを変える。 例えば、HTTPサーバーをhttpdで立てて、ドキュメントルートを/var/www/htmlに設定して、以下のようにファイルを配置したとする。 /var/www/html/ | +-- index.html | +-- sub/ | +-- hoge.html この場合、ブラウザでhttp://<HTTPサーバアドレス>/index.htmlにアクセスすれば/var/www/html/index.htmlが配信されてレンダリングされて表示される。 http://<HTTPサーバアドレス>/sub/hoge.htmlにアクセスすれば/var/www/html/sub/hoge.htmlが配信される。 古のWebサイトは、こんな感じにコンテンツごとにHTMLファイルを書いてサーバに置いておいて、その間にリンクを張って辿れるようにすることで構成されていた。 まあ今も大体そんな感じだけど。 DHTML 1990年代後半、クライアントサイドのJavaScriptでHTMLドキュメントをいじって、多少の動的感・インタラクティブ感をだす技術は既に一応あって、DHTMLと呼ばれていた。 DHTMLの肝はJavaScriptのDOM APIだ。 このAPIでは、HTML文書が各要素(タグなど)をノードとするツリー構造(DOMツリー)で表され、任意の要素を検索して取得したり、属性などを書き換えたり、要素の追加・削除ができる。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> </head> <body> <div id="hogehoge"></div> <script type="text/javascript"> // idがhogehogeの要素の子要素として「<p>HOGEEEEEEE</p>」を追加。 document.getElementById("hogehoge").innerHTML = "<p>HOGEEEEEEE</p>" </script> </body> </html> しかし、このころのJavaScriptは、仕様・機能が貧弱だった上、ブラウザ間で挙動に差があったり、標準メソッドがブラウザ固有のメソッドで代替されていたりして開発体験が最悪だったためか、今日のようにWeb UIの中心的役割を果たすことはなく、補助的・装飾的機能の実装に使われることが多かったように思う。 アクセスした日付を表示したり、背景に雪を降らせたり、マウスカーソルを目玉に追いかけさせたり。 動的HTML生成 (プログラムでHTMLを書き出す) 静的サイトだと表現できることが非常に限られるので、クライアントからのリクエストの内容をサーバが解釈し、DBの情報やなんかをもとにサーバ側でHTMLドキュメントを動的に生成し、クライアントに返す、ということをするようになった。 原始的には、プログラム中で一連のHTMLドキュメントを出力する方法がとられた。 public void doGet( HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException { response.setContentType("text/html;"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println(" <head>"); out.println(" <title>Hoge</title>"); out.println(" </head>"); out.println(" <body>"); out.println(new java.util.Date()); out.println(" </body>"); out.println("</html>"); } 使われた技術は、CGI (Perl)とか、Java Servletとか。 Jakarta ECSなんてのもあった。 動的HTML生成 (HTMLにプログラムを埋め込む) プログラムでHTMLを書き出すことにより、かなり動的な感じにはなったが、書き出す処理を書くのがめんどくさすぎるし、読みにくい。 そのため、HTMLを主体にして、そのなかの動的な部分だけにプログラムを埋め込む方式が生まれた。 <%@ page contentType="text/html %> <html> <head> <title>Hoge</title> </head> <body> <% out.println(new java.util.Date()); %> </body> </html> HTMLドキュメントのひな型を作っておいて、その中にプログラムの処理結果を埋め込んでクライアントに返すため、テンプレートエンジンとか、テンプレートシステムとか呼ばれる。 該当する技術は、PHPとか、JSPとか、Velocityとか、eRubyとか。 MVCアーキテクチャ 2000年初頭、Struts (Struts1)というJavaのWebアプリケーションフレームワークが流行り、Controller (Java Servlet)がクライアントからリクエストを受け取り、Model (JavaBeans)がそれを処理して、View (JSP)がHTMLをレンダリングしてクライアントに返す、という、MVCアーキテクチャが流行った。 Strutsに続いてSpring MVC、Ruby on Rails、CakePHPといったフレームワークが出てきて、MVCアーキテクチャによる開発効率や開発体験は洗練されていった。 Ajax Strutsが全盛期の2005年ころ、JavaScriptで非同期にサーバからデータを取得し、それをもとにクライアントサイドでHTMLを動的に編集するような技術に、Ajaxという名前が付いた。 Ajaxは「Asynchronous JavaScript + XML」の略で、XMLHttpRequest (略してXHR)というJavaScriptのAPIで 、サーバにHTTPリクエストを送り、そのレスポンスを非同期に処理する技術。 レスポンスは、当時XMLが流行っていたので、その形式で送ることが想定されていたが、実際にはどんな形式でもいい。はず。 最近はJSONで送られることがほとんど。 JavaScriptはシングルスレッドで動くわけだけど、XMLHttpRequestはレスポンスを非同期に処理するため、リクエスト送信からレスポンス受信までの間、クライアントがスタックせずに済む。 また、通常のHTTPリクエストは、完全なHTMLドキュメントを受信して画面全体をレンダリングしなおす(i.e.
eyecatch
Sat, Jun 30, 2018

PackerでESXiにVMを自動構築

前回「Packer + Ansible on Windows 10でKubernetes 1.10のクラスタ on VirtualBoxを全自動構築」で、やったことをESXiでやっただけ。 書いたコードはGitHubに置いてある。 (adsbygoogle = window.adsbygoogle || []).push({}); 前回との違い VirtualBoxとESXiとで変えないといけない部分は、主にPackerのbuilderの定義。 前回はvirtualbox-isoだったけど、今回はvmware-isoを使う。 それに伴ってパラメータが結構違ってくる。 いっこトリッキーだったのが、cdrom_adapter_typeにideを明示的に指定しておかないと、CDロムドライブがSCSIになって、OSのインストールメディアのマウントか読み取り辺りでエラーになってしまったところ。 環境によっては指定しないでいいかも。 また、"vnc_disable_password": "true"をbuilderに指定しておかないと、Packerが「Error handshaking with VNC: no suitable auth schemes found. server supported: []byte{0x1}」というエラーを出す。 あとは、Nested Virtualizationでやった(下記)ので、すごく遅くて、色々タイムアウトを伸ばしたりしてやる必要があった。 ESXi環境 ESXi(というかVMware vSphere Hypervisor)は、現時点での最新の6.7を使用。 自前のWindows 10 HomeのノートPC上で動くVMware Player 12で作ったVMにESXiをインストールして環境を作った。 (因みにVirtualBoxにもインストールしてみたESXi上ではVM作成できなかった。VirtualBoxは今の時点でNested Virtualization未サポートで、サポートする予定もない模様。) Packerから操作するには、以下の設定をする必要がある。 静的IPアドレスを設定。Packerからの接続先に指定するので。 SSH有効化。PackerがSSHで接続するので。 因みにSSHクライアントでESXiにつなぐときは、チャレンジ/レスポンス認証になる。 GuestIPHack の有効化 ESXiにSSHでログインして「esxcli system settings advanced set -o /Net/GuestIPHack -i 1」 ファイアウォール設定でVNCポート(TCP5900番台)を開ける。 これをしないとPackerが「Starting HTTP server on port xxxx」でハングする。 けどこれが一筋縄ではいかない。この記事にあるように、/etc/vmware/firewall/service.xmlに設定を追加して「esxcli
eyecatch
Sun, Jun 17, 2018

Packer + Ansible on Windows 10でKubernetes 1.10のクラスタ on VirtualBoxを全自動構築

「Kubernetes 1.10のクラスタを全手動で構築するのをAnsibleで全自動化した」の続きで、さらにPackerを組み合わせて、VM作成まで自動化した話。 AnsibleをWindows(MSYS2)で動かした話でもある。 書いたPackerテンプレートはGitHubに置いた。 (adsbygoogle = window.adsbygoogle || []).push({}); Packerとは Packerは、様々な種類のVMを構築できるツール。 VagrantとかTerraformとかを開発しているHashiCorpが開発している。 テンプレートと呼ばれるビルド定義をJSONファイルに書いて、ビルド、プロビジョニング、ポストプロセスを実行して、アーティファクトと呼ばれるビルドの成果物を生成する。 ビルドのステップでは、VMを作成して、ハードウェア構成を設定したり、OSをインストールしたりする。 以下のような環境でVMを作れる。 VirtualBox Hyper-V VMware Workstation VMware vSphere Hypervisor Docker AWS EC2 プロビジョニングのステップでは、ビルドで作ったVMのOS上で指定された操作を実行し、ソフトウェアのインストールなどのセットアップ処理をする。 プロビジョニングには以下のようなツールを使える。 Shell PowerShell Ansible Chef Puppet プロビジョニングが終わるとアーティファクト(VMイメージファイルや、AWS EC2のAMI IDとか)が出力される。 ポストプロセスのステップでは、アーティファクトを入力として何らかの処理をして、最終的なアーティファクトを生成する。 ポストプロセスでは以下のような処理を実行できる。 アーカイブ VagrantBox生成 AWS EC2へのインポート Docker push PackerはGoで書かれていてビルド済みのバイナリが配布されているので、ダウンロードページから落として PATHの通ったところに置くだけでインストールできる。 今回はPacker 1.2.4のWindows版をインストールした。 Packerのテンプレート概要 Packerのテンプレートにはビルド、プロビジョニング、ポストプロセスの定義を複数かけて、複数環境のVM生成を1ファイルで定義できる。 テンプレートには以下のプロパティを書く。 builders: ビルドの定義のリスト。 description: テンプレートの説明。 min_packer_version: Packer の最低バージョン指定。 post-processors: ポストプロセスの定義のリスト。 provisioners: プロビジョニングの定義のリスト。 variables: テンプレート内で使う変数の定義。 _comment: コメントなどを書くためのプロパティ。実際はアンダースコアで始まればなんでもいい。JSON オブジェクトのルートレベルのみで使える。 これらのうち、必須なのはbuildersだけ。 一つのビルド定義には一つのcommunicatorを紐づける。 communicatorはビルド時にVMにつなぐための設定。 基本はSSHだけど、WinRMとかもある。 やりたいこと Windows 10上でPackerとAnsibleを動かして、VirtualBoxのVMをOracle Linux 7.4で作って、Kubernetes 1.10をインストールしたい。 Windowsでやりたいのは、単にベアメタルのLinuxの環境が無いからってのもあるし、いずれHyper-VのVMも作りたいからってのもある。 PackerはGo製で普通にWindowsで動くからいいけど、問題はAnsibleがPython製のくせにWindowsのPythonでは動かないこと。 AnsibleはWSLでは動くけど、VirtualBoxとかHyper-VはWindows上で動くから、PackerはWindows上で動かさないといけないはずで、そうなるとPackerから呼ばれるAnsibleもWindows上で動かさないといけない気がする。 のでWSLではだめな気がするし、そもそも実はWindows 7でも同じことやりたいのでWSLは無し。 要はWindows上でLinuxのPythonを使ってAnsibleを動かしたい。 ならばCygwinかMSYS2+MinGW-w64かGit Bashか。 ここにAnsibleはCygwinでもGit Bashでも動かすの難しいと書いてあって、逆にMSYS2でAnsible動かした記事はあったので、安直にMSYS2でやることにした。 MSYS2インストール MSYS2は、公式サイトからx86_64のインストーラ(msys2-x86_64-20180531.exe)をダウンロードして実行して普通にインストールしただけ。 Ansibleインストール MSYS2でのパッケージ管理にはpacmanを使う。 何はともあれPythonを入れる。3系でいい。 MSYS2 MSYSのショートカット(MSYS2 MinGW 64-bitじゃだめ)からターミナルを開いて、 $ pacman -S python で、Python 3.6.2が入った。 次に、Ansible(の依存)のビルドに必要なパッケージを入れる。 $ pacman -S gcc $ pacman -S make $ pacman -S libffi-devel $ pacman -S openssl-devel さらに、AnsibleからのSSH接続で(鍵ではなくて)パスワードを使う場合に必要なパッケージも入れる。 $ pacman -S sshpass sshpassの依存としてopensshも入った。 Ansibleはpipでインストールするんだけど、pacmanで入れたPython 3にはpipが付いてなかったので、別途入れる。 $ curl https://bootstrap.pypa.io/get-pip.py -LO $ python get-pip.py (ちょっと古いけどpipはpacman python3-pipでも入る。) で、ようやくAnsibleインストール。 $ export CFLAGS=-I/usr/lib/libffi-3.2.1/include $ pip install ansible 依存するPyNaClのビルドに20分くらいかかるのでゆっくり待つと、インストール完了するはず。 今回はAnsible 2.5.4がインストールされた。 AnsibleでJinja2のipaddrフィルターを使うために、もう一つPyPiパッケージ入れる。 $ pip install netaddr Packerテンプレート作成 ビルドは、OSインストールメディアのISOファイルを使うVirtualBoxのビルダであるvirtualbox-isoを指定して書いた。 OSのインストールは、Boot Commandをテンプレートに書くことで、インストーラのGUIを操作してやることもできるけど、RHEL系ならKickstartを使うのが楽。 Kickstartの定義ファイルは、普通に手動でOSをインストールした後、/root/anaconda-ks.cfgを採取して、必要に応じて編集して作る。 今回作ったのはこれで、このスレを参考に、Minimalインストールから、Wifiのファームウェアとか要らないのを抜いてる。 プロビジョニングは、「Kubernetes 1.10のクラスタを全手動で構築するのをAnsibleで全自動化した」ときのPlaybookを実行するやつを公式マニュアル見ながら適当に書いて、ポストプロセスも適当に書いて、できたのがこれ。 ansible_env_varsでANSIBLE_SSH_ARGSに-o ControlMaster=noを入れているのは、この問題に対応するため。 ビルド実行 MSYS2 MSYSのショートカットからターミナルを開いて、Packerを実行してみたら以下のエラー。 $ packer build -var-file=variables.json k8s_single_node_cluster-vb.json bash: packer: コマンドが見つかりません WindowsのPathが通ったところにPackerバイナリを置いておいてもMSYS2からは見えない。 のでpackerバイナリのフルパス(今回はC:\Users\kaitoy\Desktop\bin\にインストールしてたのでそのパス)を指定してやる。 $ /c/Users/kaitoy/Desktop/bin/packer.exe build -var-file=variables.json k8s_single_node_cluster-vb.json k8s-single-node-cluster output will be in this color.