<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4562980847459588265</id><updated>2024-09-01T12:18:38.642+09:00</updated><category term="javascript"/><category term="nodejs"/><category term="iOS"/><category term="objective-c"/><category term="Android"/><category term="PowerShell"/><category term="Windows"/><category term="C#"/><category term="Git"/><category term="PetaPoco"/><category term="aws"/><category term="babel"/><category term="browserify"/><category term="es2015"/><category term="knockoutjs"/><category term="koa"/><category term="serverless"/><category term="ASP.NET MVC"/><category term="ClockNewTab"/><category term="DbUtils"/><category term="DynamoDB"/><category term="Java"/><category term="Mastodon"/><category term="Oracle"/><category term="SQLServer"/><category term="Slack"/><category term="Windows 10"/><category term="Windows Update"/><category term="bash"/><category term="bootstrap"/><category term="chrome"/><category term="chrome ClockNewTab"/><category term="css"/><category term="electron"/><category term="excel"/><category term="html"/><category term="react"/><category term="shell script"/><category term="socket.io"/><category term="wsh"/><category term="アプリ開発"/><category term="雑記"/><title type='text'>調査メモ</title><subtitle type='html'>主にJavaScriptを用いた開発に関するメモなど</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>35</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-4467524167174026596</id><published>2017-04-24T11:09:00.001+09:00</published><updated>2017-04-24T11:09:45.796+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Mastodon"/><title type='text'>Mastodon (マストドン) とは何か</title><content type='html'>&lt;h2 id=&quot;mastodon-マストドン-とは&quot;&gt;Mastodon (マストドン) とは？&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://camo.githubusercontent.com/61d9a02e23c4281ebe954a4518af14c931a9493b/68747470733a2f2f6d6173746f646f6e2e736f6369616c2f6f6f70732e706e67&quot; alt=&quot;mastodon&quot; title=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/tootsuite/mastodon&quot;&gt;A GNU Social-compatible microblogging server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Mastodon&lt;/em&gt; とは &lt;em&gt;GNU social&lt;/em&gt; と互換性のある 短文投稿型SNS。 &lt;br&gt;
ネットワークは複数の &lt;em&gt;インスタンス&lt;/em&gt; から構成されており、インスタンス間は &lt;code&gt;OStatus&lt;/code&gt; を用いて通信を行う。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;投稿は &lt;em&gt;トゥート&lt;/em&gt; と呼ばれ、500文字の制限がある&lt;/li&gt;
&lt;li&gt;ライセンス: AGPL-3.0&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;gnu-social&quot;&gt;GNU social&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://ja.wikipedia.org/wiki/GNU_social&quot;&gt;GNU social - Wikipedia&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;PHPで書かれたミニブログサーバーのフリー・オープンソースソフトウェア&lt;/p&gt;
&lt;/blockquote&gt;



&lt;h3 id=&quot;ostatus&quot;&gt;OStatus&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://ja.wikipedia.org/wiki/OStatus&quot;&gt;OStatus - Wikipedia&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;OStatusは分散型ミニブログのためのオープン標準である。Atom、Activity Streams、PubSubHubbub、Salmon、Webfingerといったオープンプロトコルによって構成されており、異なるサイト間においてユーザー同士の投稿をほぼリアルタイムで届けることを可能にする。&lt;/p&gt;
&lt;/blockquote&gt;



&lt;h2 id=&quot;システム構成&quot;&gt;システム構成&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Webアプリ &lt;br&gt;
&lt;ul&gt;&lt;li&gt;サーバーサイド: Ruby on Rails&lt;/li&gt;
&lt;li&gt;クライアントサイド: React &amp;amp; Redux&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;ストリーミングサーバー: express &amp;amp; WebSocket (Node.js)&lt;/li&gt;
&lt;li&gt;Database &lt;br&gt;
&lt;ul&gt;&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/4467524167174026596/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2017/04/mastodon.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/4467524167174026596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/4467524167174026596'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2017/04/mastodon.html' title='Mastodon (マストドン) とは何か'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-3192252420648050272</id><published>2017-02-08T18:49:00.001+09:00</published><updated>2017-02-08T18:50:54.245+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Windows 10"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows Update"/><title type='text'>Windows Update のダウンロードが 0% のまま進まない場合の対処方法</title><content type='html'>&lt;p&gt;&lt;em&gt;以下の操作によって不具合等が発生したとしても、一切の責任を負いかねます。ご了承ください。&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;現象&quot;&gt;現象&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;いつまでたってもWindows Updateのダウンロードが 0% のまま進まない (今回は &lt;code&gt;KB2267602&lt;/code&gt; で発生しましたが、どの更新かはあまり関係ないように思われます)&lt;/li&gt;
&lt;li&gt;タスク マネージャー でディスクの使用率が 100% になっている&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;再起動等してもWindows Updateがキャンセルできず、サービスも停止できないという状況でした。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYqCQPGSuJIfnkDEJt5e88mumR3wSLZG1AHoKg_373AenbW8-FsymL8SSOfEdgOdIQfrB3DDW1Ji4b9YCPpFV21n04UWyTdbe6VFgCmnwXNjMIQWcy7f8wQgNn3hYzHvDcQbiNbj0imQ6x/s1600/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588+2017-02-08+15.27.49.png&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYqCQPGSuJIfnkDEJt5e88mumR3wSLZG1AHoKg_373AenbW8-FsymL8SSOfEdgOdIQfrB3DDW1Ji4b9YCPpFV21n04UWyTdbe6VFgCmnwXNjMIQWcy7f8wQgNn3hYzHvDcQbiNbj0imQ6x/s400/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588+2017-02-08+15.27.49.png&quot; width=&quot;400&quot; height=&quot;253&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Windows Defender&lt;/code&gt; が悪さしてるのかも？と思ってWindows Updateと一緒にキャプチャしていますが、結果的に冤罪でした。&lt;/p&gt;

&lt;h2 id=&quot;対処方法&quot;&gt;対処方法&lt;/h2&gt;

&lt;p&gt;今回紹介する手順を実施する前に、以下のページに記載されている対処方法を順に試した方が良いです。 &lt;br&gt;
&lt;a href=&quot;https://answers.microsoft.com/ja-jp/windows/forum/windows_10-update/windows-10-windows-update/a8a3a4cb-9d67-406e-8ae6-d25451c237d7&quot;&gt;Windows 10 - Windows Update に失敗する場合の対処法 - マイクロソフト コミュニティ&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;私が紹介する対処方法は最終手段だと思います。&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;Windows Updateでダウンロードするファイルは &lt;code&gt;%SystemRoot%\SoftwareDistribution&lt;/code&gt; というフォルダに保存されているのですが、こいつが破損しているんじゃないかなー、と考えました。 &lt;br&gt;
それであれば、 &lt;code&gt;SoftwareDistribution&lt;/code&gt; フォルダをサックリ削除してしまえば問題解決しそうです。&lt;/p&gt;

&lt;p&gt;ただ、&lt;code&gt;SoftwareDistribution&lt;/code&gt; フォルダは当然 Windows Update がアクセスしており、削除もリネームも出来ません。なので、Windows Updateが起動しないようにセーフモードで作業します。 &lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h3 id=&quot;1-セーフモードで起動する&quot;&gt;1. セーフモードで起動する&lt;/h3&gt;

&lt;p&gt;Windows Update がキャンセルできず、サービス管理からも停止できない (停止処理中のままになる) という状況なので、まずは &lt;code&gt;セーフモード&lt;/code&gt; で起動します。&lt;/p&gt;

&lt;p&gt;Windows XP なんかだと起動時に &lt;code&gt;F8&lt;/code&gt; キーを連打することでセーフモードで起動するのですが、Windows 10 ではこの方法も変更されています。 &lt;br&gt;
&lt;br&gt;&lt;br&gt;
こちらのサイトが詳しいですが、セーフモードで起動する方法はいくつかあります。 &lt;br&gt;
&lt;a href=&quot;http://www.japan-secure.com/entry/how-to-start-windows-10-in-safemode.html&quot;&gt;「Windows 10」をセーフモードで起動する方法について&lt;/a&gt; &lt;br&gt;
&lt;br&gt;&lt;br&gt;
私は &lt;code&gt;Windowsの設定&lt;/code&gt; から起動しました。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;スタートメニューの左アイコンの歯車をクリックすると、&lt;code&gt;Windowsの設定&lt;/code&gt; が起動します。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;更新とセキュリティ&lt;/code&gt; をクリック&lt;/li&gt;
&lt;li&gt;左メニューから &lt;code&gt;回復&lt;/code&gt; を選択&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PCの起動をカスタマイズする&lt;/code&gt; の &lt;code&gt;今すぐ再起動する&lt;/code&gt; というボタンをクリック&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;PCが再起動します。 &lt;br&gt;
起動すると、真っ青な画面に幾つかのパネルが表示されます。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;トラブルシューティング&lt;/code&gt; をクリック&lt;/li&gt;
&lt;li&gt;&lt;code&gt;詳細オプション&lt;/code&gt; をクリック&lt;/li&gt;
&lt;li&gt;&lt;code&gt;スタートアップ設定&lt;/code&gt; をクリック&lt;/li&gt;
&lt;li&gt;&lt;code&gt;再起動&lt;/code&gt; をクリック&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;再びPCが再起動します。 &lt;br&gt;
&lt;code&gt;スタートアップ設定&lt;/code&gt; という画面が表示されるので、&lt;code&gt;F4&lt;/code&gt; キーを押してセーフモードを有効にします。&lt;/p&gt;

&lt;p&gt;ログイン画面が表示されるので、パスワードを入力してログインします。 &lt;br&gt;
やっとこさ、どこか懐かしい四隅に &lt;code&gt;セーフモード&lt;/code&gt; と書かれたデスクトップが表示されます。&lt;/p&gt;

&lt;p&gt;Microsoftはセーフモードでログインさせたくないんだろうなー、というほど面倒くさい手順です。 &lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h3 id=&quot;2-softwaredistributionフォルダをリネームする&quot;&gt;2. SoftwareDistributionフォルダをリネームする&lt;/h3&gt;

&lt;p&gt;さて、苦労してセーフモードで起動することができましたので、諸悪の根源であろう &lt;code&gt;SoftwareDistribution&lt;/code&gt; フォルダを表示します。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;エクスプローラから &lt;code&gt;C:¥Windows&lt;/code&gt; にアクセスします。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SoftwareDistribution&lt;/code&gt; というフォルダを探します。無ければ Windows Update 云々以前の問題なので、おとなしくWindowsを再インストールしてください。&lt;/li&gt;
&lt;li&gt;サックリ削除しても良い気がしますが、何か問題があっても怖いので、フォルダをリネームしておきます。私は &lt;code&gt;SoftwareDistribution.bak&lt;/code&gt; としました。&lt;/li&gt;
&lt;li&gt;もうセーフモードに用はないので、普通に再起動します。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h3 id=&quot;3-再び-windows-update-を行う&quot;&gt;3. 再び Windows Update を行う&lt;/h3&gt;

&lt;p&gt;再起動して普通にログインし直したら、タスクマネージャーを立ち上げてしばらく様子を見ましょう。 &lt;br&gt;
起動直後の数分はディスク使用率 100% になるのは当たり前です。30分くらい放置して、ディスク使用率が落ち着くのを確認しましょう。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SoftwareDistribution&lt;/code&gt; フォルダは Windows Update を実施すると自動的に作成されるみたいです。 &lt;br&gt;
私の場合、先月のWindows Update もまともに動いていなかったようなので、改めて Windows Update を実施することにしました。 &lt;br&gt;
&lt;br&gt;&lt;br&gt;
さて、現象は解決しているのでしょうか？ &lt;br&gt;
この数時間の作業が灰燼に帰すのかどうか… &lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvh1PqLMN7TNk-AuPvCmyXqiUoAd0shfJTbcaHJ2eK5qlRNDaEs6Yy5M8zTy4XIDsOM_ij0VC3BVjjIrSqAgRwgyLmkm_0tHtk-Hq_Hd-S6BhqFK8HOi19wcOIi8t-5mztVIyGXN273v95/s1600/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588+2017-02-08+18.31.14.png&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvh1PqLMN7TNk-AuPvCmyXqiUoAd0shfJTbcaHJ2eK5qlRNDaEs6Yy5M8zTy4XIDsOM_ij0VC3BVjjIrSqAgRwgyLmkm_0tHtk-Hq_Hd-S6BhqFK8HOi19wcOIi8t-5mztVIyGXN273v95/s400/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588+2017-02-08+18.31.14.png&quot; width=&quot;400&quot; height=&quot;290&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ででーん！ &lt;br&gt;
無事、Windows Updateが完了しました！&lt;/p&gt;

&lt;p&gt;いやー、原因の調査などなどで丸一日かかってしまいました… &lt;br&gt;
この記事が誰かのお役に立てれば幸いです。&lt;/p&gt;

&lt;hr&gt;

&lt;h3 id=&quot;参考&quot;&gt;参考&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.atmarkit.co.jp/ait/articles/0710/19/news138.html&quot;&gt;Tech TIPS：Windows Update／Microsoft Updateのトラブルを解消する（SoftwareDistributionフォルダを修復する方法） - ＠IT&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/3192252420648050272/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2017/02/windows-update-0.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/3192252420648050272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/3192252420648050272'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2017/02/windows-update-0.html' title='Windows Update のダウンロードが 0% のまま進まない場合の対処方法'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYqCQPGSuJIfnkDEJt5e88mumR3wSLZG1AHoKg_373AenbW8-FsymL8SSOfEdgOdIQfrB3DDW1Ji4b9YCPpFV21n04UWyTdbe6VFgCmnwXNjMIQWcy7f8wQgNn3hYzHvDcQbiNbj0imQ6x/s72-c/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588+2017-02-08+15.27.49.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-6727855995392483885</id><published>2017-01-11T17:29:00.001+09:00</published><updated>2017-01-11T17:30:30.849+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="aws"/><category scheme="http://www.blogger.com/atom/ns#" term="DynamoDB"/><category scheme="http://www.blogger.com/atom/ns#" term="serverless"/><title type='text'>第1回 サーバレスアーキテクチャのお勉強 - DynamoDB</title><content type='html'>
&lt;p&gt;サガ スカーレット グレイス に手を出してしまいました… &lt;br&gt;
序盤は大剣＆斧のゴリ押し戦法で全滅しまくりでしたが、最近は小剣技の便利さに気付き、それなりに安定してきました。 &lt;br&gt;
そろそろ1周目が終わるかな？&lt;/p&gt;

&lt;p&gt;それはさておき、昨年から引き続き サーバレスアーキテクチャ なWebアプリケーションの作成手法について勉強していきたいと思います。&lt;/p&gt;

&lt;hr&gt;



&lt;h3 id=&quot;dynamodbについて&quot;&gt;DynamoDBについて&lt;/h3&gt;

&lt;p&gt;勉強会の開催情報は &lt;em&gt;&lt;a href=&quot;https://aws.amazon.com/jp/documentation/dynamodb/&quot;&gt;Amazon DynamoDB&lt;/a&gt;&lt;/em&gt; に格納していきます。&lt;/p&gt;

&lt;p&gt;DynamoDBはNoSQLデータベースなので、Oracleなどのリレーショナルデータベースとはテーブル設計の考え方が異なります。&lt;/p&gt;

&lt;p&gt;公式の開発者ガイド (&lt;a href=&quot;http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Introduction.html&quot;&gt;http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Introduction.html&lt;/a&gt;) に目を通しましたが、とても一度で理解できる内容ではないので、詳細はおいおい把握していこうと思います。&lt;/p&gt;

&lt;p&gt;ちなみに、以降にスクリーンショットを掲載していますが、2017年1月時点のものであり、将来的に変更になる可能性大です。&lt;/p&gt;

&lt;h3 id=&quot;テーブルの作成とデータの登録&quot;&gt;テーブルの作成とデータの登録&lt;/h3&gt;

&lt;p&gt;(1) AWSのコンソールにサインインし、&lt;code&gt;DynamoDB&lt;/code&gt; のリンクをクリックします。 &lt;br&gt;
&lt;code&gt;テーブルの作成&lt;/code&gt; というボタンがあるので、クリックします。&lt;/p&gt;

&lt;p&gt;(2) 以下のような画面が表示されます。&lt;/p&gt;

&lt;p&gt;今回、勉強会のイベント情報を管理したいので、 &lt;code&gt;Events&lt;/code&gt; というテーブル名とします。 &lt;br&gt;
キーは &lt;code&gt;EventId&lt;/code&gt; で良いでしょう。 &lt;br&gt;
で、実際の画面には開催日順にイベントが並んでいるのが普通だと思いますので、 ソートキーに &lt;code&gt;Date&lt;/code&gt; を指定しておきます。&lt;/p&gt;

&lt;p&gt;型は &lt;code&gt;文字列&lt;/code&gt;, &lt;code&gt;バイナリ&lt;/code&gt;, &lt;code&gt;数値&lt;/code&gt; の3種類しかないようなので、どちらも文字列にしておきます。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjb3tp4QiXALsuwHv9OKpatVFB3u8F1JrB25NuXWoE5WnbjoaozO_gfHNCzMPB10CocOgIIfnAmz_fa8UMWeVmB0e6jRnNx3oQI1air3oClXb9-S90QZReb43rCAfR24WK71SthnSAqMdIh/s1600/2017-01-11-1-create.png&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjb3tp4QiXALsuwHv9OKpatVFB3u8F1JrB25NuXWoE5WnbjoaozO_gfHNCzMPB10CocOgIIfnAmz_fa8UMWeVmB0e6jRnNx3oQI1air3oClXb9-S90QZReb43rCAfR24WK71SthnSAqMdIh/s320/2017-01-11-1-create.png&quot; width=&quot;320&quot; height=&quot;173&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(3) テーブルを作成すると一覧画面が表示されます。&lt;/p&gt;

