J'ai des problèmes avec le nouveau système de modules de go, car j'aimerais définir un module local et l'importer dans le programme principal. Le paquet local réside dans un dossier du dossier paquet/racine principal. Imaginez la structure de projet suivante en dehors de la $GOPATH
.
./main.go
package main
import "fmt"
import "example.com/localModule/model"
func main() {
var p = model.Person{name: "Dieter", age:25}
fmt.Printf("Hello %s\n", p.name)
}
./model/person.go
package model
type Person struct {
name string
age int
}
Dans le dossier racine, j'ai initialisé un module en appelant
go mod init example.com/localModule
Dans le model/
dossier j’ai ensuite initialisé le sous-module en appelant
go mod init example.com/localModule/model
Dans le dossier racine appelant les commandes suivantes, échouez.
$ go get
go build example.com/localModule/model: no Go files in
$ go build
main.go:4:8: unknown import path "example.com/localModule/model": cannot find module providing package example.com/localModule/model
Le message d’erreur pour go get est coupé, je ne l’analyse pas à tort.
Je n’envisage pas de transférer le module sur un serveur et j’avais besoin d’un moyen de référencer le paquet local model
, j’ai donc choisi example.com/localModule/
et example.com/localModule/model
respectivement.
J'utilise go1.11 darwin/AMD64
sur un Macbook sous MacOS 10.13.6.
Vous pouvez avoir des "sous" modules locaux comme vous le demandez en ajoutant une instruction require et une instruction de remplacement correspondante avec un chemin de fichier relatif dans go.mod.
Dans la "racine" ./go.mod:
module example.com/localModule
require example.com/localModule/model v0.0.0
replace example.com/localModule/model v0.0.0 => ./model
Vous obtenez cette erreur parce que vous avez défini deux modules qui ne savent pas comment se trouver l'un sur l'autre sur votre disque local.
$ go build
main.go:4:8: unknown import path "example.com/localModule/model":
cannot find module providing package example.com/localModule/model
replace
Vous pouvez ajouter une directive replace
au module go.mod
fichier, tel que:
replace example.com/localModule/model v0.0.0 => ./model
ce qui permet au module supérieur de trouver l’autre module sur le disque. Ceci est couvert plus en détail dans la section remplacez FAQ et "Référentiels multi-modules" sur le wiki des modules.
Cependant, il s’agit d’une solution plus complexe, qui peut s’avérer difficile à mettre en place, qui demande généralement plus de travail et dont certaines limitations, telles que replace
est ignorée pour tous les modules, à l’exception du module actuel. Pour la plupart des gens, un référentiel multi-modules n'est probablement pas ce qu'ils veulent. Il est relativement rare à ce stade d'avoir réellement besoin de plusieurs modules dans un même référentiel.
Bien qu'il soit possible d'utiliser une directive replace
, la solution la plus courante et la plus simple est:
go.mod
fichier dans votre référentiel, etgo.mod
fichier à la racine de votre référentiel.C'est une solution très simple, et cela signifie que vos deux paquets dans le référentiel pourront se trouver automatiquement sans avoir besoin de replace
, ce qui évite le message d'erreur que vous avez signalé.
replace
avec référentiel multi-module, vs référentiel à module unique?Russ Cox a commenté dans # 26664 :
Pour tous les utilisateurs sauf les utilisateurs expérimentés, vous voudrez probablement adopter la convention habituelle selon laquelle un référentiel = un module. Il est important pour l'évolution à long terme des options de stockage de code qu'un référentiel puisse contenir plusieurs modules, mais ce n'est certainement pas quelque chose que vous souhaitez faire par défaut.
Si vous voulez plutôt que plusieurs modules soient définis dans un même référentiel, il y a beaucoup de nuances sur la façon de le faire correctement, et il y a une section section entière du wiki de Modules à lire. comment gérer la complexité associée à plusieurs modules dans un même référentiel, y compris ce conseil:
Ajouter des modules, supprimer des modules et gérer des versions avec plusieurs modules dans un même référentiel requiert une attention et des délibérations considérables. Il est donc toujours plus simple et plus simple de gérer un référentiel à module unique plutôt que plusieurs modules dans un référentiel existant.