Webアプリケーションは、画像、CSSスタイル、JavaScriptスクリプトなどの追加データを使用します。 原則として、これらはWebサーバーのファイルシステムにアプリケーション実行可能コードとは別に保存されます。 しかし、これらの追加リソースが1メガバイト未満の場合、バイナリに直接埋め込みませんか? Webアプリケーションのデプロイを簡単にしましょう!
この記事は、小さいながらも興味深いiptadminプロジェクトのテーマの続きです。
埋め込み
実行可能ファイルへのテキストの埋め込みは簡単なタスクです。 文字列定数を作成するだけで十分です。 実行可能ファイルへのバイナリの埋め込みはもう少し複雑です。
yesod Webフレームワークの 作成 者による ファイル埋め込みライブラリが hackageで見つかりました。
コンパイル段階でghc テンプレートhaskell拡張を使用するこのライブラリは、任意のファイルを読み取り、文字列に変換し、文字列定数に保存し、バイト文字列としてインターフェイスを提供します。 印刷可能な範囲外のコードを持つ文字列は問題なく保存されます。 このアプローチでは、入力/出力に参加せず、コードエディターに表示されません。
ライブラリの作成者は、 embedDir関数の使用を提案しています。 指定されたディレクトリからファイルのリストを受け取り、ファイルの大きなセットを便利に処理するためのペアのリスト(ファイル名、バイト文字列)を作成します。
ただし、それでも、 embedFile関数が使用され、各ファイルに対して個別に呼び出されます( PageHandlers関数 )。 これによりコードの量は増えましたが、プログラムがコンパイルされると、すべてのファイルが確実に利用可能になります。 必要なテストの数が減りました。
リソースへのアクセス
「静的」データにアクセスするためのURLは変更されません。 したがって、アプリケーションのクライアント部分では何も編集する必要がありませんでした。 httpサーバー/静的のルートディレクトリは、別のハンドラーによって処理されます。 ハンドラーは、認証機能の開始時に呼び出されます。 承認手順の前に、ログインページが正しく機能するようにします。
クライアントにHappstackのByteStringファイルを提供するのは非常に簡単です。 Responseデータコンストラクターを使用して、タイプResponseの値を一時的に収集できます。 rsHeadersフィールドにContent-Typeのヘッダーを追加し、rsBodyフィールドに保存されたByteStringを指定します。
ただし、Happstack.Server.FileServe.BuildingBlocksはHappstack 6に含まれており、まさに必要なことを実行します。 strictByteSTringResponse関数は、ByteString、Content-Typeの説明を受け入れ、ファイルをクライアントに返します。 この機能が使用されました。 さまざまなタイプのファイルをクライアントに転送するために、関数returnJs、returnCss、およびreturnPngが書き込まれます。
304
大規模なWebサーバーは、If-Modified-Sinceヘッダーを持つ条件付きGET要求をサポートし、要求されたファイルが最後の呼び出し以降変更されていない場合、空のメッセージ本文で304コードを返します。 この方法は、Webアプリケーションを高速化し、ネットワークトラフィックを削減します。
既にロードされているリソースについては、コード304でクライアントに応答する必要があります。 Responseコンストラクターを使用してクライアントへの応答を手動で組み立てた場合、要求を手動で分析し、最後の要求以降にデータが変更されていないことも確認する必要があります。 Happstack.Server.FileServe.BuildingBlocksモジュールの機能は、この機能を「内部」で実装します。 データ変更の日付と時刻を転送するだけです。
この日付はどこで入手できますか? 明らかに、私たちの場合、「ファイル」の最後の変更の時間はアプリケーションのコンパイル時間になります。 したがって、テンプレートhaskell( updateTime )を使用してコンパイル中に取得します。
問題と解決策
このアプローチにはいくつかの明らかな問題があります。
静的ファイルのみを変更すると、ビルドシステムは静的モジュールを再構築しません。 したがって、再構築を強制するには、 touch Static.hsコマンドを実行してからビルドする必要があります。 自動化のために、 htmlrebuildコマンドがMakefileに追加されました。
さらに、開発サイクルが大幅に増加しています。 JavaScriptプログラムを編集した後、静的アプリケーションモジュールを完全に再構築する必要があります。 その後、それを実行し、その後のみデバッグを開始できます。 この問題は単純に解決されます。開発時には、/静的ディレクトリからファイルシステム内のファイルへのアクセスを有効にする必要があります。 すべてのWebアプリケーションでこれを行う方法。 happstackにより、これは簡単に行われます。 そして、完成したリリースのアセンブリ中にのみ、リソースを実行可能ファイルに埋め込みます。
PS
いつものように、私は批判や他のフィードバックを喜んでいます。
誰かがこのトピックに関する投稿を突然偶然見つけた場合、将来の投稿に興味のあるトピックを提案してください。 この素晴らしいサイトにアカウントがない場合、他の連絡方法があります。