&lt;p&gt;最初のうちは &lt;code&gt;状態&lt;/code&gt; が作成中のままですが、そのうち &lt;code&gt;有効&lt;/code&gt; となります。 &lt;br&gt;
リストから作成したテーブルを選択すると、右側に詳細情報が表示されます。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLlV6WIkuwWAnV4udrsPrwuP6TcfSq_lJbSeq6nG7jBtC68cA7KLHPK_oqws6w6vEll2rOAhQdWkxMkzfq-fHL_6EaLgZ2jaCA-udbATjYlpXuGvYSDQAOjzUGfGKcYmIffVirFqLYXXHT/s1600/2017-01-11--2-list.png&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLlV6WIkuwWAnV4udrsPrwuP6TcfSq_lJbSeq6nG7jBtC68cA7KLHPK_oqws6w6vEll2rOAhQdWkxMkzfq-fHL_6EaLgZ2jaCA-udbATjYlpXuGvYSDQAOjzUGfGKcYmIffVirFqLYXXHT/s320/2017-01-11--2-list.png&quot; width=&quot;320&quot; height=&quot;173&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(4) 詳細情報の &lt;code&gt;項目&lt;/code&gt; タブでデータの登録ができます。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;DynamoDB&lt;/code&gt; では、テーブル作成時に指定した &lt;code&gt;パーティションキー&lt;/code&gt; と &lt;code&gt;ソートキー&lt;/code&gt; 以外の項目は任意に追加できます。&lt;/p&gt;

&lt;p&gt;とりあえず、テストデータとして「ほげほげ」というデータを登録してみました。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht6RktxxeRus9TnPBlICeEj__c5mgaEYaXIhh79TKn5DgRJuv3-5tOqMpghPrG-3n8mHbcfXcjWO5tz-nTeHPIoThV-L1msUYwYdZzy6h9mvEFBDG4kyoG0HGd-1GKx8XKVzsaVnLTpWZW/s1600/2017-01-11-3-item.png&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht6RktxxeRus9TnPBlICeEj__c5mgaEYaXIhh79TKn5DgRJuv3-5tOqMpghPrG-3n8mHbcfXcjWO5tz-nTeHPIoThV-L1msUYwYdZzy6h9mvEFBDG4kyoG0HGd-1GKx8XKVzsaVnLTpWZW/s320/2017-01-11-3-item.png&quot; width=&quot;320&quot; height=&quot;173&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;DynamoDB のパフォーマンスを活かすためには パーティションキーやソートキーを工夫したり、RDBとはちょっと異なるテーブル設計にする必要があるみたいです。&lt;/p&gt;

&lt;p&gt;今回のWebアプリではタグを付けてイベントを分類するくらいは実装したいと思っていますが、タグ情報を格納するテーブルなどは後に作成しようと思います。 &lt;br&gt;
全文検索は Elasticsearch Service を使うのかな？&lt;/p&gt;

&lt;p&gt;ここまで書いといてアレですが、今回のような要件であれば &lt;em&gt;Amazon RDS&lt;/em&gt; を使用すべきだった気もしますが…まぁ、勉強なのでいいか。&lt;/p&gt;

&lt;p&gt;と、いうことで、次回はいよいよ &lt;em&gt;Lambda&lt;/em&gt; を触ってみたいと思います。&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/6727855995392483885/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2017/01/1-dynamodb.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/6727855995392483885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/6727855995392483885'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2017/01/1-dynamodb.html' title='第1回 サーバレスアーキテクチャのお勉強 - DynamoDB'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjb3tp4QiXALsuwHv9OKpatVFB3u8F1JrB25NuXWoE5WnbjoaozO_gfHNCzMPB10CocOgIIfnAmz_fa8UMWeVmB0e6jRnNx3oQI1air3oClXb9-S90QZReb43rCAfR24WK71SthnSAqMdIh/s72-c/2017-01-11-1-create.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-4256324057369548641</id><published>2016-12-26T19:01:00.001+09:00</published><updated>2016-12-26T19:02:33.232+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="aws"/><category scheme="http://www.blogger.com/atom/ns#" term="serverless"/><title type='text'>第0回 サーバレスアーキテクチャのお勉強 - システム概要</title><content type='html'>
&lt;p&gt;勉強会情報配信アプリの作成を通して、&lt;em&gt;サーバーレス アーキテクチャ&lt;/em&gt; のお勉強をしていきます。&lt;/p&gt;

&lt;h2 id=&quot;サーバーレス-アーキテクチャとは&quot;&gt;サーバーレス アーキテクチャとは？&lt;/h2&gt;

&lt;p&gt;物理サーバーや仮想サーバー(EC2など)、コンテナ(dockerなど) を使用しないシステム設計のこと …だと理解しています。&lt;/p&gt;

&lt;p&gt;具体的には、以下の2パターンの構成が見られます。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://firebase.google.com/?hl=ja&quot;&gt;Google Firebase&lt;/a&gt; や Parse.com(もうすぐサービス終了) といった、&lt;em&gt;BaaS (Backend as a Service)&lt;/em&gt; を組み込んだ構成&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html&quot;&gt;AWS Lambda&lt;/a&gt; や &lt;a href=&quot;https://azure.microsoft.com/ja-jp/services/functions/&quot;&gt;Azure Functions&lt;/a&gt; といった &lt;em&gt;FaaS (Function as a Service)&lt;/em&gt; を組み込んだ構成&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;今回の一連の記事において &lt;em&gt;サーバーレス アーキテクチャ&lt;/em&gt; といえば 2. の方を指すこととします。&lt;/p&gt;

&lt;h2 id=&quot;アプリの概要&quot;&gt;アプリの概要&lt;/h2&gt;

&lt;p&gt;毎月、フリーランスの仲間内でIT勉強会を開催しています。 &lt;br&gt;
その開催案内や勉強会で使用する資料の置き場所などの情報共有を行うWebアプリケーションの開発を行います。&lt;/p&gt;

&lt;h2 id=&quot;システム構成の検討&quot;&gt;システム構成の検討&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEho9vGYjhkYf2mve5LSMSTWvHu8HCcvRB-LWeZ5KQrN6loL9ATPM33iBsrcTMXdlYy6FZuUCQkW05_j-RQWAJ9odCq2ESHfLbz934lRQua4CMQ9sR4-SUGlm6uSt-rAs9p50jp0TslkK8CS/s640/IMG_0012.PNG&quot; alt=&quot;&quot; title=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;ざっくりですが、上記のようなシステム構成を考えました。 &lt;br&gt;
今回のアプリ開発はAWSの勉強も兼ねているので、ほとんどをAWSのマネージドサービスだけで構成します。&lt;/p&gt;

&lt;p&gt;次回は DynamoDB のテーブル設計をしていきたいと思います！&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/4256324057369548641/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2016/12/0.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/4256324057369548641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/4256324057369548641'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2016/12/0.html' title='第0回 サーバレスアーキテクチャのお勉強 - システム概要'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEho9vGYjhkYf2mve5LSMSTWvHu8HCcvRB-LWeZ5KQrN6loL9ATPM33iBsrcTMXdlYy6FZuUCQkW05_j-RQWAJ9odCq2ESHfLbz934lRQua4CMQ9sR4-SUGlm6uSt-rAs9p50jp0TslkK8CS/s72-c/IMG_0012.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-3093424998877508724</id><published>2016-07-22T13:58:00.000+09:00</published><updated>2016-07-22T13:58:59.740+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="雑記"/><title type='text'>温泉宿で開発合宿してきました</title><content type='html'>
&lt;p&gt;フリーランスの仲間を誘って、7/1～3 に温泉宿で開発合宿をしてきました。&lt;/p&gt;

&lt;p&gt;総勢14名、広間にPCを広げて作業です。&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJJcEU5VD66RspohVolOOJIvcGz84MpkmeUI4xutbx6oarW5uudZqCZK9QqjHWxVDn6Vw3U-LLtzmEVP8Xw1d2tb-JgZ5lhC8HLxKzxgjHDvqBDNz8gVAxbpHvWybFPxlz-1j9yZW7nlkR/s1600/dev-camp1.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJJcEU5VD66RspohVolOOJIvcGz84MpkmeUI4xutbx6oarW5uudZqCZK9QqjHWxVDn6Vw3U-LLtzmEVP8Xw1d2tb-JgZ5lhC8HLxKzxgjHDvqBDNz8gVAxbpHvWybFPxlz-1j9yZW7nlkR/s320/dev-camp1.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;特に目標などは設けませんでしたし 参加者の属性もバラバラなので、他のソフトウェア企業がやっているような開発合宿とは、すこし趣が違うのかもしれません。&lt;/p&gt;
&lt;p&gt;どちらかというと温泉宿に来て もくもく会を開催した、って感じでしょうか。&lt;/p&gt;

&lt;br&gt;

&lt;p&gt;言い出しっぺだったので、宿の選定や会計、タイムスケジュールの作成などやらせてもらいました。&lt;/p&gt;
&lt;p&gt;どれくらいの予算が良いのか いまいち掴めず、1日あたり1万円前後かなー、という感じで計画しましたが、ちょっとケチりすぎた感じがします。&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvEPp94Gmvvxb1BlcGSB8sTI7oaufC9LPQcULBE4Cnsrz6xVXgYQxkUkTkw8QRDyHN1Xh9xVss12XJYbE9VlP3hLXADJm7Z3HJd8thk1-cxZmx836BrkjW6Czmy0iCkRVAiGt4WHnVhX26/s1600/dev-camp2.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvEPp94Gmvvxb1BlcGSB8sTI7oaufC9LPQcULBE4Cnsrz6xVXgYQxkUkTkw8QRDyHN1Xh9xVss12XJYbE9VlP3hLXADJm7Z3HJd8thk1-cxZmx836BrkjW6Czmy0iCkRVAiGt4WHnVhX26/s320/dev-camp2.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;費用面を重視したために田園風景広がる自然豊かな場所にポツンとある宿になってしまいました。&lt;/p&gt;
&lt;p&gt;施設の清潔感がイマイチ (他の参加者からも言われた) でしたが、一泊二食付き 8,000円とかなので、こんなもんかなー、という感じです。次回は予算含めて見直したいですね。&lt;/p&gt;

&lt;p&gt;東京方面だと「開発合宿プラン」がある温泉宿なんかもチラホラあるみたいですが、関西で探すとなかなか難しいです。&lt;/p&gt;
&lt;p&gt;無線LAN完備で会議室と広いお風呂が 24時間利用可能、なんていう宿泊施設があると良いんですが。&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/3093424998877508724/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2016/07/blog-post.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/3093424998877508724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/3093424998877508724'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2016/07/blog-post.html' title='温泉宿で開発合宿してきました'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJJcEU5VD66RspohVolOOJIvcGz84MpkmeUI4xutbx6oarW5uudZqCZK9QqjHWxVDn6Vw3U-LLtzmEVP8Xw1d2tb-JgZ5lhC8HLxKzxgjHDvqBDNz8gVAxbpHvWybFPxlz-1j9yZW7nlkR/s72-c/dev-camp1.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-1565182865345119800</id><published>2016-02-09T20:37:00.001+09:00</published><updated>2016-02-09T20:38:45.171+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Slack"/><title type='text'>Slackとは？</title><content type='html'>&lt;p&gt;&lt;a href=&quot;https://slack.com/&quot;&gt;Slack&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SaaSのチャットアプリ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;



&lt;h2 id=&quot;利点&quot;&gt;利点&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;マルチプラットフォーム &lt;br&gt;
&lt;ul&gt;&lt;li&gt;Webアプリなので Windows, Mac, Linux で使用可能&lt;/li&gt;
&lt;li&gt;electronで作成されたデスクトップアプリもある&lt;/li&gt;
&lt;li&gt;Android, iOSアプリも当然ある&lt;/li&gt;
&lt;li&gt;複数端末同時ログイン可能&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;他のシステムとの連携機能が豊富 &lt;br&gt;
&lt;ul&gt;&lt;li&gt;GithubやGoogle Driveなど、様々なサービスと容易に連携可能&lt;/li&gt;
&lt;li&gt;無料枠では10システムまで連携可能&lt;/li&gt;
&lt;li&gt;WebhookやAPIを使用することで、デフォルトでは提供されていないシステム(社内システムなど)とも連携可能&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;markdown が投稿でき、ソースコードはシンタックスハイライトされる点が &lt;br&gt;
プログラマ同士の会話に非常に適している事が &lt;br&gt;
競合の他サービスと比較して、IT系企業で積極的に導入されている理由と考えられる。&lt;/p&gt;

&lt;p&gt;インターフェースが英語のため、プログラマ以外の職種には &lt;br&gt;
ChatWork や HipChat といったサービスの方が受け入れられやすい模様。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;



&lt;h2 id=&quot;無料の範囲&quot;&gt;無料の範囲&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href=&quot;https://get.slack.help/hc/en-us/articles/201723133-Billing-FAQ#can-i-use-slack-for-free&quot;&gt;https://get.slack.help/hc/en-us/articles/201723133-Billing-FAQ#can-i-use-slack-for-free&lt;/a&gt; &lt;br&gt;
  &lt;em&gt;Can I use Slack for free?&lt;/em&gt; &lt;br&gt;
  Yes, you can use Slack for free. You’ll only be able to browse and search your team’s 10,000 most recent messages, and you’ll be limited to 5GB of file storage and 10 apps or custom integrations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;直近 10,000件までの検索&lt;/li&gt;
&lt;li&gt;5GBのストレージ&lt;/li&gt;
&lt;li&gt;10個までのアプリ連携&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;



&lt;h2 id=&quot;価格&quot;&gt;価格&lt;/h2&gt;

&lt;p&gt;一人あたり一ヶ月 8ドル (アカウントがアクティブかどうかで日割り計算)&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;



&lt;h3 id=&quot;参考&quot;&gt;参考&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://slack.keihin.blue/&quot;&gt;Slackメモ&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Slack&lt;/em&gt; が広がっている背景のひとつとして、&lt;em&gt;ChatOps&lt;/em&gt; の流行の影響が考えられる。 &lt;br&gt;
&lt;em&gt;ChatOps&lt;/em&gt; とは文字通り、コンソールの代わりにチャットにて運用オペレーションを行う事である。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;



&lt;h3 id=&quot;chatops&quot;&gt;ChatOps&lt;/h3&gt;

&lt;p&gt;チャットチャンネルに常駐するボットにコマンドを投げて、システム運用を行う。 &lt;br&gt;
&lt;em&gt;Github&lt;/em&gt; が取り入れていることで有名。 &lt;br&gt;
&lt;a href=&quot;http://www.publickey1.jp/blog/16/github128chatopsredis.html&quot;&gt;PublicKey | GitHubが1月28日のサービス障害の詳細を公開。停電により内部のChatOpsシステムも落ちて初期対応が困難に。Redisクラスタの復旧に時間&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ChatOps&lt;/em&gt; のメリットとして、以下の様な点が考えられる。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;多数の人間が見ているチャットにコマンドを投げることにより、間違い等に早期に気づきやすい&lt;/li&gt;
&lt;li&gt;チャットのアーカイブ機能や検索機能によって、過去の操作履歴を追いかける事が可能&lt;/li&gt;
&lt;li&gt;わざわざ各サーバーにログインする必要がなくなる &lt;br&gt;
&lt;ul&gt;&lt;li&gt;昨今は仮想化・コンテナ化の結果、とんでもない台数のサーバーを管理する必要があるので、人間が「どのサーバーにログインする必要があるか」とか把握しきれない&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/1565182865345119800/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2016/02/slack.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/1565182865345119800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/1565182865345119800'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2016/02/slack.html' title='Slackとは？'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-886195911043379655</id><published>2016-02-08T19:50:00.001+09:00</published><updated>2016-02-08T19:50:10.338+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="electron"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><title type='text'>electron触ってみた</title><content type='html'>&lt;h2 id=&quot;electron触ってみた&quot;&gt;electron触ってみた&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://electron.atom.io/&quot;&gt;electron&lt;/a&gt; でローカルで動く&lt;a href=&quot;http://www.graphviz.org/Home.php&quot;&gt;Graphviz&lt;/a&gt; のビューア兼エディタを作った。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Kazunori-Kimura/electron-viz&quot;&gt;electron-viz&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;とりあえず動くけど、使い勝手とかが微妙なのでパッケージ化はしない。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h3 id=&quot;作ってみて感じたこと&quot;&gt;作ってみて感じたこと&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;クライアントサイドとサーバーサイドのjsが混じってて面白い&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ブラウザ側の処理か、Node.js側の処理か？ みたいなことを考えなくても作れてしまう。&lt;/p&gt;

&lt;p&gt;実際には &lt;code&gt;remote&lt;/code&gt; オブジェクトっていう &lt;code&gt;electron&lt;/code&gt; 特有のヤツがいて &lt;br&gt;
ブラウザのプロセスで動くのか、Node.js側のプロセスで動くのかを管理している。&lt;/p&gt;

