43

私は基本的に、html ファイルのフォルダーをたどろうとしています。それらをバイナリ ファイルに埋め込み、テンプレートの実行目的で要求に応じて解析できるようにしたいと考えています。(これを適切に表現していない場合はご容赦ください)。

これを達成するためのアイデア、ヒント、トリック、またはより良い方法は大歓迎です。

// Template Files
type TempFiles struct {
    Files map[string]string
}

// Loop through view files and load them
func LoadTempFiles() {
    t := new(TempFiles)

    // Load template files
    filepath.Walk("application/views", func(path string, info os.FileInfo, err error) error {
    if !info.IsDir() {
        content, _ := ioutil.ReadFile(path)
        t.Files[path] = string(content)
    }
    return nil
    })
}

func ViewTemp(w http.ResponseWriter, path string) {
    t := new(TempFiles)

    temp, err := template.New().Parse(t.Files[path])
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    } else {
        temp.Execute(w, nil)
    }
}
4

4 に答える 4

48

私はほとんどの Go Web アプリでこれを行っています。go-bindataを使用して、埋め込みたいすべてのファイルから Go ソース コードを自動生成し、それらをバイナリにコンパイルします。これはすべて、ビルド中に自動的に行われます。

1 つの欠点は、現在の go ビルド ツールがビルド プロセスにフックする方法を提供しないことです。そのため、この目的のために Makefile を使用します。makefile が呼び出されると、go-bindata必要なすべてのファイルのソースを生成するために実行され、通常、いくつかの追加のコード生成ビットとボブが実行されます (特に、マップ内のすべての埋め込みファイルをリストする Go ソース ファイルの作成..もしそうなら)。次に、実際のプログラムのコンパイルに進みます。

これは少し面倒になる可能性がありますが、一度だけ設定する必要があります。もう 1 つの欠点は、Makefile を使用すると、ソフトウェアがgo getコマンドと互換性がないことを意味することです。しかし、私の Web アプリのほとんどはとにかく共有することを意図していないため、これは今のところ問題にはなっていません。

このようなアプリケーションのデバッグ/開発に関して言えば、静的な Web コンテンツを埋め込むことから生じる別の問題があります。HTML または CSS ファイルを編集してブラウザを更新してその効果を確認することはできません。編集するたびに、サーバーを停止して再構築し、再起動する必要がありました。debugこれは明らかに理想的ではないので、Makefile をandreleaseモードに分割しました。リリースモードは、上で説明したことを行います。ただし、デバッグ モードでは、実際には静的ファイルは埋め込まれません。それぞれのソースファイルを生成しますが、実際のファイルデータを含める代わりに、ファイルシステムからデータをロードするだけのスタブが含まれています。

サーバー コードに関する限り、生成されるコードに違いはありません。関数を呼び出して、特定の静的ファイルの内容をフェッチするだけです。そのコンテンツが実際にバイナリに埋め込まれているかどうか、または外部ソースから読み込まれたかどうかは気にしません。したがって、2 つのビルド モードは自由に交換できます。

たとえば、リリース モードとデバッグ モードで静的ファイルのコンテンツをフェッチするために生成された同じ関数は、次のようになります。

リリースモード:

func index_html() []byte {
    return []byte {
        ....
    }
}

デバッグモード:

func index_html() []byte {
   data, err := ioutil.ReadFile("index.html")
   ...
   return data
}

どちらの場合もインターフェースは同じです。これにより、簡単で心配のない開発とデバッグが可能になります。

于 2012-09-18T18:52:16.347 に答える
18

考慮すべきもう 1 つのツール: もう 1 つの最近の優れたツールはesc から提供されています: Embedding Static Assets in Go ( GitHub リポジトリ)

次のようなプログラム:

  • いくつかのディレクトリを取り、http.FileSystem と互換性のある方法ですべてのファイルを再帰的に埋め込むことができます。
  • オプションで、ローカル開発用のローカル ファイル システムでの使用を無効にすることができます
  • 後続の実行で出力ファイルを変更しません
  • ファイルが変更されたときの適切なサイズの差分があります
  • ベンダーに優しい

ベンダーフレンドリーとは、走っgodepたりパーティーをしたりしても、静的な埋め込みファイルが変更されないことを意味します。これは、サード パーティのインポート (インポート パスが の実行中に書き換えられ、ツール自体が生成するものとは異なるため)、または必要なサード パーティのインポート用に指定可能な場所が含まれ
ていてはならないことを意味します。goimports

ファイルごとに 1 つずつ、gzip された素敵な文字列を生成します。
ローカル開発モードを有効にする単純なフラグがあります。これは、ファイル名からディレクトリ プレフィックスを削除しないほどスマートです (オプションがesc必要になる場合があります)。
出力には必要なコードがすべて含まれており、 との互換性についてサードパーティ ライブラリに依存していませんhttp.FileSystem

于 2014-11-20T07:49:18.043 に答える
1

Go には、これに対するサポートが組み込まれています。

package main

import (
   "embed"
   "os"
)

//go:embed *.html
var content embed.FS

func main() {
   b, e := content.ReadFile("index.html")
   if e != nil {
      panic(e)
   }
   os.Stdout.Write(b)
}

https://golang.org/pkg/embed

于 2021-04-01T20:16:47.863 に答える