Каталог статей серии
Глава 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/Today ee u Wen/Статья…
Указанный сейчас адрес проекта не уверен, имеет ли он какое-либо отношение к первоначальному автору — скорее всего, нет. Тогда это всего лишь одна из многих вилок. Выбрал его просто потому, что он самый активный и имеет наибольшее количество подписчиков. Это может иметь какое-то отношение к тому, что он висит под одноименной организацией, а может быть в нем большая корова.
Причина не имеет значения, просто знайте, что наиболее активным является консенсус, этого достаточно.
цитата не по темеДжей Си chant.info/2020/go-bin…