Go | Пакетирование статических файлов на языке Go и как использовать Go-bindata с Gin

Gin

Каталог статей серии

Глава 1. Упаковка статических файлов в Go и использование Go-bindata с Gin


[TOC]


предисловие

На днях начал учиться разрабатывать внутренний проект на Go, чтобы помочь с некоторыми неудобствами в тестовой среде. Поскольку в разработанном небольшом проекте есть некоторые статические файлы и файлы конфигурации, было обнаружено, что статические файлы не упакованы в исполняемый файл при первой упаковке, поэтому очень проблематично вручную копировать статические файлы при публикации. найдено в некоторых интернет-источникахgo-bindata. Таким образом, я все еще могу распространять только один файл, но упакованный файл будет больше.

1. Что такое go-bindata?

his package converts any file into managable Go source code. Useful for embedding binary data into a go program. The file data is optionally gzip compressed before being converted to a raw byte slice.

It comes with a command line tool in the go-bindata sub directory. This tool offers a set of command line options, used to customize the output being generated.

go-bindata инкапсулирует любой файл в исходный код языка Go. При преобразовании данных файла в необработанные байты вы можете использовать сжатие gzip. В то же время он предоставляет унифицированный интерфейс для получения исходных данных файла.

2. Используйте шаги

1. Установка

go get -u github.com/jteeuwen/go-bindata/...

2. Используйте

использоватьgo-bindata --helpУзнайте, как его использовать

go-bindata --help
Usage: go-bindata [options] <input directories>

  -debug
        Do not embed the assets, but provide the embedding API. Contents will still be loaded from disk.
  -dev
        Similar to debug, but does not emit absolute paths. Expects a rootDir variable to already exist in the generated code's package.
  -fs
        Whether generate instance http.FileSystem interface code.
  -ignore value
        Regex pattern to ignore
  -mode uint
        Optional file mode override for all files.
  -modtime int
        Optional modification unix timestamp override for all files.
  -nocompress
        Assets will *not* be GZIP compressed when this flag is specified.
  -nomemcopy
        Use a .rodata hack to get rid of unnecessary memcopies. Refer to the documentation to see what implications this carries.
  -nometadata
        Assets will not preserve size, mode, and modtime info.
  -o string
        Optional name of the output file to be generated. (default "./bindata.go")
  -pkg string
        Package name to use in the generated code. (default "main")
  -prefix string
        Optional path prefix to strip off asset names.
  -tags string
        Optional set of build tags to include.
  -version
        Displays version information.

Общая структура этого проекта выглядит следующим образом.

├── conf
│   └── app.ini
├── main.go
├── routers
│   └──  router.go
├── setting
│   └── setting.go
└── template
    ├── css
    │   └── chunk-vendors.c6d02872.css
    ├── favicon.ico
    ├── fonts
    │   └──  element-icons.535877f5.woff
    ├── img
    │   └──  Avatar.41ba4b7a.jpg
    ├── index.html
    └── js
        ├── app.40872d4f.js

Для удобства просмотра и ограниченного места некоторые неактуальные файлы были удалены

При упаковке я хочу/confа также/template, упакованный в сгенерированный файл

Самый простой способ использовать этоgo-bindata <input directories>Здесь мы все используем параметры по умолчанию, которые создадутbindata.goИ сгенерированные файлы помещаются под основной пакет в корневой каталог

go-bindata template/... conf/...

Если вы хотите изменить окончательное сгенерированное имя файла и имя пакета, вы можете использовать-oа также-pkgпараметры, поэтому файл assets.go создается под активом, а пакет является активом

go-bindata -o=asset/asset.go -pkg=asset template/... conf/...

3. Прочитайте файл

3 Получает информацию файла, создаваемой методом, описанным выше, содержащимся в файле Asset.go

  • func Asset(name string) ([]byte, error) Загрузить файл в соответствии с именем файла и вернуть байт
  • func AssetNames() []string возвращает список всех файлов
  • func AssetInfo(строка имени) (os.FileInfo, ошибка) возвращает информацию о файле

Если вы посмотрите на исходный файл, вы увидите_bindataИнформация о файлах, хранящихся в

var _bindata = map[string]func() (*asset, error){
	"template/css/app.ee8ee5dd.css":              templateCssAppEe8ee5ddCss,
	"template/favicon.ico":                       templateFaviconIco,
	"template/fonts/element-icons.535877f5.woff": templateFontsElementIcons535877f5Woff,
	"template/img/Avatar.41ba4b7a.jpg":           templateImgAvatar41ba4b7aJpg,
	"template/index.html":                        templateIndexHtml,
	"template/js/app.40872d4f.js":                templateJsApp40872d4fJs,
	"conf/app.ini":                               confAppIni,
}

Если мы хотим прочитать файл conf/app.ini, мы можем использовать

conf_ini, _ := asset.Asset("conf/app.ini")

Эта простая операция выполняется

3. Используйте с джином

При обычном использовании Gin мы обычно настраиваем использование статических ресурсов следующим образом.

r := gin.Default()

r.LoadHTMLGlob("template/index.html")
r.Static("/css", "./template/css")
r.Static("/fonts", "./template/fonts")
r.Static("/img", "./template/img")
r.Static("/js", "./template/js")
r.StaticFile("/favicon.ico", "./template/favicon.ico")

// 首页
r.GET("/", func(c *gin.Context) {
	c.HTML(http.StatusOK, "index.html", nil)
})

Чтобы использовать упакованные статические ресурсы, нам нужно упаковать и настроить по-другому.

