Visual StudioでTypeScriptの静的検証ツールtslintを導入する方法
TypeScript始めました。C#erだと1日あればすらすら書けるんじゃないでしょうか。躓いたのは読み込み順序*1とかthisの扱い*2とかJavaScript的な部分。知識として必要になってくるのも、むしろJavaScript。というか、本質的にそう。
環境
- Visual Studio 2013 update 4
- TypeScript 1.4
- Web Essentials 2.5.4
tslint とは
「書き方がルールと違うんじゃないの?」と常々指摘してくれるツールです。
余談ですが、勉強会よりもOJTよりも何よりも成長効果があるなと実感中*3。そして無料。無料、大事。同じく検証してくれるReSharperは有料だから……*4
Visual StudioでTypeScriptの静的検証ツールtslintを導入する方法
話はシンプル。拡張機能「Web Essentials」をインストールする。
Web Essentials for Visual Studio
tslintのルールを定義する
tslintの検証のルールはtslint.jsonで定義されていますが、これについてもWeb Essentialsで可能です。メニュー経由で"C:\Users\[user name]\tslint.json"を編集できます。
ルールの意味もちゃんと表示されるので安心です。
ただし、このままだとファイルのパスの通り個人設定なので、保存は[名前を付けて保存]からソリューションファイルと同じ階層に保存しましょう。そうするとソリューション単位に設定できます。ソース管理を使用しているのであればtslint.jsonも一緒に管理すると管理、共有ができて良いです。
オススメのルール
基本はデフォルトのままで十分ですが、いくつか好きなルールを追加しました。
- member-ordering
- no-switch-case-fall-through
- etc...
好みの tslint.json(Web Essentials 2.5.4時点のすべての rules)
デフォルトをコミットしてからカスタムをコミットしたので何を変えたのかは差分を見てください。
Visual Studioのフォーマット機能(CTRL + K,D)に合わないspaceの制約を消したりもしました。
おまけ:Productivity Power Toolsが便利
拡張機能「Productivity Power Tools」をインストールすると、エラー一覧の情報をソリューションエクスプローラー上に破線、吹き出しで反映してくれます。tslintがファイルを開いている時しか反応してくれずエラー一覧では見落としがちなので助かっています。
Productivity Power Tools 2013 extension
他にもMatch Margin機能がめちゃくちゃいいですね。選択してるワードと同じワードをハイライトしてくれます。Scrollbar markers機能でスクロールバー上でもハイライトされるのが最高。
×構文解析、○静的検証(2015/02/17 追記)
記事投稿時、tslintそのものを構文解析ツールと表現していたのですが、tsコンパイラが解析した構文木を利用した静的な検証だよとご指摘いただきました。
@KatsuYuzu @AntiBayesian 構文解析というと、通常ソースコードをコンパイルする時の1過程を指します。tslintは構文解析した後のデータをさらに分析して"きな臭さ"を検出するツールです。一般には"静的解析ツール"と呼ばれるように思います。
— わかめ@TypeScriptカッコガチ (@vvakame) February 16, 2015
@vvakameさん、ありがとうございます&すいませんでした*5。
@vvakameさんの本、基礎はもちろん、こうした開発環境や言語仕様など一歩踏み込んだ内容まで書かれていましたのでオススメです。
TypeScriptリファレンス Ver.1.0対応【委託】 - 達人出版会
参照
ASP.NET MVC の ActionFilter でレガシー IE でのファイルダウンロードの文字化け、不具合と戦う #aspnetjp
この記事はASP.NET Advent Calendar 2014 - Qiitaに参加しています。12日目の担当です。空いていたので登録しました。明日以降もまだ空いてますよ!(デジャブ)
前日はid:hagi44さんでした。
ASP.NET MVC の ActionFilter でレガシー IE でのファイルダウンロードの文字化け、不具合と戦う
ちょうど前日の方と同じく ActionFilter のお話です。
レガシー IE(ここでは IE8 以下ということにしておきます)向けにファイルのダウンロードを実装しようとすると実は結構大変です。闇。
- SSL(HTTPS)でファイルのダウンロードができない場合 - [PHP + PHP] ぺんたん info
- ファイルダウンロード時のファイル名が文字化けする対処法 - [PHP + PHP] ぺんたん info
この時代にもういいのでは……感はありますが、せやかて、エンタープライズ。文字化けやらダウンロードできないやら。主に Response の Header をごにょごにょすることで戦っていきます。
SSL(HTTPS) でダウンロードできない
これは IE8 以下で no-cache のときに一切の保存ができなくなることが原因です。
ダウンロードすることができません。
Internet Explorer でこのサイトを開くに失敗しました。要求されたサイトがいずれか使用できないか、または見つからない。後でもう一度やり直してください。
キャッシュ コントロール ヘッダーでは、SSL を使用した Internet Explorer のファイルをダウンロードが機能しません。
サクッと消してしまいましょう。
// #################### // # Download will fail when the ssl and no-cache. // #################### var cacheControl = response.Headers["Cache-Control"]; if (!string.IsNullOrEmpty(cacheControl)) { response.Headers["Cache-Control"] = RemoveNoCache(cacheControl); } var pragma = response.Headers["Pragma"]; if (!string.IsNullOrEmpty(cacheControl)) { response.Headers["Pragma"] = RemoveNoCache(pragma); }
private static readonly Regex NoCacheRegex = new Regex(@" ?no-cache,?", RegexOptions.Compiled); private static string RemoveNoCache(string cache) { // no-cache の指定を削除 return NoCacheRegex.Replace( cache, _ => string.Empty); }
ちなみに no-cache はグローバルのフィルターで入れています。
ファイル名が文字化けする
これは IE8 以下で RFC 6266(RFC 2231/RFC 5987)をサポートしていないことが原因です。
どういうことかっていうとファイル名をエンコードして filename*=UTF-8'' 形式で付加できるのが最新仕様なんですが、それを解釈できないので filename= 形式が必要です。それらの属性がない場合は Request を送る時の URL の末尾がファイル名になります。
ASP.NET MVC の FileResult では英数字の時は filename、そうではない時はエンコードすると使い分けているようで、この問題にぶち当たります。
こちらもサクッと置換します。
// #################### // # Not supported RFC 6266 (RFC 2231/RFC 5987). // #################### var contentDisposition = response.Headers["Content-Disposition"]; if (!string.IsNullOrEmpty(contentDisposition)) { response.Headers["Content-Disposition"] = ReplaceFileName(contentDisposition); }
private static readonly Regex FileNameRegex = new Regex(@"filename(\*)?=""?(UTF-8'')?([^;""]+)""?;?", RegexOptions.Compiled); private static string ReplaceFileName(string contentDisposition) { // filename*=UTF-8'' 形式を filename= 形式に置換 // 空白がエンコードされていないので置換 return FileNameRegex.Replace( contentDisposition, x => string.Format(@"filename=""{0}""", x.Groups[3].Value.Replace(" ", "%20"))); }
ActionFilter
これらを愚直に書いていたらロジックの汚染が始まるので ActionFilter で処理しましょう。OnResultExecuted で処理することで FileResult の処理が終わった後をハンドルできます。
public class CompatibleFileResultAttribute : ActionFilterAttribute { public override void OnResultExecuted(ResultExecutedContext filterContext) { // 先ほどの諸々の処理 } }
ActionFilter を使う側はシンプルそのものです。通常と同じ関数が使用できます。
public class HomeController : Controller { [CompatibleFileResultAttribute] public ActionResult File(string name) { var fileName = Server.MapPath(@"~/App_Data/sample.txt"); return File(fileName, "application/octet-stream", name); } }
結果
やったね!
レガシー IE 以外にも倒さないといけない相手がいるかもしれませんが、同じアプローチで攻略できますね。
参照
- SSL(HTTPS)でファイルのダウンロードができない場合 - [PHP + PHP] ぺんたん info
- キャッシュ コントロール ヘッダーでは、SSL を使用した Internet Explorer のファイルをダウンロードが機能しません。
- ファイルダウンロード時のファイル名が文字化けする対処法 - [PHP + PHP] ぺんたん info
- 久しぶりの技術ネタ。HTTPレスポンスヘッダの[Content-Disposition]について、Safariでの日本語文字化け対策など。 - maachangの日記
- modern.IE
- ASP.NET MVC でブラウザにページをキャッシュさせない方法 - しばやん雑記
ASP.NET の customErrors、IISの httpErrors #aspnetjp
この記事はASP.NET Advent Calendar 2014 - Qiitaに参加しています。10日目の担当です。空いていたので登録しました。明日以降もまだ空いてますよ!
前日は@tanaka_733さんでした。
ASP.NET の customErrors、IISの httpErrors
ハマった & 毎回ぐぐるのでメモ。
ASP.NET と IIS のエラーについては@shibayanさんの記事を毎回ぐぐるので、先に紹介します。
9割は記事の紹介で済んでしまっているんですが、いろんな要素がミルフィーユのように重なっている部分なので、一つポカミスをやらかしていると途端に迷走します。軽くおさらいしながらポカミスの回避を紹介します。
ASP.NET
ASP.NET のエラーは customErrors でカスタマイズできます。
<system.web> <customErrors mode="RemoteOnly"> <error statusCode="404" redirect="~/Error?source=MVC&statusCode=404"/> <error statusCode="500" redirect="~/Error?source=MVC&statusCode=500"/> </customErrors> </system.web>
HandleErrorAttribute の確認
この時、グローバルフィルターで HandleErrorAttribute が設定されていないか確認してください。HandleErrorAttribute が設定されていると例外発生時にハンドルされ Error という View が返されてしまいます。
IIS
IIS のエラーは httpErrors でカスタマイズできます。
<system.webServer> <httpErrors errorMode="Custom"> <remove statusCode="404"/> <remove statusCode="500"/> <error statusCode="404" path="https://localhost:xxxxx/Error?source=IIS&statusCode=404" responseMode="Redirect"/> <error statusCode="500" path="https://localhost:xxxxx/Error?source=IIS&statusCode=500" responseMode="Redirect"/> </httpErrors> </system.webServer>
(2015/05/23 追記)上記サンプルにて"../Error……"としていましたが、この場合、パス階層を変えて404を出すと無限にパスを探しに行って最終的にIISの別の例外が飛んできます。設置環境に合わせてURLを指定するのが正解です。config切り替えなどで実現するといいですね。
パスの指定の仕方については次の「パスの確認」の項を確認してください。
パスの確認
この時、path と responseMode に注目してください。responseMode によって path に指定する値が相対パスなのか絶対パスなのか変わります。
デバッグでも本番環境に合わせて仮想ディレクトリを設定しておくとデプロイ後の不具合がないかと思います。
IIS のセットアップの確認
さらに、ローカルの IIS で確認している場合、最大の罠(ただのポカミス)がありました。IIS でカスタムエラーを表示するには [Windows の機能] から [インターネット インフォメーションサービス] > [World Wide Web サービス] > [HTTP 共通機能] > [HTTP エラー] を有効にする必要があります。
これが有効になっていない場合、うんともすんとも言わずに IIS の標準のエラーが表示されます。私はこれが有効になっておらず、何か誤解しているのではないかと環境を疑わずにソース修正とデバッグをしていてかなりハマりました……。
デバッグ環境の構築
以前にこんなポカミス(SSL で挙動が変わる部分を非 SSL でデバッグしていた)もしていたわけですが、デバッグ環境は必ず本番環境に合わせてください。
IIS Express
IIS Express で SSL と仮想ディレクトリを使う方法を紹介しておきます。
まず、プロジェクトのプロパティウィンドウで [SSL 有効] を設定します。[SSL URL] をコピーしておいてください。
次に、プロジェクトのプロパティ画面で先ほどコピーしておいた URL を張り付けて、ディレクトリの URL を追加しておきます。
こうすることで、IIS Express でも SSL や仮想ディレクトリを使ったデバッグができるようになります。
Azure WebSites の利用
Azure が使える状況であれば利用しましょう。
[サーバー エクスプローラー] から WebSites を作成して、すぐに発行できます。
仮想ディレクトリの設定は、Visual Studio では行えないのでポータルへ移動してください。
ところで、Visual Studio の Azure WebSites の設定画面がちゃんと作られていてちょっと驚きました。
サンプル
エラーを発生させるボタンを配置した、カスタムエラーを確認できるサンプルです。KatsuYuzu/aspnet-CustomErrorsSample · GitHub