requirejsで管理してるjsのキャッシュを管理する方法
requirejsはいいツールなんだが初めてjsがキャッシュに残ってしまって更新されなくてどうしたもんかと調べたので記録。
urlArgs
requirejsのconfigにurlArgs
というのがある。
読んで字の通り、requirejsで読み込んだjavascriptファイルのurlのクエリパラメーターに適当なパラメーターを設定できるというもの。
require.config({ urlArgs: 'v=2', paths: { ...
これでファイル更新にともなうcacheの更新が簡単になった。
今後の展望
package.jsonとかのversionみてリリースのタイミングでまとめてversionアップとかできたら、それはとっても素敵だなって
# 参考にしたサイト
HeimdallというjQuery/Zeptoで使えるFormValidatorを書いた話
温泉発火村#2に参加しましたという記事で紹介したライブラリの話をもうちょっと突っ込んで話します。
Synopsis
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> <script src="/js/heimdal.min.js"></script> <script> // validatorのインスタンスを生成 var heimdall = $.heimdall({ "name" : ["required", ["length", [1, 32]]], "age" : ["required", "int"], "gender" : ["required", ["select", ["male", "female"], "message" : [ ["length", [0, 256]]] }); $('.form') .on('submit', function () { var result = heimdall.validate({ "name": $('#input-name').val(), // みたいな感じでフォームのデータを{name: value, }でvalidateに渡す ... }); if (result.has_error()) { // エラーがあったら ... $(this).trigger('invalid', [result]); // エラーだよってイベントのトリガ発火するとか。 } }) .on('invalid', function (e, result) { // エラーを表示するなり、アラートを出すなり、リダイレクトするなり。 });
Heimdallがやること
- データの制約(ルール)の定義と保持
- 与えられたデータが制約に基づくものかの検証
- すべてのデータが制約通りのものかどうかの判定
制約(ルール)の定義
言わずもがな、必須入力、数値入力、E-mail、電話番号その他もろもろ、入力フォームに応じ仕様と照合して「何が正しいデータなのか」を定義するもの。
この制約は、formのnameアトリビュート毎にArrayで制約を定義する。 制約は独自のものを定義することもできる。
heimdal.load_constraints('my_rule', function (value) { // `tamanegi`以外の入力は受け付けない return value === 'tamanegi' ? true : false; });
より柔軟に仕様に対応することができ、またheimdallの拡張も可能。
デフォルトでは、
- requires: 必須入力
- length: 入力文字列の上限・下限を設定できる
- select: 文字列の集合の中に含まれている文字列である
- int: 整数値である
が定義されている。
与えられたデータが制約に基づくものかを検証
いわゆるバリデーションの機能。 与えるデータは、formのnameアトリビュートをキーとしたオブジェクトを期待する。
すべてのデータが制約通りのものかどうかの判定
バリデーションはその結果をResultのオブジェクトとして返す。 これはエラーの有無/エラーの内容を取得することができる。
これは主にForm上でユーザにエラーの内容を表示するために利用する、ことを想定している。
Heimdallの背景
そもそもなんで「ヘイムダル」なのか。北欧神話の神が由来で、巨人の軍勢がビフレストを渡ってアースガルズへ侵攻するのを知らせる、という門番の役割を持ってる、ということから。
WEBサイトのフォームは、CGIの時代から多くのパターンが考慮され、またサイトの仕様に密接に関連している。使い勝手もサイトによって千差万別。
「サーバ側で不適切なデータであれば弾けばいい」というものから、「よりユーザにわかりやすいように」と考慮されたリッチなフォームまで存在する。
2013年において、入力フォームはJavaScriptを用いて多くの場合において逐一サーバーにリクエストを投げなくても正しい/正しくないの判定を行うことができ、かつ柔軟に表示を切り替えるようになっている。それも、端末にさほど負荷をかけずに。(例外はあるけれど
しかし、その実装は非情に面倒でありバリデーションようにライブラリは多くあるけれど、なかなか僕の好みに合うライブラリがなかった。
- バリデーションの制約を拡張できる
- エラーが出た時にその事由を取得し、シームレスにUIへ伝達できる
- jQuery, Zeptoのどちらでもつかえること
- (僕個人としての)直感的なインターフェース
4つめは、単純に気持よくかけるかどうかなんですが・・・
Heimdallはこの辺を指標として実装しました。
Heimdallの目指すトコロ
正直、Heimdallには足りない機能がある。
- formに入力されているデータの取得する機能
- formにエラーを伝達しUIを更新する機能
- 単体のinputに対するバリデーション
formとの連携は、悩んだ結果、Heimdallから外すことにした。formの構造や取得方法は、Heimdallに依存してしまう。汎用性を求めようとすれば、その分ソースが膨らむ。メンテナンスコストも。
なので、それは(formaize)https://github.com/rymizuki/jquery-formizeというライブラリに委譲した。
formizeの構造・機能を許容できるのなら、それによって簡単にデータの取得/更新が可能になる。
単体のinputに対するバリデーションは、今後の課題として今もなお検討中。 なかなか良いアイディが浮かばず悶々としている。
あとがきてきな
さて、なんでこんな記事を書いているかというと、@karupanerura に触発されたというのが一番の理由なんだけれど。
jQueryやHTML5の登場で、リッチなUIの実装はそのハードルは大分下がった。 しかし、それでもまだ「全角数字のみを受け入れるフォーム」「どのinputが間違っているのかわからないエラー」等の実にイケてないフォームは未だ多くある。
わざわざサーバにリクエストしてページを遷移しなくても、そのフォーム、そのページ内でエラーをハンドルできるんだから、通信とか無駄に時間を取って、ユーザ体験を損ねているだけじゃね? って思うことは多々ある。
多々あるが、それでも「じゃあJSで書きなヨー」とは言えない。それなりにコストがかかるし、僕もやっぱりPerlで書いたほうが早いし楽だって思うから。
Heimdallしかり、formizeしかり、僕はそういうハードルを下げたいと思ってる。もっとお手軽に、もっと少ないコードで、もっと素早く実装できるようにしたい。
これらのライブラリは少なくとも僕がストレスに思っていた、あるいはコピペで済ませていたやつを集約して汎用化したものなので、まだまだ至らない点は多くあると思う。 それでも、こうして公開して、自分だったり自分以外の誰かに使ってもらって、コードに対する知見をためて、改善していくことができるのも、いまのWEBがあってこそ。Github万歳ヽ(^o^)丿
何が言いたいかというと、全角数字入力のフォームとかうざいし通信の待ち時間とかストレスでそういうフォームを撃滅したいので簡単に実装にできるようなプラグインのために試してIssueとかぷるりくとか投げたり投げられたりしてだせーWEBサイトを減らしていこうぜ!!!
Heimdall、よろしくお願いします。
――と、SYNOPSIS以降はガリレイドンナ見ながら書いてたのでおかしな文章になってるかもしれないけど、がんばって明日はfromizeの記事を書きたいな! サムライフラメンコ見て寝よう。
Text::Xslateにis_array_ref, is_hash_refはビルトインで入ってる
月一でとあるチャンネルでぼやいてるきがするのでそろそろメモることにした。
$ perldoc Text::Xslate::Manual::Builtin
: if is_array_ref(hoge) { <p>arrayref</p> :}
そんな僕を見た某かるぴす先生から適切なアドバイスを受けた。
$MODULE::Manual 以下はひと通り眺めてからつかうといいよ!
おっしゃるとおりで・・・だが、 忘 れ て し ま え ば 、な ん の 意 味 も な い
ので、日々記録を大切にね。
grunt-init で jquery-plugin を作って travisCIに上げるまでのメモ
準備
以下をインストール
$ npm install -g grunt-init $ git clone https://github.com/gruntjs/grunt-init-jquery.git ~/.grunt-init/jquery
プロジェクトの作成
grunt-init jquery
をプロジェクトディレクトリで走らせるとplugin用のアセットを生成してくれる。
なお、既にルートディレクトリにpackage.json
が存在するとエラーになる模。様l
$ mkdir eg-grunt-init $ cd eg-grunt-init $ grunt-init jquery
生成されたコード
. ├── CONTRIBUTING.md ├── Gruntfile.js ├── LICENSE-MIT ├── README.md ├── eg-grunt-init.jquery.json ├── libs │ ├── jquery │ │ └── jquery.js │ ├── jquery-loader.js │ └── qunit │ ├── qunit.css │ └── qunit.js ├── package.json ├── src │ └── eg-grunt-init.js └── test ├── eg-grunt-init.html └── eg-grunt-init_test.js
とりあえず動かす
なにもオリジナルなコードは書かずに、そのまま動かす。
$ npm install $ npm test
すでにもうテストが動くという親切っぷり。 テストはqunitを使っている。そのまま使うか、mochaでも入れるか、は各自の自由なのかな。 また、jshintも設定されてるので、これに従えばjqueryの規約に沿ったコードになる様子。
サンプルコードは2indentで書かれているが、jshint的には特に規定はなく、そのまま4indentで書いてしまったが、好きに設定して良いのかもしれない。 まあ、minifyするか
pluginを実装する
かく。 テスト通らせる
travisCIに上げる
ここでちょっとあれこれしたのでメモ。
- grunt-cliをinstallする
- デフォルトではgrunt-cliが無いので、
npm install --save-dev grunt-cli
した
- デフォルトではgrunt-cliが無いので、
- vesionかえる
- package.jsonに定義されているversionが
0.0.0-ignored
だったので、npmとれなかった気配 - versionやnpmの流儀についてはちゃんと調べずここまで来ているので、なんか勘違いしてるきもするけど、とりあえず動いたので。
- package.jsonに定義されているversionが
おしまい
grunt-initはべんりだなーって思った。 でもqunitは使いにくい。
あ、あと。jquery-formize on Githubというpluginを書きました。form要素にデータ入れたりデータ取ったりエラーのスタイル当てるのにいい感じにしてくれる子がほしかった。 この子を書くときにgrunt-initに入門したので、色々勉強になった。まる。
plenv install-cpanmをすると~/perl5にcpanmをインストールして困った話
App::cpanminusはインストールディレクトリの決定にオプションとしてのlocal_lib
と環境変数PERL_LOCAL_LIB_ROOT
とPERL_MM_OPT
を参照して決定するようになっている。
僕のMac Book Airさんはたぶん昔にlocal::libをインストールしたりした経緯からか、PERL_LOCAL_LIB_ROOT
及びPERL_MM_OPT
が/User/$user/perl5
になっており、cpanmのインストールがPLENV_ROOTよりも優先されてしまっていたため、何をどうしても、/User/$user/perl5
にcpanmがインストールされ、plenvからcpanmがたたけ無いというこまった事態におちいったのでした。
どこでPERL_LOCAL_LIB_ROOT
とPERL_MM_OPT
がセットされたのかは謎・・・とりあえず、こいつら消したらちゃんとplenvのversionにinstallできたので備忘録として。
追記
Cartonをinstallしたつもりが、また~/perl5にインストールされた。
$ plenv exec cpanm Carton $ plenv exec carton install plenv: carton: command not found $ plenv exec perldoc -l Carton /User/mizuki/perl5/lib/Carton.pm
で、まだなにかあるのかと、環境変数をあさったらPERL_MB_OPT
というのがございましてですね。。。
これもどうやらlocal::lib
系の何からしい。
こいつも潰して、もうないはず。。。
温泉発火村 #2 に参加しました #発火村
概要っぽいの
温泉発火村とは
温泉発火村 #2 : ATNDより抜粋。
温泉発火村とは 温泉でハッカソンしようぜという企画です。まーまー普通のハッカソンです。 ノートPCが持参出来ればだれでも参加出来ます。
温泉でゆったりしつつ美味しいものを食べつつわいわいもくもくハックしようぜ!ってイベントです。
会場について
今回の会場は山木旅館(静岡県熱海) という旅館で、なかなか良い感じでした。あとご飯が美味しかった。ご飯が美味しかった。(大事なことなの(ry
ふりかえり
ご飯美味しかったなぁ・・・お昼ごはんに食べた「あじなどんぶり」。味のぬかづけ?だったろうか、臭みもなくてでも鯵の味がしてて、程よい香りがついてて、一杯では物足りない感じだった。
・・・って考えてるとご飯が美味しかったコトだけで記事埋めちゃうのでこの辺はコンテンツ力ある方々におまかせして。 僕は淡々と作ったものの話をしますよ。
成果物
https://github.com/rymizuki/Heimdall
Heimdal!! キラキラネームを採用したjQuery,Zeptoで使えるFormValidatorモジュールを作りました。 もともとbackbone-validatorというBackbonejs用のValidator書いてたんですけど、弊社開発二部のチャンネル内にて「それBackboneに依存しなくてよくね」ってツッコミもらったので、underscorejsの依存を外して$系とネイティブコードを使ったValidatorに書き換えました。
SYNOPSISとしてはこんな感じ。
// validatorのインスタンスを生成 var heimdall = $.heimdall({ "name" : ["required", ["length", [1, 32]]], "age" : ["required", "int"], "gender" : ["required", ["select", ["male", "female"], "message" : [ ["length", [0, 256]]] }); $('.form') .on('submit', function () { var result = heimdall.validate({ "name": $('#input-name').val(), // みたいな感じでフォームのデータを{name: value, }でvalidateに渡す ... }); if (result.has_error()) { // エラーがあったら ... $(this).trigger('invalid', [result]); // エラーだよってイベントのトリガ発火するとか。 } }) .on('invalid', function (e, result) { // エラーを表示するなり、アラートを出すなり、リダイレクトするなり。 });
みたいな感じでバリデーションに特化したモジュールになっております。 ちょっとJSの流儀であるところの命名規則とか、jQueryの公式が出してるpluginのフォーマットに沿ってない、とかもろもろ後になってから気づいたんだけど。
特にdisが飛んでこなければ僕の好みのままで放置しようかなと。
今後の予定
- ・・・とは言うものの、jQueryのフォーマットには沿わせようかなと。配布の仕組みとかよくしらないし。
- @gfx さんより「キーアップ等のイベントに連動して特定のinputだけvalidationしたいケース」という宿題を提示してもらったので直近のTODOにする。
今回の困ったこと
- 唐突に僕のpocketWifiが初期化されパスワードがわからず @kfly8 の無線LANを借りる事になった。事故にも程がある
- 電源コンセントが辛かったのでタコ足持って行くと良い。
- testemをgrunt-testemからではなく直接叩きたかったがディレクトリ構造の解決がうまくいかず数時間testemの調査で終わってしまった。
- 温泉が気持ちよすぎて、ご飯が美味しすぎて、満足感に浸りすぎて作業にならない
今回の学び
- 熱海素晴らしい
- 熱海のご飯は実に美味しい
- 山木旅館さんは山木茶屋という食事処を併設してて(そこでお昼食べた)そこのご飯も実に、実に美味しかった。 * またいきたい
grunt-init jquery
jsプロジェクトのひな形はコピペで済ましていたんだけど、やっぱりジェネレーター使うべきだなって思った。$.expr[':'].heimdall
jQueryの拡張セレクタは、実は好きに定義することが可能。- Zeptojsには拡張セレクタが無いので、DOM操作周り気をつけないとjQueryでは動くけど、Zeptoだと動かないプロダクトが出来上がる。
- 拡張セレクタが使えないのは結構大きい気もするけど、Form操作がそんなに無いなら大体querySelect系でなんとかなる気もする。
- 海楽しい
まとめ
- Heimdallというバリデーション特化ライブラリを書きました。
- 熱海最高
- 山木旅館飯が美味い
- 温泉発火村はやっぱり最高だぜ!
#yapcasia 2013 に参加しました
9/20, 9/21 とYAPC::ASIA 2013に参加してきました。
参加するのは3回目で、初のLTにも挑戦させていただきました。
備忘録はあとでまとめるとして、ざっくり所感とか次の一年に思うトコロとかを書き留めようかなと。
あとブログ書くまでがYAPCなので。あとブログ書くまでがYAPCなので。
今年はPerlの話題が多かったですね。去年は「あれ、これPerlのカンファレンスだよね?!」ってくらい周辺技術の話が多かった気がするんですけれど(笑)
セッションで増えたなって思ったのは、Perlのテスト、とGit周りの開発フロー/環境の話。
Perlのテストは、「50ms or die」とは言わずとも、どこも時間短縮したいようで。
中規模チャットサービスの運用事例で紹介されたApp::Prove::Plugin::MySQLPoolを使って一つのサーバでMySQLを並列化するっていうのは気になった。
http://yapcasia.org/2013/talk/show/767463b0-d8fd-11e2-971a-72936aeab6a4で紹介されてたテストの手法、並列化や実行手順はもろもろ参考にしたいところでした。
また、PhantomJSやSeleniumを使ってUIをテストするという話もちらほら。
この辺りは概要だけ撫でて詳しく全然追っていなかったので、ちゃんと追いたい。
Gitに関しては、開発フロー、ブランチ戦略とか、各所で微妙に異なる方法を採用してる。
git-flowとかの影響もありつつ、それだけじゃ賄えないよね。だからうちはこうしようとおもう、みたいなものがあるっぽい。
今回のベストトークショーは二年連続しての @yusukebe さんが受賞。おめでとうございます!
Mojoliciousのトークは(一年半くらいまともに触ってない)僕としてはいろいろ忘れてたコトを思い出せてよかった。
敢えてMojoのPluginや機能をModelとかで避けるのは「Web名前空間以外ではMojoに依存したくない」という思いからそういう規約を作っているとのこと。Mojo本体もバージョンアップ速いし、互換性の無いPluginを多数投入しちゃうと、移植とか大変だよね。管理大変だよね。だから、WebはMojoにしつつビジネスロジックの部分はそこから切り離せることができるようにしたい、とのことだった。
トークの後に雑談させてもらって色々と勉強になりました!
Mojoliciousといえば、WAF、WAFといえば、Amon2!!!
Amon2をテーマにしたセッションは少ない(っていうか無かった?)んですけど、いくつかのセッションの中で「Amon2使って」って言葉が聞こえてました。
弊社も使ってます( ー`дー´)キリッ
MojoもいいWAFだけどAmon2もいいWAFなのです。
前回から楽しみにしているPerl6系の話題。
それをPerl5に取り込むモジュールの紹介、今回もいろいろ発掘があったので楽しみたいトコロ。
特にhttp://search.cpan.org/~barefoot/Method-Signatures-20130505/lib/Method/Signatures.pm:Method::Signatures←個人的にはこれがアツい。
他の言語と同じような表記を持ちつつ、しかしPerlの柔軟な引数の受け渡しを残せる。
method/func とで振る舞いが異なるので、明示的にそれらの宣言を示すことができる。
funcとして期待されてるものをうっかりmethod呼び出ししちゃったりその逆だったりが、ソースをぱっと見するだけでわかるんだよ便利!
いや、`$self = shift`してるところで気づけって説はあるんだけども。
明示的にしてくれるのは嬉しいよね。
そんなこんなで語り尽くせないくらい面白い話題がありました。
あ、これメモ見ず思いつきで書いてるんで、メモみたら1周間分くらいに記事になりそうw
@mizuki_rこと僕は初日に初LTしてきました。
・・・まあ、なんだ。うん、次は準備をちゃんとしよう。
反省はもろもろあるけれど、改めて言いたいことは
Web APIのデータアクセスのI/Fを共通化するために書かれたモジュール
TengのI/F(とコード)を参考にしている
なのでDSLでごりごりAPIの仕様的なのを定義できる
データを利用するためのもろもろな厄介事を隠蔽できる
ビジネスロジックには本質的に「データの扱い方」を書くことができる
ってことが言いたかった。言えれば満足できた。言えなかった、後悔している。
突発的自体が発生しても穏やかに、余裕を持って対応できる大人になりたい。そう思った。
https://github.com/rymizuki/p5-Spica
bug潰したらCPANに上げる。予定。
YAPC::ASIA楽しかったです!!!
I Love Perl Communityヽ(^o^)丿ヽ(^o^)丿
お疲れ様でした!