Übersicht
Dies ist ein grundlegendes Layout für Go-Anwendungsprojekte. Es handelt sich nicht um einen offiziell definierten Standard des Go-Kernentwicklungsteams
; es handelt sich um eine häufig verwendete Verzeichnisanordnung für Community-Go-Projekte.
Wenn Sie Go lernen oder einen Proof of Concept (PoC) oder ein einfaches persönliches Projekt erstellen, ist dieses Projektlayout zu kompliziert. Beginnen Sie stattdessen mit einem wirklich einfachen Layout (nur eine
main.go -Datei und
go.mod is genug).
Wenn Ihr Projekt wächst, stellen Sie sicher, dass Ihre Code-Struktur gut ist, da Sie sonst mit unordentlichem Code enden, der viele versteckte Abhängigkeiten und globalen Zustand enthält. Wenn mehr Menschen am Projekt beteiligt sind, benötigen Sie eine strukturiertere Herangehensweise. In diesem Fall ist es wichtig, einen gemeinsamen Weg zur Verwaltung von Paketen/Bibliotheken einzuführen. Wenn Sie ein Open-Source-Projekt haben oder wissen, dass andere Projekte Code aus Ihrem Projektrepository importieren, werden private (auch als internal
bezeichnete) Pakete und Code wichtig. Klonen Sie das Repository, behalten Sie die Teile, die Sie brauchen, und löschen Sie alles andere! Nur weil es vorhanden ist, heißt das nicht, dass Sie alles verwenden müssen. Keines dieser Muster wird in jedem Projekt verwendet. Selbst das vendor
-Muster ist nicht universell.
Diese Projektstruktur ist absichtlich sehr allgemein gehalten und versucht nicht, eine spezifische Go-Paketstruktur vorzuschreiben.
Spezifikation des Go-Projektverzeichnisses
Nachstehend finden Sie die empfohlene Spezifikation des Go-Projektverzeichnisses.
.
├── go.mod
├── api
├── assets
├── build
├── cmd
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── go.mod
├── init
├── internal
├── pkg
├── scripts
├── test
├── third_party
├── tools
├── vendor
├── web
└── website
Die Bedeutung jedes Verzeichnisses wird unten erläutert.
/cmd
Die Hauptanwendungen für das Projekt, d.h. der Einstiegspunkt der Programme. Die Go-Dateien in diesem Verzeichnis generieren in der Regel ausführbare Dateien. In einem einfachen Projekt kann eine Datei wie /test/main.go
als Einstiegspunkt dienen.
Der Verzeichnisname für jede Anwendung sollte dem Namen der ausführbaren Datei entsprechen, die Sie möchten (z.B. /cmd/myapp
).
Geben Sie nicht zu viel Code im Anwendungsverzeichnis an. Wenn Sie denken, dass der Code importiert und in anderen Projekten verwendet werden kann, fügen Sie ihn in das /pkg
-Verzeichnis ein. Wenn der Code nicht wiederverwendbar ist oder Sie nicht möchten, dass andere ihn verwenden, platzieren Sie ihn im /internal
-Verzeichnis. Sie werden überrascht sein von dem Verhalten anderer Menschen, geben Sie also Ihre Absicht deutlich wieder!
In der Regel gibt es eine kleine main
-Funktion, die Code aus den Verzeichnissen /internal
und /pkg
importiert und aufruft, und nichts anderes.
/internal
Privater Anwendungs- und Bibliothekscode. Dies ist der Code, den Sie nicht möchten, dass andere ihn in ihre Anwendungen oder Bibliotheken importieren. Beachten Sie, dass dieses Layoutmuster vom Go-Compiler selbst durchgesetzt wird. Für genauere Informationen lesen Sie bitte die Versionshinweise für Go 1.4 nach. Beachten Sie, dass dies nicht auf das Top-Level-Verzeichnis internal
beschränkt ist. Sie können mehrere internal
-Verzeichnisse auf jeder Ebene des Projektbaums haben.
Sie können sich dafür entscheiden, eine zusätzliche Struktur für interne Pakete hinzuzufügen, um zwischen freigegebenem und nicht freigegebenem internen Code zu unterscheiden. Dies ist nicht erforderlich (insbesondere für kleinere Projekte), aber die visuelle Darstellung der beabsichtigten Verwendung von Paketen ist eine gute Praxis. Ihr tatsächlicher Anwendungscode kann im Verzeichnis /internal/app
platziert werden (zum Beispiel /internal/app/myapp
), und der gemeinsam genutzte Code für diese Anwendungen kann im Verzeichnis /internal/pkg
platziert werden (zum Beispiel /internal/pkg/myprivlib
).
/pkg
Bibliothekscode, der von externen Anwendungen verwendet werden kann (z.B. /pkg/mypubliclib
). Andere Projekte werden diese Bibliotheken importieren und erwarten, dass sie ordnungsgemäß funktionieren, also überlegen Sie gut, bevor Sie hier Inhalte platzieren :-) Beachten Sie, dass das internal
-Verzeichnis eine bessere Möglichkeit ist, sicherzustellen, dass private Pakete nicht importiert werden können, da es von Go selbst durchgesetzt wird. Das Verzeichnis /pkg
ist dennoch eine gute Möglichkeit, explizit zu vermitteln, dass der Code in diesem Verzeichnis für andere sicher zu verwenden ist.
Wenn Ihr Anwendungsprojekt sehr klein ist und die mehrstufige Verschachtelung nicht viel Wert hinzufügt, ist es auch in Ordnung, sie nicht zu verwenden (es sei denn, Sie möchten es wirklich verwenden :-)). Wenn das Projekt groß genug wird und das Stammverzeichnis sehr beschäftigt wird, sollten Sie dies in Betracht ziehen (insbesondere wenn Sie viele nicht-Go-Anwendungskomponenten haben).
/vendor
Anwendungsabhängigkeiten (manuell verwaltet oder unter Verwendung Ihres bevorzugten Abhängigkeitsverwaltungstools, wie z.B. das integrierte Go Modules
-Feature). Der Befehl go mod vendor
erstellt das Verzeichnis /vendor
für Sie. Beachten Sie, dass Sie, wenn Sie nicht die standardmäßig aktivierten Go 1.14 Version verwenden, möglicherweise den -mod=vendor
-Flag dem go build
-Befehl hinzufügen müssen.
Wenn Sie eine Bibliothek erstellen, sollten Sie Ihre Anwendungsabhängigkeiten nicht commiten.
Dienstanwendungsverzeichnisse
/api
OpenAPI/Swagger-Spezifikationen, JSON-Schemadateien, Protokolldefinitionen und API-Protokollverzeichnisse.
Webanwendungsverzeichnisse
/web
Spezifische Komponenten für Webanwendungen: Assets für statische Websites, serverseitige Vorlagen und Single-Page-Anwendungen (SPAs).
Allgemeine Anwendungsverzeichnisse
/configs
Konfigurationsdateivorlagen oder Standardkonfigurationen.
Platzieren Sie Ihre confd
- oder consul-template
-Vorlagendateien hier.
/init
Systeminitialisierung (systemd, upstart, sysv) und Prozessmanager/Daemon (runit, supervisord) Konfigurationen.
/scripts
Skripte für verschiedene Build-, Installations-, Analyse- und andere Operationen.
/build
Paketierung und kontinuierliche Integration.
Platzieren Sie die Konfigurationen und Skripte für Cloud (AMI), Container (Docker), Betriebssystem (deb, rpm, pkg) im Verzeichnis /build/package
.
Platzieren Sie die Konfigurationen und Skripte für kontinuierliche Integrationstools (Travis, Circle, Drone) im Verzeichnis /build/ci
. Bitte beachten Sie, dass bestimmte kontinuierliche Integrationstools (wie Travis CI) sehr spezifisch hinsichtlich des Speicherorts ihrer Konfigurationsdateien sind. Versuchen Sie, die Konfigurationsdateien im Verzeichnis /build/ci
zu platzieren und verwenden Sie Links, um sie mit dem Speicherort zu verbinden, der von den kontinuierlichen Integrationstools erwartet wird (falls möglich).
/deployments
Bereitstellungskonfigurationen und Vorlagen für IaaS, PaaS, System- und Containerorchestrierung (docker-compose, kubernetes/helm, terraform). Bitte beachten Sie, dass in einigen Repositories (insbesondere für Anwendungen, die mithilfe von Kubernetes bereitgestellt werden) dieses Verzeichnis /deploy
genannt wird.
/test
Andere externe Testanwendungen und Testdaten. Organisieren Sie das Verzeichnis /test
nach Ihren Bedürfnissen. Bei größeren Projekten macht es Sinn, Daten in Unterverzeichnisse zu organisieren. Sie können beispielsweise Verzeichnisse wie /test/data
oder /test/testdata
innerhalb von /test
erstellen, um Go dazu zu bringen, den Inhalt zu ignorieren. Bitte beachten Sie, dass Go auch Verzeichnisse oder Dateien ignoriert, die mit "." oder "_" beginnen, was eine größere Flexibilität bei der Benennung von Testdatenverzeichnissen bietet.
Andere Verzeichnisse
/docs
Entwurfs- und Benutzerdokumentation (außer den von Ihnen generierten godoc-Dokumenten).
/tools
Unterstützende Tools für dieses Projekt. Bitte beachten Sie, dass diese Tools Code aus den Verzeichnissen /pkg
und /internal
importieren können.
/examples
Beispiele für Anwendungen und/oder öffentliche Bibliotheken.
/third_party
Externe Hilfstools, geforkter Code und andere Drittanbieter-Dienstprogrammtools (z.B. Swagger UI).
/githooks
Git Hooks.
/assets
Zusätzliche Assets (Bilder, Logos usw.), die mit dem Repository bereitgestellt werden.
/website
Speicherort für die Daten der Projektwebsite, wenn Sie GitHub Pages nicht verwenden.
/src
Einige Go-Projekte können ein src
-Verzeichnis haben, was jedoch typischerweise darauf zurückzuführen ist, dass Entwickler aus der Java-Welt stammen, wo dies ein gängiges Muster ist. Versuchen Sie, dieses Java-ähnliche Muster zu vermeiden, wenn möglich. Sie möchten wirklich nicht, dass Ihr Go-Code oder Ihr Projekt wie Java aussieht :-)
Verwechseln Sie das projektweite /src
-Verzeichnis nicht mit dem für den Go-Workspace verwendeten /src
-Verzeichnis, das in How to Write Go Code
beschrieben ist. Die Umgebungsvariable $GOPATH
zeigt auf Ihren (aktuellen) Workspace (standardmäßig zeigt sie auf das Verzeichnis $HOME/go
auf Nicht-Windows-Systemen). Dieser Workspace enthält die Top-Level-Verzeichnisse /pkg
, /bin
und /src
. Ihr tatsächliches Projekt wird ein Unterverzeichnis unter dem Verzeichnis /src
sein. Wenn Ihr Projekt also ein /src
-Verzeichnis hat, sieht der Projekt-Pfad so aus: /some/path/to/workspace/src/your_project/src/your_code.go
. Bitte beachten Sie, dass Ihr Projekt ab Go 1.11 außerhalb des GOPATH
liegen kann, aber das bedeutet nicht, dass die Verwendung dieses Layoutmusters eine gute Idee ist.