&lt;p&gt;画面描画処理とそれ以外をきちんと区別することでアプリのパフォーマンスに影響するのかもしれないけど、あんまり意識しなくても動く。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;パフォーマンスに悪影響かもだけど、&lt;code&gt;knockout.js&lt;/code&gt; の処理の中で &lt;br&gt;
&lt;code&gt;Node.js&lt;/code&gt; のパッケージとか使えてしまう。&lt;/p&gt;

&lt;p&gt;今回、&lt;code&gt;node-glob&lt;/code&gt; の結果を &lt;code&gt;observableArray&lt;/code&gt; に突っ込んでリストを表示する、とかやってるけど普通に動いてびっくりした。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;バベらなくても es2015 で動いている&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;babel&lt;/code&gt; でわざわざ変換しなくても、結構 es2015 で動いている。 &lt;br&gt;
よく使う &lt;code&gt;class&lt;/code&gt; とか &lt;code&gt;Arrow function&lt;/code&gt; とかは問題なさげ。&lt;/p&gt;

&lt;p&gt;画面描画部分は &lt;code&gt;chrominium&lt;/code&gt; ベースなのかな？ (調べてない)&lt;/p&gt;

&lt;p&gt;CSS3の &lt;code&gt;flexbox&lt;/code&gt; なんかも問題なさげなので、ストレス無くて良い。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/886195911043379655/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2016/02/electron.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/886195911043379655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/886195911043379655'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2016/02/electron.html' title='electron触ってみた'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-8187786176976193948</id><published>2015-12-28T20:10:00.001+09:00</published><updated>2015-12-28T20:20:20.191+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="babel"/><category scheme="http://www.blogger.com/atom/ns#" term="browserify"/><category scheme="http://www.blogger.com/atom/ns#" term="es2015"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="knockoutjs"/><category scheme="http://www.blogger.com/atom/ns#" term="nodejs"/><title type='text'>browserifyでknockout.jsをトランスパイル</title><content type='html'>&lt;p&gt;&lt;a href=&quot;http://knockoutjs.com/&quot;&gt;knockout.js&lt;/a&gt; を &lt;em&gt;ES2015&lt;/em&gt; で書くための手順についてまとめる。&lt;/p&gt;

&lt;h2 id=&quot;環境&quot;&gt;環境&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;OS: Microsoft Windows [Version 6.1.7601]&lt;/li&gt;
&lt;li&gt;Node: v4.2.3&lt;/li&gt;
&lt;li&gt;npm: 2.14.7&lt;/li&gt;
&lt;/ul&gt;

&lt;br&gt;&lt;br&gt;

&lt;h2 id=&quot;モジュール-バージョン&quot;&gt;モジュール バージョン&lt;/h2&gt;

&lt;p&gt;各モジュールのバージョンは以下のとおり。&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-js hljs &quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;&quot;devDependencies&quot;&lt;/span&gt;: {
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;babel-preset-es2015&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^6.3.13&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;babelify&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^7.2.0&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;browserify&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^12.0.1&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;knockout&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^3.4.0&quot;&lt;/span&gt;
}&lt;/code&gt;&lt;/pre&gt;


&lt;br&gt;&lt;br&gt;

&lt;h2 id=&quot;プロジェクトフォルダの作成&quot;&gt;プロジェクトフォルダの作成&lt;/h2&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs lasso&quot;&gt;mkdir knockout&lt;span class=&quot;hljs-attribute&quot;&gt;-es6&lt;/span&gt;&lt;span class=&quot;hljs-attribute&quot;&gt;-project&lt;/span&gt;
cd knockout&lt;span class=&quot;hljs-attribute&quot;&gt;-es6&lt;/span&gt;&lt;span class=&quot;hljs-attribute&quot;&gt;-project&lt;/span&gt;
mkdir src
mkdir dist&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;src&lt;/code&gt; フォルダに変換前のソースコードを作成する &lt;br&gt;
&lt;ul&gt;&lt;li&gt;&lt;code&gt;src/index.js&lt;/code&gt; がメインファイルであると想定する&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dist&lt;/code&gt; フォルダにトランスパイルされた jsファイルが保存される &lt;br&gt;
&lt;ul&gt;&lt;li&gt;&lt;code&gt;dist/bundle.js&lt;/code&gt; という名前で生成&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;br&gt;&lt;br&gt;

&lt;h2 id=&quot;packagejson-の作成&quot;&gt;package.json の作成&lt;/h2&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs vala&quot;&gt;npm init
&lt;span class=&quot;hljs-preprocessor&quot;&gt;# 適当に入力&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;


&lt;br&gt;&lt;br&gt;

&lt;h2 id=&quot;browserify-のインストール&quot;&gt;browserify のインストール&lt;/h2&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs brainfuck&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hljs-literal&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;hljs-literal&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;dev&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;browserify&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href=&quot;http://browserify.org/&quot;&gt;browserify&lt;/a&gt; は
クライアントサイドのJavaScriptでモジュールシステムを実現するツール。&lt;/p&gt;


&lt;br&gt;&lt;br&gt;

&lt;h2 id=&quot;babelify-のインストール&quot;&gt;babelify のインストール&lt;/h2&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs lasso&quot;&gt;npm install &lt;span class=&quot;hljs-subst&quot;&gt;--&lt;/span&gt;save&lt;span class=&quot;hljs-attribute&quot;&gt;-dev&lt;/span&gt; babelify babel&lt;span class=&quot;hljs-attribute&quot;&gt;-preset&lt;/span&gt;&lt;span class=&quot;hljs-attribute&quot;&gt;-es2015&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/babel/babelify&quot;&gt;babelify&lt;/a&gt; は &lt;em&gt;browserify&lt;/em&gt; が javascript を処理する際に &lt;a href=&quot;http://babeljs.io/&quot;&gt;babel&lt;/a&gt; によって &lt;br&gt;
 ES2015で書かれたソースを (browserが理解できる) ES5 に変換するツール。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;babel-preset-es2015&lt;/code&gt; は
ES2015 の変換機能。&lt;/p&gt;

&lt;p&gt;&lt;em&gt;babel&lt;/em&gt; 本体から変換機能を切り離すことで、利用者は使用する機能を
取捨選択することが可能になっている。&lt;/p&gt;

&lt;p&gt;&lt;em&gt;browserify&lt;/em&gt; と組み合わせず、&lt;em&gt;babel&lt;/em&gt; のコマンドラインツールで
変換することも可能。 &lt;br&gt;
今回は、後述する &lt;code&gt;npm run build&lt;/code&gt; コマンド一回で 
トランスパイルが完了するようにしたかったため、このような構成とした。&lt;/p&gt;

&lt;br&gt;&lt;br&gt;

&lt;h2 id=&quot;knockoutのインストール&quot;&gt;knockoutのインストール&lt;/h2&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs brainfuck&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hljs-literal&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;hljs-literal&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;dev&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;knockout&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;browserify&lt;/em&gt; によってトランスパイルした際に
&lt;code&gt;dist/bundle.js&lt;/code&gt; に &lt;em&gt;knockout.js&lt;/em&gt; 本体も含まれるようにする。&lt;/p&gt;

&lt;br&gt;&lt;br&gt;

