I try understand how to organize go code using "internal" packages. Let me show what the structure I have:
project/ internal/ foo/ foo.go # package foo bar/ bar.go # package bar main.go # here is the code from main.go package main import ( "project/internal/foo" "project/internal/bar" )
project/
is outside from GOPATH tree. Whatever path I try to import from main.go
nothing works, the only case working fine is import "./internal/foo|bar"
. I think I do something wrong or get "internal" package idea wrong in general. Could anybody make things clearer, please?
UPDATE
The example above is correct the only what I need was to place project/
folder under $GOPATH/src
. So the thing is import path like the project/internal/foo|bar
is workable if we only import it from project/
subtree and not from the outside.
Internal packages are packages which are only intended to be used inside your monorepo. They're extremely useful for sharing code between apps in closed-source monorepos. Internal packages are quick to create, and can be turned into external packages if you end up wanting to publish them to npm .
To create such a package, place it in a directory named internal or in a subdirectory of a directory named internal. When the go command sees an import of a package with internal in its path, it verifies that the package doing the import is within the tree rooted at the parent of the internal directory.
The Internal folder stores intermediate results and configuration files required by SURE during processing. This folder stores the log files usually required when reporting issues to the Customer Success team.
Create a file basic.go inside the basic folder. The file inside the basic folder should start with the line package basic as it belongs to the basic package. Create a file gross.go inside the gross folder. The file inside the gross folder should start with the line package gross as it belongs to the gross package.
With modules introduction in Go v1.11 and above you don't have to specify your project path in $GOPATH/src
You need to tell Go about where each module located by creating go.mod file. Please refer to go help mod
documentation.
Here is an example of how to do it:
project | go.mod | main.go | \---internal +---bar | bar.go | go.mod | \---foo foo.go go.mod
project/internal/bar/go.mod
module bar go 1.14
project/internal/bar/bar.go
package bar import "fmt" //Bar prints "Hello from Bar" func Bar() { fmt.Println("Hello from Bar") }
project/internal/foo/go.mod
module foo go 1.14
project/internal/foo/foo.go
package foo import "fmt" //Foo prints "Hello from Foo" func Foo() { fmt.Println("Hello from Foo") }
project/main.go
package main import ( "internal/bar" "internal/foo" ) func main() { bar.Bar() foo.Foo() }
Now the most important module project/go.mod
module project go 1.14 require internal/bar v1.0.0 replace internal/bar => ./internal/bar require internal/foo v1.0.0 replace internal/foo => ./internal/foo
Couple things here:
go: internal/[email protected]: malformed module path "internal/bar": missing dot in first path element
That is the reason why you need to have replace
where you tell Go where to find it, and that is the key!
replace internal/bar => ./internal/bar
Now, when you execute your code you will have
Hello from Bar Hello from Foo
Here is GitHub link for this code example
The packages have to be located in your $GOPATH
in order to be imported. The example you gave with import "./internal/foo|bar"
works because it does a local-import. internal
only makes it so code that doesn't share a common root directory to your internal
directory can't import the packages within internal
.
If you put all this in your gopath then tried to import from a different location like OuterFolder/project2/main.go
where OuterFolder
contains both project
and project2
then import "../../project/internal/foo"
would fail. It would also fail as import "foo"
or any other way your tried due to not satisfying this condition;
An import of a path containing the element “internal” is disallowed if the importing code is outside the tree rooted at the parent of the “internal” directory.
Now if you had the path $GOPATH/src/project
then you could do import "foo"
and import "bar"
from within $GOPATH/src/project/main.go
and the import would succeed. Things that are not contained underneath project
however would not be able to import foo
or bar
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With