1. Пакет с go-bindata-assetfs

Serve embedded files from go-bindata with net/http.

go-bindata-assetfs реализует http.FileSystem, чтобы помочь нам лучше использовать сгенерированные файлы в http-сервисах.

2. Установите go-bindata-assetfs

Эта потребность иgo-bindataУстановить вместе, если уже установленоgo-bindataнет необходимости устанавливать снова

go get github.com/go-bindata/go-bindata/...
go get github.com/elazarl/go-bindata-assetfs/...

3. Упаковать файлы

Здесь нам просто нужноgo-bindataзаменить go-bindata-assetfsВот и все, оба используются одинаково

go-bindata-assetfs -o=asset/asset.go -pkg=asset template/... conf/...

4. Реконфигурация

r := gin.Default()

fsCss := assetfs.AssetFS{Asset: asset.Asset, AssetDir: asset.AssetDir, AssetInfo: asset.AssetInfo, Prefix: "template/css", Fallback: "index.html"}

fsJs := assetfs.AssetFS{Asset: asset.Asset, AssetDir: asset.AssetDir, AssetInfo: asset.AssetInfo, Prefix: "template/js", Fallback: "index.html"}

fsFonts := assetfs.AssetFS{Asset: asset.Asset, AssetDir: asset.AssetDir, AssetInfo: asset.AssetInfo, Prefix: "template/fonts", Fallback: "index.html"}

fsImg := assetfs.AssetFS{Asset: asset.Asset, AssetDir: asset.AssetDir, AssetInfo: asset.AssetInfo, Prefix: "template/img", Fallback: "index.html"}

fs := assetfs.AssetFS{Asset: asset.Asset, AssetDir: asset.AssetDir, AssetInfo: asset.AssetInfo, Prefix: "template", Fallback: "index.html"}

r.StaticFS("/css", &fsCss)
r.StaticFS("/fonts", &fsFonts)
r.StaticFS("/img", &fsImg)
r.StaticFS("/js", &fsJs)
r.StaticFS("/favicon.ico", &fs)

r.GET("/", func(c *gin.Context) {
	c.Writer.WriteHeader(200)
	indexHtml, _ := asset.Asset("template/index.html")
	_, _ = c.Writer.Write(indexHtml)
	c.Writer.Header().Add("Accept", "text/html")
	c.Writer.Flush()
})

о

fs := assetfs.AssetFS{Asset: asset.Asset, AssetDir: asset.AssetDir, AssetInfo: asset.AssetInfo, Prefix: "template", Fallback: "index.html"}

в:

Prefix: "template"удалить при запросе файловtemplateпрефикс, например, исходный путь к файлу"template/css/app.ee8ee5dd.css" => /css/app.ee8ee5dd.cssУдобно соответствовать фронтенд запросам

Fallback: "index.html"Это означает, что если запрос не может быть найден, он будет возвращаться по умолчаниюindex.htmlфайл, потому что префикс настроен, то, что должно быть возвращено здесь, должно бытьtemplate/index.html

5. Ежедневное развитие

В ежедневной разработке нет необходимости перегенерировать assets.go без изменения статического файла.В настоящее время мы можем использовать-debugШаблон генерирует файл assets.go, так что файл доступа по-прежнему является реальным используемым файлом.

go-bindata-assetfs -debug -o=asset/asset.go -pkg=asset template/... conf/...

Суммировать

пройти черезgo-bindataа такжеgo-bindata-assetfs, мы можем упаковать статические файлы и, наконец, предоставить единый файл дистрибутива, упрощая развертывание и использование.

не по теме

Упомяните некоторые повороты перед проектом go-bindata.

Если вы будете искать статьи go-bindata, то обнаружите, что адреса проектов, на которые указывают более ранние статьи, часто бывают такими:GitHub.com/todayee uwen/go…. Это самый ранний адрес проекта, а jteeuwen — учетная запись первоначального автора Джима Тиувена.

Но я не знаю, когда и по какой причине первоначальный автор закрыл проект и даже удалил аккаунт jteeuwen. (Судя по существующим подсказкам, это примерно 2018 год)

Теперь исходный адрес также имеет проект, но он больше не является исходным проектом и больше не поддерживается. Именно тогда кто-то обнаружил, что после удаления go-bindata, чтобы предотвратить сообщения об ошибках в проектах, которые зависели от него, они перерегистрировали учетную запись jteeuwen и повторно разветвили проект (исходный проект был удален и разветвлен). от вилки). Поскольку первоначальное намерение состоит в том, чтобы позволить определенному проекту продолжать работу (говорят, что это частный проект, который нельзя изменить, поэтому он не может указывать на новый адрес), и он не намерен продолжать обслуживание и не хочет притворяться исходным проектом, поэтому этот проект установлен в архив (только для чтения). Подробности см. в следующем обсуждении:

GitHub.com/todayee uwen/go…

GitHub.com/Today ee u Wen/Статья…

Указанный сейчас адрес проекта не уверен, имеет ли он какое-либо отношение к первоначальному автору — скорее всего, нет. Тогда это всего лишь одна из многих вилок. Выбрал его просто потому, что он самый активный и имеет наибольшее количество подписчиков. Это может иметь какое-то отношение к тому, что он висит под одноименной организацией, а может быть в нем большая корова.

Причина не имеет значения, просто знайте, что наиболее активным является консенсус, этого достаточно.

цитата не по темеДжей Си chant.info/2020/go-bin…

Ссылаться на