&lt;h2 id=&quot;packagejson-の修正&quot;&gt;package.json の修正&lt;/h2&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-js hljs &quot;&gt;{
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;knockout-es6-project&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;version&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;1.0.0&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;description&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;knockout es6 sample&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;main&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;index.js&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;scripts&quot;&lt;/span&gt;: {
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;test&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;echo \&quot;Error: no test specified\&quot; &amp;amp;&amp;amp; exit 1&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;build&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;browserify src/index.js -o dist/bundle.js&quot;&lt;/span&gt;
  },
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;keywords&quot;&lt;/span&gt;: [
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;knockout.js&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;babel&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;es2015&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;browserify&quot;&lt;/span&gt;
  ],
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;author&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;Kazunori Kimura &amp;lt;kazunori.kimura.js@gmail.com&amp;gt;&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;license&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;MIT&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;devDependencies&quot;&lt;/span&gt;: {
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;babel-preset-es2015&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^6.3.13&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;babelify&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^7.2.0&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;browserify&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^12.0.1&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;knockout&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^3.4.0&quot;&lt;/span&gt;
  },
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;browserify&quot;&lt;/span&gt;: {
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;transform&quot;&lt;/span&gt;: [
      [
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;babelify&quot;&lt;/span&gt;,
        {
          &lt;span class=&quot;hljs-string&quot;&gt;&quot;presets&quot;&lt;/span&gt;: [
            &lt;span class=&quot;hljs-string&quot;&gt;&quot;es2015&quot;&lt;/span&gt;
          ]
        }
      ]
    ]
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;修正点は以下の2つ。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;scripts&lt;/em&gt; に &lt;em&gt;build&lt;/em&gt; の指定を追加。 &lt;br&gt;
&lt;ul&gt;&lt;li&gt;&lt;em&gt;browserify&lt;/em&gt; を使用して &lt;em&gt;index.js&lt;/em&gt; を &lt;em&gt;bundle.js&lt;/em&gt; に変換する&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;browserify&lt;/em&gt; を追加し、&lt;em&gt;presets&lt;/em&gt; を指定 &lt;br&gt;
&lt;ul&gt;&lt;li&gt;&lt;code&gt;.babelrc&lt;/code&gt; というファイルを作成して &lt;em&gt;presets&lt;/em&gt; の指定を行うことも可能だが、&lt;code&gt;package.json&lt;/code&gt; に集約するほうがシンプルであると判断した&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;br&gt;&lt;br&gt;

&lt;h2 id=&quot;サンプルコード&quot;&gt;サンプルコード&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;src/index.js&lt;/code&gt;&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-js hljs &quot;&gt;import ko from &lt;span class=&quot;hljs-string&quot;&gt;&quot;knockout&quot;&lt;/span&gt;;
import MyViewModel from &lt;span class=&quot;hljs-string&quot;&gt;&quot;./MyViewModel&quot;&lt;/span&gt;;

ko.components.register(&lt;span class=&quot;hljs-string&quot;&gt;&quot;MyComponent&quot;&lt;/span&gt;,
{
  viewModel: MyViewModel,
  template: `&amp;lt;div&amp;gt;
  &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;text&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;value: text, valueUpdate: &#39;afterkeydown&#39;&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  length: &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;text: text().length&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;`
});

ko.applyBindings();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;src/MyViewModel.js&lt;/code&gt;&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-js hljs &quot;&gt;import ko from &lt;span class=&quot;hljs-string&quot;&gt;&quot;knockout&quot;&lt;/span&gt;;

export &lt;span class=&quot;hljs-keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;class&lt;/span&gt; MyViewModel {
  constructor(){
    &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.text = ko.observable(&lt;span class=&quot;hljs-string&quot;&gt;&quot;&quot;&lt;/span&gt;);
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;dist/index.html&lt;/code&gt;&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-html hljs &quot;&gt;&lt;span class=&quot;hljs-doctype&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;lang&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;ja&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;head&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;charset&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;UTF-8&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;title&lt;/span&gt;&amp;gt;&lt;/span&gt;Document&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;title&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;head&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;body&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;component: &#39;MyComponent&#39;&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;bundle.js&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;javascript&quot;&gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;script&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;body&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;html&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;br&gt;&lt;br&gt;

&lt;h2 id=&quot;トランスパイルの実行&quot;&gt;トランスパイルの実行&lt;/h2&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs lasso&quot;&gt;$ npm run build

&lt;span class=&quot;hljs-subst&quot;&gt;&amp;gt;&lt;/span&gt; knockout&lt;span class=&quot;hljs-attribute&quot;&gt;-es6&lt;/span&gt;&lt;span class=&quot;hljs-attribute&quot;&gt;-project&lt;/span&gt;@&lt;span class=&quot;hljs-number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.0&lt;/span&gt; build C:&lt;span class=&quot;hljs-subst&quot;&gt;\&lt;/span&gt;Repository&lt;span class=&quot;hljs-subst&quot;&gt;\&lt;/span&gt;knockout&lt;span class=&quot;hljs-attribute&quot;&gt;-es6&lt;/span&gt;&lt;span class=&quot;hljs-attribute&quot;&gt;-project&lt;/span&gt;
&lt;span class=&quot;hljs-subst&quot;&gt;&amp;gt;&lt;/span&gt; browserify src/index&lt;span class=&quot;hljs-built_in&quot;&gt;.&lt;/span&gt;js &lt;span class=&quot;hljs-attribute&quot;&gt;-o&lt;/span&gt; dist/bundle&lt;span class=&quot;hljs-built_in&quot;&gt;.&lt;/span&gt;js
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;dist/bundle.js&lt;/code&gt; が生成されていることを確認する。&lt;/p&gt;

&lt;br&gt;&lt;br&gt;

&lt;h2 id=&quot;参考&quot;&gt;参考&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://lorefnon.me/2015/08/24/smarter-knockout-applications-with-es-next.html&quot;&gt;Smarter knockout applications with ES6/7&lt;/a&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/8187786176976193948/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/12/browserifyknockoutjs.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/8187786176976193948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/8187786176976193948'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/12/browserifyknockoutjs.html' title='browserifyでknockout.jsをトランスパイル'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-8145741217447632012</id><published>2015-12-17T19:58:00.001+09:00</published><updated>2015-12-17T20:00:47.799+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="babel"/><category scheme="http://www.blogger.com/atom/ns#" term="browserify"/><category scheme="http://www.blogger.com/atom/ns#" term="es2015"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="nodejs"/><category scheme="http://www.blogger.com/atom/ns#" term="react"/><title type='text'>browserifyでReact(JSX)をトランスパイル</title><content type='html'>&lt;h3 id=&quot;概要&quot;&gt;概要&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;React (JSX) と ES2015 をトランスパイルする環境を構築する&lt;/li&gt;
&lt;li&gt;できるだけシンプルな構成を目指す&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h3 id=&quot;環境&quot;&gt;環境&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;OS: Microsoft Windows [Version 6.1.7601]&lt;/li&gt;
&lt;li&gt;Node: v4.2.3&lt;/li&gt;
&lt;li&gt;npm: 2.14.7&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h3 id=&quot;モジュール-バージョン&quot;&gt;モジュール バージョン&lt;/h3&gt;

&lt;p&gt;各モジュールのバージョンは以下のとおり。&lt;/p&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-js hljs &quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;&quot;devDependencies&quot;&lt;/span&gt;: {
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;babel-preset-es2015&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^6.3.13&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;babel-preset-react&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^6.3.13&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;babelify&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^7.2.0&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;browserify&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^12.0.1&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;react&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^0.14.3&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;react-dom&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^0.14.3&quot;&lt;/span&gt;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;バージョンによって手順が変わる可能性が高いため
最新の情報を参照する必要がある。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h3 id=&quot;プロジェクトフォルダの作成&quot;&gt;プロジェクトフォルダの作成&lt;/h3&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs lasso&quot;&gt;mkdir react&lt;span class=&quot;hljs-attribute&quot;&gt;-babel&lt;/span&gt;&lt;span class=&quot;hljs-attribute&quot;&gt;-sample&lt;/span&gt;
cd react&lt;span class=&quot;hljs-attribute&quot;&gt;-babel&lt;/span&gt;&lt;span class=&quot;hljs-attribute&quot;&gt;-sample&lt;/span&gt;
mkdir src
mkdir dist&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;src&lt;/code&gt; フォルダに変換前のソースコードを作成する &lt;br&gt;
&lt;ul&gt;&lt;li&gt;&lt;code&gt;src/index.js&lt;/code&gt; がメインファイルであると想定する&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dist&lt;/code&gt; フォルダにトランスパイルされた jsファイルが保存される &lt;br&gt;
&lt;ul&gt;&lt;li&gt;&lt;code&gt;dist/bundle.js&lt;/code&gt; という名前で生成&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h3 id=&quot;packagejson-の作成&quot;&gt;package.json の作成&lt;/h3&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs vala&quot;&gt;npm init
&lt;span class=&quot;hljs-preprocessor&quot;&gt;# 適当に入力&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h3 id=&quot;browserify-のインストール&quot;&gt;browserify のインストール&lt;/h3&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs brainfuck&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hljs-literal&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;hljs-literal&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;dev&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;browserify&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href=&quot;http://browserify.org/&quot;&gt;browserify&lt;/a&gt; は
クライアントサイドのJavaScriptでモジュールシステムを実現するツール。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h3 id=&quot;babelify-のインストール&quot;&gt;babelify のインストール&lt;/h3&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs lasso&quot;&gt;npm install &lt;span class=&quot;hljs-subst&quot;&gt;--&lt;/span&gt;save&lt;span class=&quot;hljs-attribute&quot;&gt;-dev&lt;/span&gt; babelify babel&lt;span class=&quot;hljs-attribute&quot;&gt;-preset&lt;/span&gt;&lt;span class=&quot;hljs-attribute&quot;&gt;-es2015&lt;/span&gt; babel&lt;span class=&quot;hljs-attribute&quot;&gt;-preset&lt;/span&gt;&lt;span class=&quot;hljs-attribute&quot;&gt;-react&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/babel/babelify&quot;&gt;babelify&lt;/a&gt; は &lt;em&gt;browserify&lt;/em&gt; が javascript を処理する際に &lt;a href=&quot;http://babeljs.io/&quot;&gt;babel&lt;/a&gt; によって
 ES2015やReact(JSX)で書かれたソースを (browserが理解できる) ES5 に変換するツール。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;babel-preset-es2015&lt;/code&gt;, &lt;code&gt;babel-preset-react&lt;/code&gt; は
それぞれ ES2015, React(JSX) の変換機能。&lt;/p&gt;

&lt;p&gt;&lt;em&gt;babel&lt;/em&gt; 本体から変換機能を切り離すことで、利用者は使用する機能を
取捨選択することが可能になっている。&lt;/p&gt;

&lt;p&gt;&lt;em&gt;browserify&lt;/em&gt; と組み合わせず、&lt;em&gt;babel&lt;/em&gt; のコマンドラインツールで
変換することも可能。 &lt;br&gt;
今回は、後述する &lt;code&gt;npm run build&lt;/code&gt; コマンド一回で
トランスパイルが完了するようにしたかったため、このような構成とした。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h3 id=&quot;reactのインストール&quot;&gt;Reactのインストール&lt;/h3&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs lasso&quot;&gt;npm install &lt;span class=&quot;hljs-subst&quot;&gt;--&lt;/span&gt;save&lt;span class=&quot;hljs-attribute&quot;&gt;-dev&lt;/span&gt; react react&lt;span class=&quot;hljs-attribute&quot;&gt;-dom&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;browserify&lt;/em&gt; によってトランスパイルした際に
&lt;code&gt;dist/bundle.js&lt;/code&gt; に &lt;em&gt;React.js&lt;/em&gt; 本体も含まれるようになる。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h3 id=&quot;packagejson-の修正&quot;&gt;package.json の修正&lt;/h3&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-js hljs &quot;&gt;{
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;react-babel-sample&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;version&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;1.0.0&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;description&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;react project sample&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;main&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;index.js&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;scripts&quot;&lt;/span&gt;: {
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;test&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;echo \&quot;Error: no test specified\&quot; &amp;amp;&amp;amp; exit 1&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;build&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;browserify src/index.js -o dist/bundle.js&quot;&lt;/span&gt;
  },
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;keywords&quot;&lt;/span&gt;: [
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;react&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;babel&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;browserify&quot;&lt;/span&gt;
  ],
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;author&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;Kazunori Kimura &amp;lt;kazunori.kimura.js@gmail.com&amp;gt;&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;license&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;MIT&quot;&lt;/span&gt;,
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;devDependencies&quot;&lt;/span&gt;: {
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;babel-preset-es2015&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^6.3.13&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;babel-preset-react&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^6.3.13&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;babelify&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^7.2.0&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;browserify&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^12.0.1&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;react&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^0.14.3&quot;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;react-dom&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;^0.14.3&quot;&lt;/span&gt;
  },
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;browserify&quot;&lt;/span&gt;: {
    &lt;span class=&quot;hljs-string&quot;&gt;&quot;transform&quot;&lt;/span&gt;: [
      [
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;babelify&quot;&lt;/span&gt;,
        {
          &lt;span class=&quot;hljs-string&quot;&gt;&quot;presets&quot;&lt;/span&gt;: [
            &lt;span class=&quot;hljs-string&quot;&gt;&quot;es2015&quot;&lt;/span&gt;,
            &lt;span class=&quot;hljs-string&quot;&gt;&quot;react&quot;&lt;/span&gt;
          ]
        }
      ]
    ]
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;修正点は以下の2つ。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;scripts&lt;/em&gt; に &lt;em&gt;build&lt;/em&gt; の指定を追加。 &lt;br&gt;
&lt;ul&gt;&lt;li&gt;&lt;em&gt;browserify&lt;/em&gt; を使用して &lt;em&gt;index.js&lt;/em&gt; を &lt;em&gt;bundle.js&lt;/em&gt; に変換する&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;browserify&lt;/em&gt; を追加し、&lt;em&gt;presets&lt;/em&gt; を指定 &lt;br&gt;
&lt;ul&gt;&lt;li&gt;&lt;code&gt;.babelrc&lt;/code&gt; というファイルを作成して &lt;em&gt;presets&lt;/em&gt; の指定を行うことも可能だが、&lt;code&gt;package.json&lt;/code&gt; に集約するほうがシンプル&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h3 id=&quot;サンプルコード&quot;&gt;サンプルコード&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;src/index.js&lt;/code&gt;&lt;/p&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-js hljs &quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;// index.js&lt;/span&gt;
import React from &lt;span class=&quot;hljs-string&quot;&gt;&quot;react&quot;&lt;/span&gt;;
import ReactDOM from &lt;span class=&quot;hljs-string&quot;&gt;&quot;react-dom&quot;&lt;/span&gt;;
import MainComponent from &lt;span class=&quot;hljs-string&quot;&gt;&quot;./MainComponent&quot;&lt;/span&gt;;

ReactDOM.render(
  &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;MainComponent&lt;/span&gt; /&amp;gt;&lt;/span&gt;,
  document.getElementById(&quot;content&quot;)
);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;src/MainComponent.js&lt;/code&gt;&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-js hljs &quot;&gt;import React from &lt;span class=&quot;hljs-string&quot;&gt;&quot;react&quot;&lt;/span&gt;;
import MySubComponent from &lt;span class=&quot;hljs-string&quot;&gt;&quot;./SubComponent&quot;&lt;/span&gt;;

export &lt;span class=&quot;hljs-keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;class&lt;/span&gt; MainComponent extends React.Component {
  render(){
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt;(
      &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;className&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;main-component&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;Main&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;MySubComponent&lt;/span&gt; /&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
    );
  }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;src/SubComponent.js&lt;/code&gt;&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-js hljs &quot;&gt;import React from &lt;span class=&quot;hljs-string&quot;&gt;&quot;react&quot;&lt;/span&gt;;

export &lt;span class=&quot;hljs-keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;class&lt;/span&gt; MySubComponent extends React.Component {
  render() {
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt;(
      &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;className&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;sub-component&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
        sub component.
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
    );
  }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;dist/index.html&lt;/code&gt;&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-js hljs &quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;lang&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;ja&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;head&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;charset&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;UTF-8&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;title&lt;/span&gt;&amp;gt;&lt;/span&gt;Document&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;title&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;head&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;body&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;content&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;bundle.js&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;javascript&quot;&gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;script&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;body&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;html&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h3 id=&quot;トランスパイルの実行&quot;&gt;トランスパイルの実行&lt;/h3&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs lasso&quot;&gt;$ npm run build

&lt;span class=&quot;hljs-subst&quot;&gt;&amp;gt;&lt;/span&gt; react&lt;span class=&quot;hljs-attribute&quot;&gt;-babel&lt;/span&gt;&lt;span class=&quot;hljs-attribute&quot;&gt;-sample&lt;/span&gt;@&lt;span class=&quot;hljs-number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.0&lt;/span&gt; build C:&lt;span class=&quot;hljs-subst&quot;&gt;\&lt;/span&gt;Repository&lt;span class=&quot;hljs-subst&quot;&gt;\&lt;/span&gt;react&lt;span class=&quot;hljs-attribute&quot;&gt;-babel&lt;/span&gt;&lt;span class=&quot;hljs-attribute&quot;&gt;-sample&lt;/span&gt;
&lt;span class=&quot;hljs-subst&quot;&gt;&amp;gt;&lt;/span&gt; browserify src/index&lt;span class=&quot;hljs-built_in&quot;&gt;.&lt;/span&gt;js &lt;span class=&quot;hljs-attribute&quot;&gt;-o&lt;/span&gt; dist/bundle&lt;span class=&quot;hljs-built_in&quot;&gt;.&lt;/span&gt;js
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;dist/bundle.js&lt;/code&gt; が生成されていることを確認する。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;h3 id=&quot;更新履歴&quot;&gt;更新履歴&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;2015-12-15: 新規作成&lt;/li&gt;
&lt;li&gt;2015-12-16: サンプルコード追加&lt;/li&gt;
&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/8145741217447632012/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/12/browserifyreactjsx.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/8145741217447632012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/8145741217447632012'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/12/browserifyreactjsx.html' title='browserifyでReact(JSX)をトランスパイル'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-4070571642704436614</id><published>2015-11-13T12:12:00.001+09:00</published><updated>2015-11-13T12:12:08.742+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="knockoutjs"/><category scheme="http://www.blogger.com/atom/ns#" term="koa"/><category scheme="http://www.blogger.com/atom/ns#" term="nodejs"/><category scheme="http://www.blogger.com/atom/ns#" term="socket.io"/><title type='text'>koa と socket.io を使用したチャットアプリ</title><content type='html'>&lt;p&gt;koa と socket.io を使用したチャットアプリを作成する。&lt;/p&gt;

&lt;p&gt;&lt;em&gt;koa&lt;/em&gt; に &lt;em&gt;socket.io&lt;/em&gt; を組み込んだ、&lt;a href=&quot;https://github.com/koajs/koa.io&quot;&gt;koa.io&lt;/a&gt; を使用する。&lt;/p&gt;

&lt;p&gt;(&lt;em&gt;koa.io&lt;/em&gt; は現在開発中だが、とりあえず動作に支障はなかった。 &lt;br&gt;
ただ、 &lt;em&gt;socket.io&lt;/em&gt; をそのまま組み込んでもコード量はそれほど変わらないと思われる。)&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;



&lt;h2 id=&quot;koaioのインストール&quot;&gt;koa.ioのインストール&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;koa.io&lt;/em&gt; は &lt;em&gt;koa&lt;/em&gt; を含んでいるので、先に &lt;em&gt;koa&lt;/em&gt; をアンインストールしてからインストールする。&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-sh hljs brainfuck&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;uninstall&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hljs-literal&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;save&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;koa&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hljs-literal&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;save&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;koa&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;io&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;



&lt;h2 id=&quot;サーバー側の処理&quot;&gt;サーバー側の処理&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;app.js&lt;/code&gt;&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-js hljs &quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;// app.js&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; app = &lt;span class=&quot;hljs-built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&#39;koa.io&#39;&lt;/span&gt;)();
&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; route = &lt;span class=&quot;hljs-built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&#39;koa-route&#39;&lt;/span&gt;);
&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; serve = &lt;span class=&quot;hljs-built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&#39;koa-static&#39;&lt;/span&gt;);
&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; views = &lt;span class=&quot;hljs-built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&#39;koa-views&#39;&lt;/span&gt;);
&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; moment = &lt;span class=&quot;hljs-built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&#39;moment&#39;&lt;/span&gt;);

&lt;span class=&quot;hljs-comment&quot;&gt;// ectをテンプレートエンジンとして指定&lt;/span&gt;
app.use(views(__dirname + &lt;span class=&quot;hljs-string&quot;&gt;&#39;/views&#39;&lt;/span&gt;, {
  map: {
    html: &lt;span class=&quot;hljs-string&quot;&gt;&#39;ect&#39;&lt;/span&gt;
  }
}));

&lt;span class=&quot;hljs-comment&quot;&gt;// -- routing --&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;// GET /chat&lt;/span&gt;
app.use(route.get(&lt;span class=&quot;hljs-string&quot;&gt;&#39;/chat&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; *&lt;span class=&quot;hljs-title&quot;&gt;chat&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;{&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.render(&lt;span class=&quot;hljs-string&quot;&gt;&#39;chat.ect&#39;&lt;/span&gt;, {
    title: &lt;span class=&quot;hljs-string&quot;&gt;&#39;CHAT&#39;&lt;/span&gt;,
    version: &lt;span class=&quot;hljs-string&quot;&gt;&#39;1.0.0&#39;&lt;/span&gt;
  });
}));

&lt;span class=&quot;hljs-comment&quot;&gt;// static files&lt;/span&gt;
app.use(serve(__dirname + &lt;span class=&quot;hljs-string&quot;&gt;&#39;/public&#39;&lt;/span&gt;));

&lt;span class=&quot;hljs-comment&quot;&gt;// -- WebSocket --&lt;/span&gt;

app.io.use(&lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;* &lt;span class=&quot;hljs-params&quot;&gt;(next)&lt;/span&gt;{&lt;/span&gt;
  console.log(&lt;span class=&quot;hljs-string&quot;&gt;&#39;[connect]&#39;&lt;/span&gt;);
  &lt;span class=&quot;hljs-keyword&quot;&gt;yield&lt;/span&gt;* next;
  console.log(&lt;span class=&quot;hljs-string&quot;&gt;&#39;[disconnect]&#39;&lt;/span&gt;);
  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.username) {
    &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.broadcast.emit(&lt;span class=&quot;hljs-string&quot;&gt;&#39;message&#39;&lt;/span&gt;, { message: &lt;span class=&quot;hljs-string&quot;&gt;&#39;logout: &#39;&lt;/span&gt; + &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.username});
    &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.username = &lt;span class=&quot;hljs-string&quot;&gt;&#39;&#39;&lt;/span&gt;;
  }
});

app.io.route(&lt;span class=&quot;hljs-string&quot;&gt;&#39;login&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;*&lt;span class=&quot;hljs-params&quot;&gt;(next, args)&lt;/span&gt;{&lt;/span&gt;
  console.log(&lt;span class=&quot;hljs-string&quot;&gt;&#39;[login] &#39;&lt;/span&gt; + &lt;span class=&quot;hljs-built_in&quot;&gt;JSON&lt;/span&gt;.stringify(args));
  &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.username = args.username;
  &lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; msg = { message: &lt;span class=&quot;hljs-string&quot;&gt;&#39;login: &#39;&lt;/span&gt; + &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.username };
  &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.broadcast.emit(&lt;span class=&quot;hljs-string&quot;&gt;&#39;message&#39;&lt;/span&gt;, msg);
  &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.emit(&lt;span class=&quot;hljs-string&quot;&gt;&#39;message&#39;&lt;/span&gt;, msg);
});

app.io.route(&lt;span class=&quot;hljs-string&quot;&gt;&#39;logout&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;*&lt;span class=&quot;hljs-params&quot;&gt;(next)&lt;/span&gt;{&lt;/span&gt;
  console.log(&lt;span class=&quot;hljs-string&quot;&gt;&#39;[logout] &#39;&lt;/span&gt; + &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.username);
  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.username) {
    &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.broadcast.emit(&lt;span class=&quot;hljs-string&quot;&gt;&#39;message&#39;&lt;/span&gt;, { message: &lt;span class=&quot;hljs-string&quot;&gt;&#39;logout: &#39;&lt;/span&gt; + &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.username});
    &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.username = &lt;span class=&quot;hljs-string&quot;&gt;&#39;&#39;&lt;/span&gt;;
  }
});

app.io.route(&lt;span class=&quot;hljs-string&quot;&gt;&#39;message&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;*&lt;span class=&quot;hljs-params&quot;&gt;(next, args)&lt;/span&gt;{&lt;/span&gt;
  console.log(&lt;span class=&quot;hljs-string&quot;&gt;&#39;[message] &#39;&lt;/span&gt; + &lt;span class=&quot;hljs-built_in&quot;&gt;JSON&lt;/span&gt;.stringify(args));
  &lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; msg = {
    date: moment().format(&lt;span class=&quot;hljs-string&quot;&gt;&#39;hh:mm:ss&#39;&lt;/span&gt;),
    username: &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.username,
    message: args.message
  };
  &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.broadcast.emit(&lt;span class=&quot;hljs-string&quot;&gt;&#39;message&#39;&lt;/span&gt;, msg);
  &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.emit(&lt;span class=&quot;hljs-string&quot;&gt;&#39;message&#39;&lt;/span&gt;, msg);
});

app.listen(&lt;span class=&quot;hljs-number&quot;&gt;3000&lt;/span&gt;);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;app.io&lt;/code&gt; の箇所が &lt;em&gt;koa.io&lt;/em&gt; が &lt;em&gt;socket.io&lt;/em&gt; をラッピングしている部分。 &lt;br&gt;
非常に簡単に &lt;em&gt;WebSocket&lt;/em&gt; のサーバーサイド処理が書ける。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;



&lt;h2 id=&quot;クライアント側の処理&quot;&gt;クライアント側の処理&lt;/h2&gt;

&lt;p&gt;今回はViewを &lt;em&gt;knockoutjs&lt;/em&gt; で作成する。&lt;/p&gt;

&lt;p&gt;(ちなみに… &lt;em&gt;knockoutjs&lt;/em&gt; の Model や ViewModel を ES2015 で書けないか試行錯誤してみたが、肝心の &lt;code&gt;ko.observable&lt;/code&gt; の変数が上手く認識できず、断念。)&lt;/p&gt;



&lt;h3 id=&quot;html-ect&quot;&gt;html (ECT)&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;views/layout.ect&lt;/code&gt;&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-html hljs &quot;&gt;&lt;span class=&quot;hljs-doctype&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;lang&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;ja&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;head&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;charset&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;UTF-8&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;http-equiv&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;X-UA-Compatible&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;IE=edge&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;viewport&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;width=device-width, initial-scale=1&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;title&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;vbscript&quot;&gt;&amp;lt;%- @title %&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;title&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;link&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;rel&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;stylesheet&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;/honoka/css/bootstrap.min.css&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;link&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;rel&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;stylesheet&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;/css/style.css&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-comment&quot;&gt;&amp;lt;!--[if lt IE 9]&amp;gt;
    &amp;lt;script src=&quot;https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;https://oss.maxcdn.com/respond/1.4.2/respond.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;![endif]--&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;head&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;body&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;nav&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;navbar navbar-default navbar-fixed-top&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;container&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;navbar-header&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;navbar-toggle collapsed&quot;&lt;/span&gt;
          &lt;span class=&quot;hljs-attribute&quot;&gt;data-toggle&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;collapse&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;data-target&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;#navbar&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;aria-expanded&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;false&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;aria-controls&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;navbar&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;sr-only&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;Toggle navigation&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;icon-bar&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;icon-bar&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;icon-bar&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;navbar-brand&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;/chat&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;vbscript&quot;&gt;&amp;lt;%- @title %&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;a&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;navbar&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;collapse navbar-collapse&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;ul&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;nav navbar-nav&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;li&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;/version&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;About&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;a&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;li&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;ul&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;&amp;lt;!--/.nav-collapse --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;nav&lt;/span&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;container&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;vbscript&quot;&gt;&amp;lt;% content %&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;footer&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;footer&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;container&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;vbscript&quot;&gt;&amp;lt;% include &lt;span class=&quot;hljs-comment&quot;&gt;&#39;views/footer.ect&#39; %&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;footer&lt;/span&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;/jquery/jquery.min.js&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;javascript&quot;&gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;script&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;/socketio/socket.io.js&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;javascript&quot;&gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;script&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;/knockout/knockout.js&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;javascript&quot;&gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;script&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;/js/client.js&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;javascript&quot;&gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;script&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;body&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;html&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;socket.io.js&lt;/em&gt;, &lt;em&gt;knockout.js&lt;/em&gt; を追加。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;chat.ect&lt;/code&gt;&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-html hljs &quot;&gt;&lt;span class=&quot;vbscript&quot;&gt;&amp;lt;% extend &lt;span class=&quot;hljs-comment&quot;&gt;&#39;views/layout.ect&#39; %&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;row&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;visible: !user.isLogin()&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;form&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;form-inline&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;login-form&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;form-group&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;for&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;username&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;お名前&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;label&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;text&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;form-control&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;username&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;placeholder&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;User Name&quot;&lt;/span&gt;
        &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;value: user.username&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;btn btn-primary&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;login&quot;&lt;/span&gt;
      &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;click: user.login&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;ログイン&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;form&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;row&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;visible: user.isLogin()&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;form&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;form-inline&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;login-form&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;form-group&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;form-control-static&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;ようこそ &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;text: user.username&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt;&amp;gt;&lt;/span&gt; さん！&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;btn btn-xs btn-default&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;logout&quot;&lt;/span&gt;
      &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;click: user.logout&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;ログアウト&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;form&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;row&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;visible: user.isLogin()&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;form&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;form-inline&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;chat-form&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;form-group&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;for&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;message&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;メッセージ&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;label&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;text&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;form-control&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;message&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;placeholder&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;Message&quot;&lt;/span&gt;
        &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;value: message.message&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;btn btn-primary&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;send&quot;&lt;/span&gt;
      &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;click: send&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;送 信&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;form&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;row&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;visible: user.isLogin()&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;panel panel-default&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;panel-heading&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;チャットルーム&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;panel-body&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;response&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;row&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;foreach: messageList&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;col-xs-1&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;text: date&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;col-xs-1&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;text: username&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;col-xs-10&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;data-bind&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;text: message&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上から順に、&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ログインフォーム (ログイン後に隠す)&lt;/li&gt;
&lt;li&gt;ログアウトボタン (ログイン後に表示)&lt;/li&gt;
&lt;li&gt;メッセージフォーム (ログイン後に表示)&lt;/li&gt;
&lt;li&gt;チャット欄 (ログイン後に表示)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;knockoutjs&lt;/em&gt; のデータバインドでデータをやり取りするように実装。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;



&lt;h3 id=&quot;js&quot;&gt;js&lt;/h3&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-js hljs &quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;// client.js&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;// user model&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; User = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;(chat)&lt;/span&gt;{&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; self = &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;;

  self.username = ko.observable(&lt;span class=&quot;hljs-string&quot;&gt;&#39;&#39;&lt;/span&gt;);
  self.isLogin = ko.observable(&lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;);

  self.login = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;{&lt;/span&gt;
    &lt;span class=&quot;hljs-comment&quot;&gt;// 接続処理&lt;/span&gt;
    self.isLogin(&lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;);
    chat.login(self.username());
  };

  self.logout = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;{&lt;/span&gt;
    &lt;span class=&quot;hljs-comment&quot;&gt;// 切断処理&lt;/span&gt;
    chat.logout(self.username());
    self.isLogin(&lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;);
    self.username(&lt;span class=&quot;hljs-string&quot;&gt;&#39;&#39;&lt;/span&gt;);
  };
};

&lt;span class=&quot;hljs-comment&quot;&gt;// message model&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; Message = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;(prm, chat)&lt;/span&gt;{&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; self = &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;;

  &lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; opts = {
    date: &lt;span class=&quot;hljs-string&quot;&gt;&#39;&#39;&lt;/span&gt;,
    username: &lt;span class=&quot;hljs-string&quot;&gt;&#39;&#39;&lt;/span&gt;,
    message: &lt;span class=&quot;hljs-string&quot;&gt;&#39;&#39;&lt;/span&gt;
  };
  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (!prm) {
    prm = {};
  }
  $.extend(opts, prm);

  self.date = opts.date;
  self.username = opts.username;
  self.message = ko.observable(opts.message);

  self.send = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;{&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (chat) {
      &lt;span class=&quot;hljs-comment&quot;&gt;// メッセージ送信&lt;/span&gt;
      chat.send({ message: self.message() });
      self.message(&lt;span class=&quot;hljs-string&quot;&gt;&#39;&#39;&lt;/span&gt;);
    }
  };
};

&lt;span class=&quot;hljs-comment&quot;&gt;// Chat class&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; Chat = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;Chat&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;(messageList)&lt;/span&gt;{&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; self = &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;;
  &lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; socket = io.connect();

  socket.on(&lt;span class=&quot;hljs-string&quot;&gt;&#39;connect&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;{&lt;/span&gt;
    console.log(&lt;span class=&quot;hljs-string&quot;&gt;&#39;connect&#39;&lt;/span&gt;);
  });
  socket.on(&lt;span class=&quot;hljs-string&quot;&gt;&#39;disconnect&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;{&lt;/span&gt;
    console.log(&lt;span class=&quot;hljs-string&quot;&gt;&#39;disconnect&#39;&lt;/span&gt;);
  });

  self.login = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;(username)&lt;/span&gt;{&lt;/span&gt;
    socket.emit(&lt;span class=&quot;hljs-string&quot;&gt;&#39;login&#39;&lt;/span&gt;, { username: username });

    socket.on(&lt;span class=&quot;hljs-string&quot;&gt;&#39;message&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;(data)&lt;/span&gt;{&lt;/span&gt;
      console.log(data);
      messageList.push(&lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; Message({
        date: data.date,
        username: data.username,
        message: data.message
      }));
    });
  };

  self.send = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;(msg)&lt;/span&gt; {&lt;/span&gt;
    socket.emit(&lt;span class=&quot;hljs-string&quot;&gt;&#39;message&#39;&lt;/span&gt;, msg);
  };

  self.logout = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;(username)&lt;/span&gt; {&lt;/span&gt;
    socket.emit(&lt;span class=&quot;hljs-string&quot;&gt;&#39;logout&#39;&lt;/span&gt;, { username: username });
    socket.off(&lt;span class=&quot;hljs-string&quot;&gt;&#39;message&#39;&lt;/span&gt;);
  };
};

&lt;span class=&quot;hljs-comment&quot;&gt;// application view model&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; AppViewModel = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;AppViewModel&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;{&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; self = &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;;
  &lt;span class=&quot;hljs-comment&quot;&gt;// 受信したメッセージ&lt;/span&gt;
  self.messageList = ko.observableArray([]);
  &lt;span class=&quot;hljs-comment&quot;&gt;// socket.ioのラッパー&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; chat = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; Chat(self.messageList);
  &lt;span class=&quot;hljs-comment&quot;&gt;// models&lt;/span&gt;
  self.user = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; User(chat);
  self.message = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; Message({}, chat);

  &lt;span class=&quot;hljs-comment&quot;&gt;// 送信&lt;/span&gt;
  self.send = &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;{&lt;/span&gt;
    self.message.send();
  };
};


$(&lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;{&lt;/span&gt;
  ko.applyBindings(&lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; AppViewModel());
});&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;socket.io&lt;/em&gt; の処理は &lt;em&gt;Chat&lt;/em&gt; クラスに押し込んだが、結果としてコードがゴチャゴチャになった気がする…&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/4070571642704436614/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/11/koa-socketio.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/4070571642704436614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/4070571642704436614'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/11/koa-socketio.html' title='koa と socket.io を使用したチャットアプリ'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-6353193659430635911</id><published>2015-11-11T17:45:00.001+09:00</published><updated>2015-11-11T18:04:44.772+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="koa"/><category scheme="http://www.blogger.com/atom/ns#" term="nodejs"/><title type='text'>koa + ECT による Webアプリケーション</title><content type='html'>&lt;h2 id=&quot;koa&quot;&gt;koa&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;koa&lt;/em&gt; は Expressのチームによって設計された、新しいWebフレームワーク。&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ES2015&lt;/em&gt; の &lt;code&gt;generator/yield&lt;/code&gt; を使用することにより、Expressでよくある callback地獄を回避し、簡潔にコーディング出来るようになった。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://koajs.com/&quot;&gt;koa&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;

&lt;h2 id=&quot;ect&quot;&gt;ECT&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;ECT&lt;/em&gt; は &lt;a href=&quot;http://www.embeddedjs.com/&quot;&gt;ejs&lt;/a&gt; や &lt;a href=&quot;http://jade-lang.com/&quot;&gt;jade&lt;/a&gt; のような templateエンジン。 &lt;br&gt;
非常に早い事が特徴。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://ectjs.com/&quot;&gt;ECT&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h2 id=&quot;必要なモジュールのインストール&quot;&gt;必要なモジュールのインストール&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;npm&lt;/em&gt; で必要なモジュールをインストール。&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs ruby&quot;&gt;&lt;span class=&quot;hljs-variable&quot;&gt;$ &lt;/span&gt;mkdir web-app
&lt;span class=&quot;hljs-variable&quot;&gt;$ &lt;/span&gt;cd web-app
&lt;span class=&quot;hljs-variable&quot;&gt;$ &lt;/span&gt;npm init
  &lt;span class=&quot;hljs-comment&quot;&gt;# Enter連打&lt;/span&gt;
&lt;span class=&quot;hljs-variable&quot;&gt;$ &lt;/span&gt;npm install --save koa koa-route koa-static koa-views ect&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;koa-route : ルーティングを行う、&lt;em&gt;koa&lt;/em&gt; のミドルウェア。&lt;/li&gt;
&lt;li&gt;koa-static: 静的ファイルを公開するための &lt;em&gt;koa&lt;/em&gt; のミドルウェア。&lt;/li&gt;
&lt;li&gt;koa-views : テンプレートエンジンを使用してレスポンスを組み立てるための &lt;em&gt;koa&lt;/em&gt; のミドルウェア&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;



&lt;h2 id=&quot;フォルダ構成&quot;&gt;フォルダ構成&lt;/h2&gt;

&lt;p&gt;以下の様なフォルダ構成を作成。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{PROJECT_ROOT}
  |- public
  |    |- css
  |    |- js
  |    `- images
  `- views
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;



&lt;h2 id=&quot;appjsの作成&quot;&gt;app.jsの作成&lt;/h2&gt;

&lt;p&gt;プロジェクトのルート直下に &lt;em&gt;app.js&lt;/em&gt; というファイルを作成し、 &lt;br&gt;
そこにコーディングしていく。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app.js&lt;/code&gt;&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-js hljs &quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;// app.js&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; app = &lt;span class=&quot;hljs-built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&#39;koa&#39;&lt;/span&gt;)();
&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; route = &lt;span class=&quot;hljs-built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&#39;koa-route&#39;&lt;/span&gt;);
&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; serve = &lt;span class=&quot;hljs-built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&#39;koa-static&#39;&lt;/span&gt;);
&lt;span class=&quot;hljs-keyword&quot;&gt;var&lt;/span&gt; views = &lt;span class=&quot;hljs-built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&#39;koa-views&#39;&lt;/span&gt;);

&lt;span class=&quot;hljs-comment&quot;&gt;// ectをテンプレートエンジンとして指定&lt;/span&gt;
app.use(views(__dirname + &lt;span class=&quot;hljs-string&quot;&gt;&#39;/views&#39;&lt;/span&gt;, {
  map: {
    html: &lt;span class=&quot;hljs-string&quot;&gt;&#39;ect&#39;&lt;/span&gt;
  }
}));

&lt;span class=&quot;hljs-comment&quot;&gt;// GET /test&lt;/span&gt;
app.use(route.get(&lt;span class=&quot;hljs-string&quot;&gt;&#39;/test&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; *&lt;span class=&quot;hljs-title&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;{&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.render(&lt;span class=&quot;hljs-string&quot;&gt;&#39;test.ect&#39;&lt;/span&gt;, {
    title: &lt;span class=&quot;hljs-string&quot;&gt;&#39;TEST APPLICATION&#39;&lt;/span&gt;,
    version: &lt;span class=&quot;hljs-string&quot;&gt;&#39;1.0.0&#39;&lt;/span&gt;
  });
}));

&lt;span class=&quot;hljs-comment&quot;&gt;// static files&lt;/span&gt;
app.use(serve(__dirname + &lt;span class=&quot;hljs-string&quot;&gt;&#39;/public&#39;&lt;/span&gt;));

app.listen(&lt;span class=&quot;hljs-number&quot;&gt;3000&lt;/span&gt;);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;http://localhost:3000/test&lt;/code&gt; にリクエストがあった場合に &lt;code&gt;views/test.ect&lt;/code&gt; に &lt;code&gt;title&lt;/code&gt; と &lt;code&gt;version&lt;/code&gt; を埋め込んで、レスポンスとして返す。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h2 id=&quot;viewの作成&quot;&gt;Viewの作成&lt;/h2&gt;

&lt;p&gt;viewファイルを作成していく。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;views/layout.ect&lt;/code&gt;&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-html hljs &quot;&gt;&lt;span class=&quot;hljs-doctype&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;lang&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;ja&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;head&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;charset&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;UTF-8&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;http-equiv&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;X-UA-Compatible&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;IE=edge&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;viewport&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;width=device-width, initial-scale=1&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;title&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;vbscript&quot;&gt;&amp;lt;%- @title %&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;title&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;link&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;rel&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;stylesheet&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;/css/bootstrap.min.css&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;link&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;rel&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;stylesheet&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;/css/style.css&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-comment&quot;&gt;&amp;lt;!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-comment&quot;&gt;&amp;lt;!-- WARNING: Respond.js doesn&#39;t work if you view the page via file:// --&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-comment&quot;&gt;&amp;lt;!--[if lt IE 9]&amp;gt;
    &amp;lt;script src=&quot;https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;https://oss.maxcdn.com/respond/1.4.2/respond.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;![endif]--&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;head&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;body&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;nav&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;navbar navbar-default navbar-fixed-top&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;container&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;navbar-header&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;navbar-toggle collapsed&quot;&lt;/span&gt;
          &lt;span class=&quot;hljs-attribute&quot;&gt;data-toggle&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;collapse&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;data-target&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;#navbar&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;aria-expanded&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;false&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;aria-controls&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;navbar&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;sr-only&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;Toggle navigation&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;icon-bar&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;icon-bar&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;icon-bar&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;span&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;navbar-brand&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;#&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;Project name&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;a&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;nav&lt;/span&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;container&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;vbscript&quot;&gt;&amp;lt;% content %&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;footer&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;footer&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;container&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;vbscript&quot;&gt;&amp;lt;% include &lt;span class=&quot;hljs-comment&quot;&gt;&#39;views/footer.ect&#39; %&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;footer&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;body&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;html&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;ECT&lt;/em&gt; 単体で使用した場合、&lt;code&gt;include&lt;/code&gt; では ファイルが同一階層にあれば &lt;code&gt;&amp;lt;% include &#39;footer&#39; %&amp;gt;&lt;/code&gt; で取り込めるが、 &lt;em&gt;koa&lt;/em&gt; のテンプレートエンジンとして使用した場合、ファイルの指定を &lt;em&gt;app.jsからの相対パス&lt;/em&gt; とし、ファイルの拡張子を指定しないとViewファイルが見つけられず、例外が発生する。&lt;/p&gt;

&lt;p&gt;&lt;em&gt;public&lt;/em&gt; に配置された &lt;em&gt;css&lt;/em&gt; などは、&lt;code&gt;koa-static&lt;/code&gt; によって &lt;code&gt;/ (ルート)&lt;/code&gt; に公開されている。 &lt;br&gt;
&lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; や &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; のパス指定は &lt;code&gt;/css/{file_name}&lt;/code&gt;, &lt;code&gt;/js/{file_name}&lt;/code&gt; とルートからのパスを指定する。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;views/footer.ect&lt;/code&gt;&lt;/p&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-html hljs &quot;&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;text-muted&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &amp;amp;copy; &lt;span class=&quot;vbscript&quot;&gt;&amp;lt;%- (&lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;Date&lt;/span&gt;()).getFullYear() %&amp;gt;&lt;/span&gt; -
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;https://kazunori-kimura.github.io/&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;target&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;_blank&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;Kazunori.Kimura&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;a&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;コピーライトの年表示に JavaScript を埋め込んでいる。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;views/test.ect&lt;/code&gt;&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot;language-html hljs &quot;&gt;&lt;span class=&quot;vbscript&quot;&gt;&amp;lt;% extend &lt;span class=&quot;hljs-comment&quot;&gt;&#39;views/layout.ect&#39; %&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hljs-attribute&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hljs-value&quot;&gt;&quot;jumbotron&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;vbscript&quot;&gt;&amp;lt;%- @title %&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-title&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;version info: &lt;span class=&quot;vbscript&quot;&gt;&amp;lt;%- @version %&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-title&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;app.js&lt;/code&gt; でViewに渡されたパラメータをHTMLに埋め込む。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;layout.ect&lt;/code&gt; での &lt;code&gt;include&lt;/code&gt; と同様に、 &lt;code&gt;extend&lt;/code&gt; でレイアウトファイルを指定する場合も &lt;em&gt;app.jsからの相対パス&lt;/em&gt; とする必要があることに注意。&lt;/p&gt;

&lt;h2 id=&quot;実行&quot;&gt;実行&lt;/h2&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs ruby&quot;&gt;&lt;span class=&quot;hljs-variable&quot;&gt;$ &lt;/span&gt;node app.js&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;nodejs&lt;/em&gt; のバージョンが 0.12.x 未満の場合は &lt;code&gt;--harmony&lt;/code&gt; オプションが必要になる。&lt;/p&gt;

&lt;p&gt;アプリを実行したら、ブラウザで &lt;code&gt;http://localhost:3000/test&lt;/code&gt; にアクセスし画面が表示されることを確認する。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/6353193659430635911/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/11/koa-ect-web_11.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/6353193659430635911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/6353193659430635911'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/11/koa-ect-web_11.html' title='koa + ECT による Webアプリケーション'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-2346304161398157539</id><published>2015-07-14T18:24:00.001+09:00</published><updated>2015-07-14T18:24:59.144+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="objective-c"/><title type='text'>ナビゲーションバーの高さを変更する</title><content type='html'>&lt;p&gt;&lt;br&gt;
Storyboardで作成した画面のナビゲーションバーの高さを変更したくて色々調査したので、結果をまとめておきます。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;まず、storyboardで画面遷移を定義します。 &lt;br&gt;
当然 Navigation Controllerを配置します。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NavigationBarのカスタムクラスを作成します。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;-sizeThatFits:&lt;/code&gt; でNavigationBarのサイズを返します。 &lt;br&gt;
defaultのheightは 44.0 です。&lt;/p&gt;

&lt;p&gt;また、高さを拡大すると、すべてのsubviewの上部分がその分だけ空いてしまうので、NavigationBarの中央に来るよう位置を変更します。&lt;/p&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs objectivec&quot;&gt;&lt;span class=&quot;hljs-class&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;@implementation&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;XXCustomNavigationBar&lt;/span&gt;&lt;/span&gt;

- (&lt;span class=&quot;hljs-built_in&quot;&gt;CGSize&lt;/span&gt;)sizeThatFits:(&lt;span class=&quot;hljs-built_in&quot;&gt;CGSize&lt;/span&gt;)size
{
  &lt;span class=&quot;hljs-built_in&quot;&gt;CGSize&lt;/span&gt; barSize = [&lt;span class=&quot;hljs-keyword&quot;&gt;super&lt;/span&gt; sizeThatFits:size];
  barSize&lt;span class=&quot;hljs-variable&quot;&gt;.height&lt;/span&gt; += &lt;span class=&quot;hljs-number&quot;&gt;20.0&lt;/span&gt;f; &lt;span class=&quot;hljs-comment&quot;&gt;// 高さを変更&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; barSize;
}

- (&lt;span class=&quot;hljs-keyword&quot;&gt;void&lt;/span&gt;)layoutSubviews
{
  [&lt;span class=&quot;hljs-keyword&quot;&gt;super&lt;/span&gt; layoutSubviews];

  &lt;span class=&quot;hljs-comment&quot;&gt;// vertically center&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;float&lt;/span&gt; centerY = &lt;span class=&quot;hljs-keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;hljs-variable&quot;&gt;.bounds&lt;/span&gt;&lt;span class=&quot;hljs-variable&quot;&gt;.size&lt;/span&gt;&lt;span class=&quot;hljs-variable&quot;&gt;.height&lt;/span&gt; / &lt;span class=&quot;hljs-number&quot;&gt;2.0&lt;/span&gt;f;
  &lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;hljs-built_in&quot;&gt;UIView&lt;/span&gt; *view in &lt;span class=&quot;hljs-keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;hljs-variable&quot;&gt;.subviews&lt;/span&gt;) {
    &lt;span class=&quot;hljs-comment&quot;&gt;// 位置変更&lt;/span&gt;
    &lt;span class=&quot;hljs-built_in&quot;&gt;CGPoint&lt;/span&gt; center = view&lt;span class=&quot;hljs-variable&quot;&gt;.center&lt;/span&gt;;
    center&lt;span class=&quot;hljs-variable&quot;&gt;.y&lt;/span&gt; = centerY;
    view&lt;span class=&quot;hljs-variable&quot;&gt;.center&lt;/span&gt; = center;
  }
}
&lt;span class=&quot;hljs-keyword&quot;&gt;@end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;作成したカスタムクラスをNavigation Controllerに紐付けます&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Storyboard にて &lt;code&gt;Navigation Controller Scene&lt;/code&gt; -&amp;gt; &lt;code&gt;Navigation Controller&lt;/code&gt; -&amp;gt; &lt;code&gt;Navigation Bar&lt;/code&gt; を選択します。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Custom Class&lt;/code&gt; で 作成したカスタムクラス (この例では &lt;code&gt;XXCustomNavigationBar&lt;/code&gt;) を指定します。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;これで実行すると、Navigation Barが指定した高さで表示されるはずです。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/2346304161398157539/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/07/blog-post.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/2346304161398157539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/2346304161398157539'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/07/blog-post.html' title='ナビゲーションバーの高さを変更する'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-5862086529855080160</id><published>2015-07-13T17:31:00.001+09:00</published><updated>2015-07-13T19:02:01.201+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="objective-c"/><title type='text'>UIScrollViewのスクロール関連のプロパティについて</title><content type='html'>&lt;p&gt;UIScrollView のスクロール関連のプロパティについて。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;

&lt;h2 id=&quot;スクロール方向を固定する&quot;&gt;スクロール方向を固定する&lt;/h2&gt;

&lt;p&gt;斜め方向のスクロールを制限する場合、&lt;code&gt;UIScrollView&lt;/code&gt; の &lt;code&gt;directionalLockEnabled&lt;/code&gt; に &lt;code&gt;YES&lt;/code&gt; をセットする。&lt;/p&gt;

&lt;p&gt;ただ、まれに斜め方向にスクロールしてしまう (正確に斜め方向にドラッグされた場合？)。 &lt;br&gt;
ドラッグ開始前後の位置を取得し、移動後にスクロール位置を矯正するよう実装する。&lt;/p&gt;

&lt;p&gt;以下の &lt;code&gt;UIScrollViewDelegate&lt;/code&gt; を使用する。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;- (void)scrollViewWillBeginDragging:(UIScrollView*)scrollView&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;- (void)scrollViewDidScroll:(UIScrollView*)scrollView&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;参考: &lt;a href=&quot;http://iphone-dev.g.hatena.ne.jp/tokorom/20101002/1285998723&quot;&gt;http://iphone-dev.g.hatena.ne.jp/tokorom/20101002/1285998723&lt;/a&gt;&lt;/p&gt;

&lt;br&gt;
&lt;hr&gt;

&lt;h3&gt;追記&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;- (void)scrollViewWillBeginDragging:(UIScrollView*)scrollView&lt;/code&gt; だけでスクロール方向を取得する方法があったので、参考リンクを追加&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://qiita.com/noppefoxwolf/items/2634f9484b7f78816622&quot;&gt;UITableView/UIScrollViewでスクロール直後のスクロール方向を取得する&lt;/a&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;

&lt;h2 id=&quot;スクロール速度を変更する&quot;&gt;スクロール速度を変更する&lt;/h2&gt;

&lt;p&gt;正確にはスクロールが減速するスピードの比率。 &lt;br&gt;
&lt;code&gt;UIScrollView&lt;/code&gt; の &lt;code&gt;decelerationRate&lt;/code&gt; に &lt;code&gt;UIScrollViewDecelerationRateFast&lt;/code&gt; を設定すると減速するスピードが早くなる (スクロール停止が早くなる→スクロール速度が遅くなったように見える)&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs fix&quot;&gt;&lt;span class=&quot;hljs-attribute&quot;&gt;scrollView.decelerationRate &lt;/span&gt;=&lt;span class=&quot;hljs-string&quot;&gt; UIScrollViewDecelerationRateFast;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;参考: &lt;a href=&quot;https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIScrollView_Class/&quot;&gt;UIScrollView Class Reference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/5862086529855080160/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/07/uiscrollview.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/5862086529855080160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/5862086529855080160'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/07/uiscrollview.html' title='UIScrollViewのスクロール関連のプロパティについて'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-5025967278788230637</id><published>2015-07-06T12:55:00.001+09:00</published><updated>2015-07-06T12:57:46.475+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="objective-c"/><title type='text'>UIImageViewにimageを設定する際に例外が発生する？</title><content type='html'>&lt;h2 id=&quot;uiimageviewにimageを設定する際に例外&quot;&gt;UIImageViewにimageを設定する際に例外!?&lt;/h2&gt;

&lt;p&gt;他人が作ったアプリのバグ修正依頼を受けた。&lt;/p&gt;

&lt;p&gt;デバッグ実行してみると、 &lt;br&gt;
&lt;code&gt;UIImageView&lt;/code&gt; の &lt;code&gt;image&lt;/code&gt; に &lt;code&gt;UIImage&lt;/code&gt; を設定しようとして、例外が発生していた。&lt;/p&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs markdown&quot;&gt;[&lt;span class=&quot;hljs-link_reference&quot;&gt;XxxxxView setImage:&lt;/span&gt;]:&lt;span class=&quot;hljs-link_url&quot;&gt; unrecognized selector sent to instance xxxxxxxxxx&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;unrecognized selector&lt;/code&gt; なので、メソッド名の指定に間違いがあるようだが… &lt;br&gt;
ん、&lt;code&gt;UIImageView&lt;/code&gt; でなく &lt;code&gt;XxxxxView&lt;/code&gt; (該当画面のViewController) になってる？&lt;/p&gt;

&lt;p&gt;ロジックを見てると、予め作成された &lt;code&gt;UIImageView&lt;/code&gt; を &lt;code&gt;[self viewWithTag: tagNo]&lt;/code&gt; で取得していたんだが、条件によって &lt;code&gt;tagNo&lt;/code&gt; が &lt;code&gt;0&lt;/code&gt; になるパターンがあった。&lt;/p&gt;



&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs objectivec&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;int&lt;/span&gt; i=&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;; i&amp;lt;kX; i++) {
  &lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;int&lt;/span&gt; j=&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;; j&amp;lt;kY; j++) {
    &lt;span class=&quot;hljs-built_in&quot;&gt;NSInteger&lt;/span&gt; tagNo = [&lt;span class=&quot;hljs-keyword&quot;&gt;self&lt;/span&gt; getTagNoWithX:i Y:j]; &lt;span class=&quot;hljs-comment&quot;&gt;// &amp;lt;- ここがおかしい&lt;/span&gt;
    &lt;span class=&quot;hljs-built_in&quot;&gt;UIImageView&lt;/span&gt; *img = (&lt;span class=&quot;hljs-built_in&quot;&gt;UIImageView&lt;/span&gt; *)[&lt;span class=&quot;hljs-keyword&quot;&gt;self&lt;/span&gt; viewWithTag: tagNo];
    img&lt;span class=&quot;hljs-variable&quot;&gt;.image&lt;/span&gt; = [&lt;span class=&quot;hljs-built_in&quot;&gt;UIImage&lt;/span&gt; imageNamed:@&lt;span class=&quot;hljs-string&quot;&gt;&quot;icon-name&quot;&lt;/span&gt;];
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;[self viewWithTag: 0]&lt;/code&gt; の時に 自分自身 (&lt;code&gt;self&lt;/code&gt;) が返ってきてしまう模様。 &lt;br&gt;
適切なTagNoを返すように修正した。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;参考: &lt;a href=&quot;http://stackoverflow.com/questions/12036404/uiimageview-set-image-crash&quot;&gt;UIImageview set image crash&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/5025967278788230637/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/07/uiimageviewimage.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/5025967278788230637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/5025967278788230637'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/07/uiimageviewimage.html' title='UIImageViewにimageを設定する際に例外が発生する？'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-6825803293222375119</id><published>2015-07-02T18:24:00.001+09:00</published><updated>2015-07-02T18:24:04.886+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><category scheme="http://www.blogger.com/atom/ns#" term="objective-c"/><title type='text'>UIPopoverPresentationControllerが閉じる際にタップを連打するとアプリが落ちることへの対策</title><content type='html'>&lt;h2 id=&quot;不具合内容&quot;&gt;不具合内容&lt;/h2&gt;

&lt;p&gt;iPadアプリで、あるUITextFieldが選択されると、UIPopoverPresentationControllerでTableViewを表示して選択肢の中からユーザーに項目を選ばせる、という画面を実装していたところ、以下の様な不具合が発生した。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;タップを連打すると、popoverがcloseするタイミングでエラーも出ずにアプリが落ちる&lt;/li&gt;
&lt;li&gt;iOS 8.3, 8.4 では発生しない&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;最新のOSバージョンでは発生しないのでiOSの不具合と思われるが、どうしても対応して欲しいとのリクエストをお客さんからいただいたので、検討してみた。&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;/p&gt;

&lt;h2 id=&quot;対応方法&quot;&gt;対応方法&lt;/h2&gt;

&lt;p&gt;あまり時間を掛けたくなかったので、かなり場当たり的な対応だが、以下の方法で不具合を回避できた。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;(BOOL)popoverPresentationControllerDidDismissPopover:&lt;/code&gt; にて、&lt;code&gt;beginIgnoringInteractionEvents&lt;/code&gt; でタッチイベントを無効化する&lt;/li&gt;
&lt;li&gt;500ms後に &lt;code&gt;endIgnoringInteractionEvents&lt;/code&gt; でタッチイベントを有効に戻す&lt;/li&gt;
&lt;/ul&gt;



&lt;h3 id=&quot;コード例&quot;&gt;コード例&lt;/h3&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code class=&quot; hljs java&quot;&gt;#pragma mark - タップ連打防止
&lt;span class=&quot;hljs-javadoc&quot;&gt;/**
 * iOS8.3未満の場合、タップを無効化する
 */&lt;/span&gt;
- (&lt;span class=&quot;hljs-keyword&quot;&gt;void&lt;/span&gt;)preventTapBarrage:(&lt;span class=&quot;hljs-keyword&quot;&gt;float&lt;/span&gt;)waitTime
{
  &lt;span class=&quot;hljs-comment&quot;&gt;// iOS8.3未満の場合&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; ([[UIDevice currentDevice].systemVersion floatValue] &amp;lt; &lt;span class=&quot;hljs-number&quot;&gt;8.3&lt;/span&gt;){
    &lt;span class=&quot;hljs-comment&quot;&gt;// タッチイベントを無効にする&lt;/span&gt;
    [[UIApplication sharedApplication] beginIgnoringInteractionEvents];

    &lt;span class=&quot;hljs-comment&quot;&gt;// 指定ms後、タッチイベントを有効に戻す&lt;/span&gt;
    [NSTimer scheduledTimerWithTimeInterval:waitTime
                                     target:self
                                   selector:&lt;span class=&quot;hljs-annotation&quot;&gt;@selector&lt;/span&gt;(enableTapEvents:)
                                   userInfo:nil
                                    repeats:NO];
  }
}

&lt;span class=&quot;hljs-javadoc&quot;&gt;/**
 * タップを有効に戻す
 */&lt;/span&gt;
- (&lt;span class=&quot;hljs-keyword&quot;&gt;void&lt;/span&gt;)enableTapEvents:(NSTimer *)timer
{
  &lt;span class=&quot;hljs-comment&quot;&gt;// タッチイベントが無効になっている場合&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; ([[UIApplication sharedApplication] isIgnoringInteractionEvents]){
    &lt;span class=&quot;hljs-comment&quot;&gt;// タッチイベントを有効にする&lt;/span&gt;
    [[UIApplication sharedApplication] endIgnoringInteractionEvents];
  }
}

#pragma mark - UIPopoverPresentationControllerDelegate Methods
&lt;span class=&quot;hljs-javadoc&quot;&gt;/**
 * iOS8.3未満において、popoverのclose時にタップ連打するとアプリが落ちるため
 * 一時的 (500ms) にタッチを無効化する
 */&lt;/span&gt;
- (BOOL)popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController
{
  &lt;span class=&quot;hljs-comment&quot;&gt;// 500msタッチ無効 (iOS version &amp;lt; 8.3 の場合のみ)&lt;/span&gt;
  [self preventTapBarrage:&lt;span class=&quot;hljs-number&quot;&gt;0.5&lt;/span&gt;f];
  &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; YES;
}&lt;/code&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/6825803293222375119/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/07/uipopoverpresentationcontroller.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/6825803293222375119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/6825803293222375119'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2015/07/uipopoverpresentationcontroller.html' title='UIPopoverPresentationControllerが閉じる際にタップを連打するとアプリが落ちることへの対策'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-7229350719772862095</id><published>2014-05-02T16:39:00.002+09:00</published><updated>2014-05-02T16:39:24.383+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Git"/><title type='text'>git add時の改行コード変換のwarningを消す</title><content type='html'>&lt;link rel=&quot;stylesheet&quot; href=&quot;http://yandex.st/highlightjs/8.0/styles/default.min.css&quot;&gt;

&lt;p&gt;WindowsでGitを使う際、&lt;code&gt;git add&lt;/code&gt;コマンド実行時に改行コードのwarningが出る。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;warning: LF will be replaced &lt;span class=&quot;hljs-keyword&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;hljs-constant&quot;&gt;CRLF&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;in&lt;/span&gt; app.js.
The &lt;span class=&quot;hljs-built_in&quot;&gt;file&lt;/span&gt; will have its original &lt;span class=&quot;hljs-built_in&quot;&gt;line&lt;/span&gt; endings &lt;span class=&quot;hljs-operator&quot;&gt;in&lt;/span&gt; your working &lt;span class=&quot;hljs-built_in&quot;&gt;directory&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;以下の設定で、改行コードの変換を無効にする。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config --&lt;span class=&quot;hljs-keyword&quot;&gt;global&lt;/span&gt; core.autoCRLF &lt;span class=&quot;hljs-keyword&quot;&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;script src=&quot;http://yandex.st/highlightjs/8.0/highlight.min.js&quot;&gt;&lt;/script&gt;
</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/7229350719772862095/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2014/05/git-addwarning.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/7229350719772862095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/7229350719772862095'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2014/05/git-addwarning.html' title='git add時の改行コード変換のwarningを消す'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-7162778290149482445</id><published>2014-02-06T14:38:00.001+09:00</published><updated>2014-02-06T14:38:25.646+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="PowerShell"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>[PowerShell] 外部DLLを読み込み、メソッドを実行</title><content type='html'>&lt;p&gt;Visual Studioなんかで作成したDLLの動作確認とかしたい時、
あるいは簡単なテストスクリプトを作成する時などに、PowerShellで作成したDLLを読み込むことができます。&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/Kazunori-Kimura/8838802.js&quot;&gt;&lt;/script&gt;

</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/7162778290149482445/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2014/02/powershell-dll.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/7162778290149482445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/7162778290149482445'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2014/02/powershell-dll.html' title='[PowerShell] 外部DLLを読み込み、メソッドを実行'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-6232901413546687725</id><published>2014-01-30T21:34:00.004+09:00</published><updated>2014-01-30T21:34:57.964+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="nodejs"/><title type='text'>gitignoreファイルを作成する「node-gi」を公開しました</title><content type='html'>gitignoreファイルを生成するためのコマンドラインツールを作成したので、npmで公開しました。&lt;br /&gt;
&lt;br /&gt;
中身は&amp;nbsp;&lt;a href=&quot;http://www.gitignore.io/&quot;&gt;http://www.gitignore.io/&lt;/a&gt;&amp;nbsp;にリクエストを投げて、結果を返してるだけです。&lt;br /&gt;
&lt;br /&gt;
詳細は以下を参照してください。&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://npmjs.org/package/node-gi&quot;&gt;https://npmjs.org/package/node-gi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Kazunori-Kimura/node-gi&quot;&gt;https://github.com/Kazunori-Kimura/node-gi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/6232901413546687725/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2014/01/gitignorenode-gi.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/6232901413546687725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/6232901413546687725'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2014/01/gitignorenode-gi.html' title='gitignoreファイルを作成する「node-gi」を公開しました'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-2653045249258817337</id><published>2013-06-26T00:33:00.002+09:00</published><updated>2013-06-26T00:33:49.587+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bootstrap"/><category scheme="http://www.blogger.com/atom/ns#" term="css"/><category scheme="http://www.blogger.com/atom/ns#" term="html"/><title type='text'>bootstrap-selectを試してみる</title><content type='html'>
&lt;h2&gt;概要&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://silviomoreto.github.io/bootstrap-select/&quot;&gt;bootstrap-select&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://twitter.github.io/bootstrap/&quot;&gt;bootstrap&lt;/a&gt; のデフォルトでは
&lt;code&gt;select&lt;/code&gt;タグのスタイルはイマイチ。&lt;/p&gt;

&lt;p&gt;bootstrap-selectを使用すると、&lt;code&gt;select&lt;/code&gt;タグを
&lt;a href=&quot;http://twitter.github.io/bootstrap/components.html#buttonDropdowns&quot;&gt;Button dropdown menu&lt;/a&gt; に置き換えてくれる。&lt;/p&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUss92lL6Ak-8bRxgliEcWve69tIxEBSGP59ylExd91xxPpcL-4jMMG6klYwd_acCiKvBVI7ZWIqm4Mx5vqPiMjcFfOuJtRojCNvYtOfoSzXzAzhFhV4p51gI5-Cn-d-W0WalME7MXS_7f/s1600/bootstrap-select.png&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUss92lL6Ak-8bRxgliEcWve69tIxEBSGP59ylExd91xxPpcL-4jMMG6klYwd_acCiKvBVI7ZWIqm4Mx5vqPiMjcFfOuJtRojCNvYtOfoSzXzAzhFhV4p51gI5-Cn-d-W0WalME7MXS_7f/s320/bootstrap-select.png&quot; /&gt;&lt;/a&gt;


&lt;hr /&gt;

&lt;h2&gt;テストページ&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;bootstrap-select.css&lt;/code&gt;, &lt;code&gt;bootstrap-select.js&lt;/code&gt; を読み込む&lt;/p&gt;

&lt;p&gt;スタイルを変更したい &lt;code&gt;select&lt;/code&gt;タグに &lt;code&gt;selectpicker&lt;/code&gt;クラスをセットする&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$(document).ready&lt;/code&gt; にて &lt;code&gt;$(&quot;.selectpicker&quot;).selectpicker();&lt;/code&gt;を実行する&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;ja&quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
    &amp;lt;title&amp;gt;ぶーとすとらっぷ せれくと&amp;lt;/title&amp;gt;
    &amp;lt;link rel=&quot;stylesheet&quot; href=&quot;vender/bootstrap/css/bootstrap.min.css&quot; /&amp;gt;
    &amp;lt;link rel=&quot;stylesheet&quot; href=&quot;vender/bootstrap-select/bootstrap-select.min.css&quot; /&amp;gt;

    &amp;lt;style type=&quot;text/css&quot;&amp;gt;
        body {
            padding: 40px;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

    &amp;lt;form class=&quot;form-inline&quot;&amp;gt;
        &amp;lt;select id=&quot;s1&quot; class=&quot;selectpicker&quot; name=&quot;s1&quot;&amp;gt;
            &amp;lt;option value=&quot;1&quot;&amp;gt;hoge&amp;lt;/option&amp;gt;
            &amp;lt;option value=&quot;2&quot;&amp;gt;foo&amp;lt;/option&amp;gt;
            &amp;lt;option value=&quot;3&quot;&amp;gt;bar&amp;lt;/option&amp;gt;
        &amp;lt;/select&amp;gt;

        &amp;lt;button id=&quot;hoge&quot; class=&quot;btn btn-primary&quot;&amp;gt;Get Value&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;

    &amp;lt;input id=&quot;t1&quot; type=&quot;text&quot; readonly /&amp;gt;

    &amp;lt;script src=&quot;//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;vender/bootstrap/js/bootstrap.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;vender/bootstrap-select/bootstrap-select.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;

    &amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
        $(document).ready(function(){

            //enable bootstrap-select
            $(&quot;.selectpicker&quot;).selectpicker();

            //click hoge button
            $(&quot;#hoge&quot;).click(function(){
                $(&quot;#t1&quot;).val($(&quot;#s1&quot;).val());
                return false;
            });

        });
    &amp;lt;/script&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;hr /&gt;

&lt;p&gt;今、開発中のアプリで使おうかと思ったけど
Internet Explorer 7だとちょっと表示が変だったので、
今回はbootstrap標準のselectタグを使う。&lt;/p&gt;

&lt;br&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/2653045249258817337/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2013/06/bootstrap-select.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/2653045249258817337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/2653045249258817337'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2013/06/bootstrap-select.html' title='bootstrap-selectを試してみる'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUss92lL6Ak-8bRxgliEcWve69tIxEBSGP59ylExd91xxPpcL-4jMMG6klYwd_acCiKvBVI7ZWIqm4Mx5vqPiMjcFfOuJtRojCNvYtOfoSzXzAzhFhV4p51gI5-Cn-d-W0WalME7MXS_7f/s72-c/bootstrap-select.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-4718277479558256183</id><published>2013-06-11T14:03:00.001+09:00</published><updated>2013-06-11T14:03:35.937+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="PetaPoco"/><title type='text'>[ASP.NET MVC2] 簡単なカスタム認証機能の実装</title><content type='html'>&lt;h1&gt;[ASP.NET MVC2] 簡単なカスタム認証機能の実装&lt;/h1&gt;

&lt;h2&gt;環境&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visual Studio 2010&lt;/li&gt;
&lt;li&gt;.Net Framework 4&lt;/li&gt;
&lt;li&gt;ASP.NET MVC2&lt;/li&gt;
&lt;li&gt;PostgreSQL 8.4&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;概要&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;LoginとMenuの2画面&lt;/li&gt;
&lt;li&gt;未認証状態でMenuにアクセスするとLoginに戻される&lt;/li&gt;
&lt;li&gt;PostgreSQL上でアカウント管理を行う&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2&gt;プロジェクトの作成&lt;/h2&gt;

&lt;p&gt;プロジェクト名： CustomAuthorize&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Kazunori-Kimura/CustomAuthenticate&quot;&gt;Githubレポジトリ CustomAuthorize&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;パッケージ追加&lt;/h2&gt;

&lt;p&gt;NuGetで必要なパッケージを追加&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Npgsql&lt;/li&gt;
&lt;li&gt;PetaPoco.Core&lt;/li&gt;
&lt;li&gt;log4net&lt;/li&gt;
&lt;li&gt;Bootstrap&lt;/li&gt;
&lt;li&gt;(jQuery 1.9.1) Bootstrapと一緒に追加される&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2&gt;log4net.config&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;構成ファイルを追加&lt;/li&gt;
&lt;li&gt;ファイル名: log4net.config&lt;/li&gt;
&lt;/ul&gt;

&lt;script src=&quot;https://gist.github.com/Kazunori-Kimura/5753935.js&quot;&gt;&lt;/script&gt;

&lt;ul&gt;
&lt;li&gt;ファイル名に日付を付けてローテートさせる&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Global.asax.cs&lt;/h2&gt;

&lt;script src=&quot;https://gist.github.com/Kazunori-Kimura/5753949.js&quot;&gt;&lt;/script&gt;

&lt;ul&gt;
&lt;li&gt;初期表示パスを /Login/Index に変更&lt;/li&gt;
&lt;li&gt;Application_Start() にてlog4net設定ファイル読み込み&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2&gt;Controllerの作成&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;LoginController &lt;br /&gt;
とりあえず空っぽにしておく&lt;/li&gt;
&lt;li&gt;MenuController &lt;br /&gt;
未認証ではアクセスできないように classに [Authorize] を設定&lt;/li&gt;
&lt;/ul&gt;

&lt;script src=&quot;https://gist.github.com/Kazunori-Kimura/5753959.js&quot;&gt;&lt;/script&gt;

&lt;h2&gt;Viewの作成&lt;/h2&gt;

&lt;h3&gt;マスターページを作成&lt;/h3&gt;

&lt;h4&gt;MVC2 ビューマスターページを Views/Shared に追加&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Site.Master&lt;/li&gt;
&lt;/ul&gt;

&lt;script src=&quot;https://gist.github.com/Kazunori-Kimura/5753974.js&quot;&gt;&lt;/script&gt;

&lt;ul&gt;
&lt;li&gt;ログインユーザー名を Session[&quot;USER_NAME&quot;] から取得し、ヘッダー部分に表示&lt;/li&gt;
&lt;li&gt;ログアウトボタン押下で LoginController/Logoff に Ajax($.get) で問い合わせ&lt;/li&gt;
&lt;li&gt;結果に関わらず Login画面に遷移&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3&gt;Login View を作成&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;LoginController.csを開く&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Index Methodを右クリック → ビューの追加 を選択 &lt;br /&gt;
Login/IndexはSite.Masterを使用しない&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Login/Index.aspx&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;script src=&quot;https://gist.github.com/Kazunori-Kimura/5754012.js&quot;&gt;&lt;/script&gt;

&lt;ul&gt;
&lt;li&gt;LOGINボタン押下で LoginController/Authenticate に Ajax($.post) で問い合わせ&lt;/li&gt;
&lt;li&gt;認証結果を受けて、メニュー画面に遷移&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Menu View を作成&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;MenuController.csを開く&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Index Methodを右クリック → ビューの追加 を選択&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Menu/Index.aspx&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;script src=&quot;https://gist.github.com/Kazunori-Kimura/5754020.js&quot;&gt;&lt;/script&gt;

&lt;hr /&gt;

&lt;h2&gt;Modelの作成&lt;/h2&gt;

&lt;p&gt;Database(今回はPostgreSQL)の接続には PetaPoco を使用する&lt;/p&gt;

&lt;h3&gt;user.cs を作成&lt;/h3&gt;

&lt;script src=&quot;https://gist.github.com/Kazunori-Kimura/5754530.js&quot;&gt;&lt;/script&gt;

&lt;h3&gt;AccountManager.cs を作成&lt;/h3&gt;

&lt;script src=&quot;https://gist.github.com/Kazunori-Kimura/5754538.js&quot;&gt;&lt;/script&gt;

&lt;hr /&gt;

&lt;h2&gt;LoginController 実装&lt;/h2&gt;

&lt;h3&gt;LoginController.cs&lt;/h3&gt;

&lt;script src=&quot;https://gist.github.com/Kazunori-Kimura/5754552.js&quot;&gt;&lt;/script&gt;

&lt;ul&gt;
&lt;li&gt;Authenticate: ログイン認証を行う&lt;/li&gt;
&lt;li&gt;Logoff : ログオフ処理を行う&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;実行してみる。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;初期表示で localhost/Login が表示される&lt;/li&gt;
&lt;li&gt;認証せずに localhost/Menu にアクセスすると、 localhost/Login に戻される&lt;/li&gt;
&lt;li&gt;localhost/Login で認証を行うと localhost/Menu に遷移する&lt;/li&gt;
&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/4718277479558256183/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2013/06/aspnet-mvc2.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/4718277479558256183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/4718277479558256183'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2013/06/aspnet-mvc2.html' title='[ASP.NET MVC2] 簡単なカスタム認証機能の実装'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-3631201599673556614</id><published>2013-06-07T17:52:00.003+09:00</published><updated>2013-06-07T17:52:49.592+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="PetaPoco"/><title type='text'>C#製の簡易O/Rマッパー PetaPoco を試してみる</title><content type='html'>&lt;!-- C#製の簡易O/Rマッパー PetaPoco を試してみる --&gt;

&lt;h2&gt;PetaPoco&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.toptensoftware.com/petapoco/&quot;&gt;PetaPoco&lt;/a&gt;
.NETの簡易O/Rマッパー。&lt;/p&gt;

&lt;p&gt;とりあえずPostgreSQLで試してみる。
&lt;a href=&quot;http://brandonpugh.com/blog/2011/11/getting-started-with-petapoco-and-postgres/&quot;&gt;Getting Started With PetaPoco and Postgres&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;環境&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Windows XP SP3&lt;/li&gt;
&lt;li&gt;.Net Framework 4&lt;/li&gt;
&lt;li&gt;PostgreSQL 8.4&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;プログラム作成手順&lt;/h2&gt;

&lt;h3&gt;Databaseの準備&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;server: localhost&lt;/li&gt;
&lt;li&gt;database: petapoco&lt;/li&gt;
&lt;li&gt;owner: postgres&lt;/li&gt;
&lt;/ul&gt;

&lt;script src=&quot;https://gist.github.com/Kazunori-Kimura/5727883.js&quot;&gt;&lt;/script&gt;

&lt;h3&gt;Visual Studioでコーディング&lt;/h3&gt;

&lt;h4&gt;プロジェクト作成&lt;/h4&gt;

&lt;p&gt;コンソールアプリケーションのプロジェクトを作成&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;名前: PetaPocoTest&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;NuGet Package追加&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;http://nuget.org/&quot;&gt;NuGet&lt;/a&gt;すごい便利。 &lt;br /&gt;
以下のパッケージを追加&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PetaPoco.CORE&lt;/li&gt;
&lt;li&gt;Npgsql&lt;/li&gt;
&lt;li&gt;log4net&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PetaPocoを追加すると、勝手にModelsフォルダが生成される。&lt;/p&gt;

&lt;h4&gt;POCOクラスの作成&lt;/h4&gt;

&lt;p&gt;いわゆるModel Class。 &lt;br /&gt;
usersテーブルに合わせて以下のように作成&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/Kazunori-Kimura/5727902.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;主キーが複数の場合は
&lt;code&gt;[PetaPoco.PrimaryKey(&quot;key1,key2&quot;)]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;PetaPocoに管理させたくないプロパティには
&lt;code&gt;[PetaPoco.Ignore]&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;DataManagerクラスの作成&lt;/h4&gt;

&lt;p&gt;Databaseに接続し、PetaPocoを使用してデータを取得するクラス。&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/Kazunori-Kimura/5727908.js&quot;&gt;&lt;/script&gt;

&lt;h5&gt;コンストラクタ&lt;/h5&gt;

&lt;p&gt;DbProviderFactoriesの指定は app.config にも書けるけど、記述が面倒なので引数で渡した。&lt;/p&gt;

&lt;h5&gt;GetUserBySystemIdメソッド&lt;/h5&gt;

&lt;p&gt;PetaPoco.Sql.BuilderにてSQLを組み立て。 &lt;br /&gt;
きっと引数とかはちゃんとエスケープしてくれるのだろう。&lt;/p&gt;

&lt;p&gt;テーブル作成時にキチンと指定していないけど、
system_idはユニークな想定なので、Fetchで返されたListの先頭を取得している。&lt;/p&gt;

&lt;h4&gt;Program.cs&lt;/h4&gt;

&lt;p&gt;Databaseからuserを取得し、名前をログに出力。&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/Kazunori-Kimura/5727919.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;あたりまえだが、実際には GetUserBySystemId から返ってきた値が null かどうかチェックしないといけない。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2&gt;参考&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.toptensoftware.com/petapoco/&quot;&gt;PetaPoco&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://brandonpugh.com/blog/2011/11/getting-started-with-petapoco-and-postgres/&quot;&gt;Getting Started With PetaPoco and Postgres&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.arroyocode.com/micro-orm-data-mapping-with-petapoco-and-asp-net-mvc-4&quot;&gt;Micro ORM Data Mapping with PetaPoco and ASP.NET MVC 4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/7741229/updating-database-in-transaction-from-listt&quot;&gt;Updating database in Transaction from List&lt;T&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/3631201599673556614/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2013/06/cor-petapoco.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/3631201599673556614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/3631201599673556614'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2013/06/cor-petapoco.html' title='C#製の簡易O/Rマッパー PetaPoco を試してみる'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-9038050336423934614</id><published>2013-05-15T21:40:00.000+09:00</published><updated>2013-05-15T21:54:30.307+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Git"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>WindowsでGitを使う(proxyとかFirewallの設定)</title><content type='html'>&lt;p&gt;企業内のネットワーク配下でGitを使う際の設定について。 &lt;br /&gt;
Windows XPでやってます。&lt;/p&gt;

&lt;h3&gt;&lt;a href=&quot;http://msysgit.github.io/&quot;&gt;Git for Windows&lt;/a&gt; をインストール&lt;/h3&gt;

&lt;p&gt;ウィザード内の選択肢で、コマンドプロンプトでgitを使うよう選択する。&lt;/p&gt;

&lt;p&gt;以降の作業はコマンドプロンプトとGit bashどちらでも可能。&lt;/p&gt;

&lt;h3&gt;初期設定&lt;/h3&gt;

&lt;pre class=&quot;brush:bash;&quot;&gt;git config --global user.name kazunori.kimura
git config --global user.email kazunori.kimura.js@gmail.com
&lt;/pre&gt;

&lt;br /&gt;

&lt;h3&gt;proxy設定&lt;/h3&gt;

&lt;p&gt;Proxy配下の場合は以下の設定を行う。 &lt;br /&gt;
環境変数 HTTP_PROXY を設定してたけど、見てくれなかった。&lt;/p&gt;

&lt;pre class=&quot;brush:bash;&quot;&gt;git config --global http.proxy http://{proxy_host}:{proxy_port}
git config --global https.proxy http[s]://{proxy_host}:{proxy_port}
&lt;/pre&gt;

&lt;br /&gt;

&lt;h3&gt;gitプロトコルの対応&lt;/h3&gt;

&lt;p&gt;Firewallで git:// の通信が阻害されてしまう場合は。。。&lt;/p&gt;

&lt;pre class=&quot;brush:bash;&quot;&gt;$ git clone git://github.com/Kazunori-Kimura/MyPowerShellSnippet.git
Cloning into &#39;MyPowerShellSnippet&#39;...
fatal: unable to connect to github.com:
github.com[0: 204.232.175.90]: errno=No such file or directory
&lt;/pre&gt;

&lt;p&gt;以下の設定によって、自動的に git:// を https:// に置き換えて通信してくれる。&lt;/p&gt;

&lt;pre class=&quot;brush:bash;&quot;&gt;$ git config --global url.&quot;https://&quot;.insteadOf git://
&lt;/pre&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;参考: &lt;a href=&quot;http://stackoverflow.com/questions/4891527/git-protocol-blocked-by-company-how-can-i-get-around-that/10729634#10729634&quot;&gt;git:// protocol blocked by company, how can I get around that?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/9038050336423934614/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2013/05/windowsgitproxyfirewall.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/9038050336423934614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/9038050336423934614'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2013/05/windowsgitproxyfirewall.html' title='WindowsでGitを使う(proxyとかFirewallの設定)'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-3646540107808110920</id><published>2013-05-13T22:39:00.001+09:00</published><updated>2013-05-14T03:01:47.139+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="nodejs"/><category scheme="http://www.blogger.com/atom/ns#" term="Oracle"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>node で Oracle に接続する</title><content type='html'>
&lt;h2&gt;Oracle接続&lt;/h2&gt;

&lt;p&gt;Windowsにて、nodeでOracle 11gに接続し、値を取得したい。&lt;/p&gt;

&lt;h3&gt;結論&lt;/h3&gt;

&lt;p&gt;node-odbcで動いた。&lt;/p&gt;

&lt;h3&gt;事前準備&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;python&lt;/li&gt;
&lt;li&gt;&lt;p&gt;node-gyp&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;gyp: Generate Your Projects  &lt;/li&gt;
&lt;li&gt;Google Chromeのためのビルドシステム&lt;/li&gt;
&lt;li&gt;pythonで書かれている&lt;/li&gt;
&lt;li&gt;node-gyp: gypによるビルドファイルの生成からコンパイルまで行える&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;python2.7をインストール後、node-gypをglobalオプション付きでインストール&lt;br&gt;
&lt;code&gt;npm install -g node-gyp&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;node-odbcインストール&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/w1nk/node-odbc&quot;&gt;node-odbc&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;npm install node-odbc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;node-gypのbuildで3箇所警告が出たが、一応インストールは成功した。&lt;/p&gt;

&lt;h3&gt;動作確認&lt;/h3&gt;

&lt;p&gt;とりあえず、単純なselect文を投げて結果を取得してみる&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;app.js&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class=&quot;brush:js;&quot;&gt;
/*
 * oracle test
 */

var odbc = require(&quot;odbc&quot;);

var db = new odbc.Database();
var cs = &quot;DSN=&amp;lt;DataSourceName&gt;;UID=&amp;lt;UserName&gt;;PWD=&amp;lt;Password&gt;&quot;;
db.open(cs, function(err){
    var sql = &quot;select foo, bar from HOGE order by foo&quot;;
    db.query(sql, function(err, rows, rs){
        //console.log(rows);
        var i=0;
        for (i=0; i&amp;lt;rows.length; i++) {
            console.log([
                i,
                rows[i][&quot;foo&quot;],
                rows[i][&quot;bar&quot;]
            ].join(&quot;, &quot;));
        }

        db.close(function(){
            console.log(&quot;close.&quot;);
        });
    });
});
&lt;/pre&gt;

&lt;hr /&gt;

&lt;h2&gt;試行錯誤の経緯&lt;/h2&gt;

&lt;h3&gt;試したmodule&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;node-oracle&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;上手くインストールできない。コンパイルで失敗する。&lt;/li&gt;
&lt;li&gt;node-gypで、-zオプションの使い方がおかしいといったエラー。&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;node-db-oracle&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;node-wafを使用しており、コンパイルで失敗する。&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;node-odp&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;インストールはできるが、うまく動かない。&lt;/li&gt;
&lt;li&gt;module内にバイナリファイル nodeodp.node があるが、これがx64用？&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/3646540107808110920/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2013/05/node-oracle.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/3646540107808110920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/3646540107808110920'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2013/05/node-oracle.html' title='node で Oracle に接続する'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-660700117305511026</id><published>2013-05-06T23:59:00.001+09:00</published><updated>2013-05-07T12:39:46.966+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="nodejs"/><title type='text'>[備忘録] node.js環境構築</title><content type='html'>&lt;p&gt;node.js環境 (nvm, npm) をインストールする手順。今回はMacにて行ったが、Gitを使える環境であればWindows/Linuxで(ほぼ)共通。&lt;/p&gt;
&lt;p&gt;Githubからnvmを取得する。&lt;/p&gt;
&lt;pre class=&quot;brush:bash;&quot;&gt;
cd ~
git clone git://github.com/creationix/nvm.git .nvm
. .nvm/nvm.sh
&lt;/pre&gt;

&lt;p&gt;nvmでダウンロード可能なnodeの最新バージョンを確認する。&lt;/p&gt;

&lt;pre class=&quot;brush:bash;&quot;&gt;
nvm ls-remote
&lt;/pre&gt;

&lt;p&gt;最新バージョンのnodeをインストール&lt;/p&gt;

&lt;pre class=&quot;brush:bash;&quot;&gt;
nvm install v0.11.1
&lt;/pre&gt;

&lt;p&gt;インストールされたか確認。nvmインストール時に最新のnpmもインストールされている。&lt;/p&gt;

&lt;pre class=&quot;brush:bash;&quot;&gt;
node -v
npm -v
&lt;/pre&gt;

&lt;p&gt;次回ログイン時以降に .nvm/nvm.sh が読み込まれるように、~/.bash_profile に登録&lt;/p&gt;

&lt;pre class=&quot;brush:bash;&quot;&gt;
. ~/.nvm/nvm.sh
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/660700117305511026/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2013/05/nodejs.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/660700117305511026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/660700117305511026'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2013/05/nodejs.html' title='[備忘録] node.js環境構築'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4562980847459588265.post-1389522338266180762</id><published>2012-05-31T20:32:00.001+09:00</published><updated>2012-05-31T20:33:56.248+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="PowerShell"/><category scheme="http://www.blogger.com/atom/ns#" term="SQLServer"/><title type='text'>PowerShellでSQLServerのデータベースのバックアップ/リストアを行うスクリプト</title><content type='html'>&lt;p&gt;SqlCmdコマンドを使用してSQL Serverのデータベースをバックアップ/リストアするスクリプト。&lt;/p&gt;
&lt;p&gt;GitHub: &lt;a href=&quot;https://github.com/Kazunori-Kimura/MyPowerShellSnippet/blob/master/Backup-Database.ps1&quot;&gt;Backup-Database.ps1&lt;/a&gt;&lt;/p&gt;

&lt;pre class=&quot;brush:ps;&quot;&gt;
#Backup-Database.ps1
#simple backup &amp; restore script for SQLServer2008

Param(
  [switch] $backup,
  [switch] $restore,
  [string] $database=&quot;&quot;,
  [string] $server=$env:computerName,
  [string] $file=&quot;&quot;,
  [string] $directory=&quot;&quot;,
  [switch] $help,
  [switch] $debug
)

$usage=@&#39;

名前
    Backup-Database

概要
    SQL Serverデータベースの完全バックアップを作成/復元します。

構文
    Backup-Database {-Backup | -Restore} -Database &lt;DatabaseName&gt; [-Server &lt;ServerName&gt;] [-File &lt;BackupFile&gt; | 
     -Directory &lt;BackupDir&gt;]

説明
    SqlCmdコマンドを使用し、SQL Serverデータベースの完全バックアップを作成/復元します。
    SQL ServerにはWindows認証にて接続します。スクリプト実行アカウントにバックアップ/リストアを実施する
    権限がない場合、エラーとなります。
    
    File オプションを指定した場合、Directory オプションは無視されます。
    保存先とファイル名の両方を指定する場合 ( たとえば、D:\backup に backup.db という名前で作成したい場合 ) は
    File オプションにパスを指定してください。
    
    Backup時に File オプションが未指定の場合は DatabaseName よりバックアップファイル名を作成します。
    (.\&lt;DatabaseName&gt;_yyyyMMddHHmmss.bak)
    Restor時に File オプションが未指定の場合は例外が発生します。

関連するリンク
    http://msdn.microsoft.com/ja-jp/library/ms186865.aspx
    http://msdn.microsoft.com/ja-jp/library/ms186858.aspx
    http://msdn.microsoft.com/ja-jp/library/ms179313.aspx

&#39;@

$query_backup=&quot;BACKUP DATABASE {database_name} TO DISK = &#39;{backup_file}&#39;&quot;
$query_restore=&quot;RESTORE DATABASE {database_name} FROM DISK = &#39;{backup_file}&#39; WITH REPLACE&quot;

# Sqlcmdを実行
function Exec-SqlCommand($query){
  Sqlcmd -S $server -Q &quot;$query&quot;
}

# Backupを実施
function Backup-Database(){
  # database未指定→Error
  if( $database.length -eq 0 ){
    throw &quot;対象となる Database を指定してください。&quot;
  }
  # file未指定→database名 + 日付とする
  if( $file.length -eq 0 ){
    #カレントディレクトリを取得
    $current_path = Convert-Path .
    
    if( $directory.length -gt 0 ){
      #ディレクトリ指定時
      if( Test-Path $directory ){
        $current_path = Convert-Path $directory
      }else{
        throw &quot;指定されたディレクトリが存在しません。 [ $directory ]&quot;
      }
    }
    
    #yyyyMMddhhmmss
    $date_time = Get-Date -format &#39;yyyyMMddHHmmss&#39;
    #結合
    $file = $current_path + &#39;\&#39; + $database + &#39;_&#39; + $date_time + &#39;.bak&#39;;
  }

  $now = Get-Date -format &#39;yyyy/MM/dd HH:mm:ss&#39;
  $msg=@&quot;

Backupを実施します。[ $now ]
`tDatabase:`t$database
`tBackupFile:`t$file

&quot;@
  Write-Host $msg
  
  $q = $query_backup -replace &#39;{database_name}&#39;, $database
  $q = $q -replace &#39;{backup_file}&#39;, $file
  
  Write-Debug &quot;query= $q&quot;
  
  Exec-SqlCommand $q
  
  $now = Get-Date -format &#39;yyyy/MM/dd HH:mm:ss&#39;
  
  Write-Host &quot;`nBackupが完了しました。 [ $now ]`n&quot;
}

# Restoreを実施
function Restore-Database(){
  # database未指定→Error
  if( $database.length -eq 0 ){
    throw &quot;対象となる Database を指定してください。&quot;
  }
  # file未指定→Error
  if( $file.length -eq 0 ){
    throw &quot;リストアするファイルを指定してください。&quot;
  }
  # 存在しないfileを指定
  if( Test-Path $file ){
    $file = Convert-Path $file
  }else{
    throw &quot;指定されたファイルが存在しません。 [ $file ]&quot;
  }

  $now = Get-Date -format &#39;yyyy/MM/dd HH:mm:ss&#39;
  $msg=@&quot;

Restoreを実施します。[ $now ]
`tDatabase:`t$database
`tBackupFile:`t$file

&quot;@
  Write-Host $msg
  
  $q = $query_restore -replace &#39;{database_name}&#39;, $database
  $q = $q -replace &#39;{backup_file}&#39;, $file
  
  Write-Debug &quot;query= $q&quot;
  
  Exec-SqlCommand $q
  
  $now = Get-Date -format &#39;yyyy/MM/dd HH:mm:ss&#39;
  
  Write-Host &quot;`nRestoreが完了しました。 [ $now ]`n&quot;
}

# 引数をチェックし、処理を分岐
function Get-CommandLineOptions(){
  if($debug){
    #デバッグ表示を有効にする
    $DebugPreference=&quot;continue&quot;
  }

  if( $help ){
    # Helpの表示
    Write-Host $usage
  }elseif( $backup -and $restore ){
    # Backup と Resutore の両方を指定 -&gt; Error
    throw &quot;Backup|Restoreのどちらかを指定してください。&quot;
  }elseif( $backup ){
    Backup-Database
  }elseif( $restore ){
    Restore-Database
  }else{
    # Helpの表示
    Write-Host $usage
  }
}

Get-CommandLineOptions

&lt;/pre&gt;

&lt;h3&gt;スイッチオプションの指定&lt;/h3&gt;

&lt;p&gt;Param に [switch]型の引数を定義すると、スクリプト実行時に該当オプションを引数に渡すと、対応する変数に $true がセットされる。&lt;/p&gt;

&lt;pre class=&quot;brush:ps;&quot;&gt;
Param(
  [switch] $backup,
  [switch] $restore,
  [string] $database=&quot;&quot;,
  [string] $server=$env:computerName,
  [string] $file=&quot;&quot;,
  [string] $directory=&quot;&quot;,
  [switch] $help,
  [switch] $debug
)
&lt;/pre&gt;

&lt;p&gt;上のように書いた場合...&lt;/p&gt;

&lt;pre class=&quot;brush:ps;&quot;&gt;
PS&gt; .\Backup-Database.ps1 -Backup
&lt;/pre&gt;

&lt;p&gt;↑このように引数を指定すると、$backup に $true がセットされる。引数を指定しなければ $false が入る。&lt;/p&gt;

&lt;p&gt;functionでも同じように[switch]を使用可能。&lt;/p&gt;

&lt;pre class=&quot;brush:ps;&quot;&gt;
function hoge([switch]$a){
  if( $a ){
    Write-Host &quot;foo&quot;
  }else{
    Write-Host &quot;bar&quot;
  }
}

hoge -a   # &gt;foo
hoge      # &gt;bar
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazunori-kimura.blogspot.com/feeds/1389522338266180762/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://kazunori-kimura.blogspot.com/2012/05/powershellsqlserver.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/1389522338266180762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4562980847459588265/posts/default/1389522338266180762'/><link rel='alternate' type='text/html' href='http://kazunori-kimura.blogspot.com/2012/05/powershellsqlserver.html' title='PowerShellでSQLServerのデータベースのバックアップ/リストアを行うスクリプト'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03339746898755745994</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>