Sharing typescript code between two projects in a monorepo (just the same as locally) - lerna

Iv been playing around with attempting to share code between two repos, so i understand the monorepo approach using lerna & yarn workspaces.
But take this example:
Lets say I have 2 react projects within a monorepo. And they share code, lets say they share:
components, utils, modules, redux reducers/actions
Why is it i cannot create a 'shared folder' and then be able to import these modules just like i would locally.
import LoginComponent from '#shared/components/login/LoginComponent'
From my understanding its not possible to do like the above? As you lose the folder structure from importing the #shared repo and have to export everything inside an index
So i guess i could add a package.json at the root of #shared/* but then i only have the one tier directory for structure.
It seems a little odd to not be able to simply be able to import from a shared directory between projects in a monorepo? Is this for any reason or am i missing something?
Or is there anything wrong with then importing the code like:
import LoginComponent from '../../../shared/components/login/LoginComponent'
?
Where shared will be within /packages

You can do that actually. I have done it with react typescript project. You can check this implementation here. http://devwithabhi.com/setting-up-react-typescript-monorepo-with-lerna/

Related

managing hardcoded import paths

In Go, it is common that some packages are versioned. So a program might look like this:
package main
import (
"github.com/go-gl/gl/v3.3-core/gl"
"github.com/go-gl/glfw/v3.2/glfw"
)
// ... do stuff
Sometimes, I might want to update the version of glfw. Lets imagine GLFW 3.3 bindings come to Go and I want to update from 3.2.
I might have multiple Go files in a project all using glfw. I don't want to go into each of them and update the version of the import by hand. Ideally I wouldn't be copying that long path around, either, and I could define it in one place per project.
Maybe I could write a script to find+replace "github.com/go-gl/glfw/v3.2/glfw"
Maybe I could template the file with Genny
Maybe I could create a symlink inside the root Go path "glfw" -> "github.com/go-gl/glfw/v3.2/glfw", update it when changing version, and just use import "glfw"
but this information then lives "outside" the project, so no-one cloning my project knows what version to use
but this is a global change and I might have multiple projects which want to depend on different versions
Ideally I would be able to do something like this in each source file:
package main
import (
$gl
$glfw
)
And in some project-level dot file, something like:
gl=github.com/go-gl/gl/v3.3-core/gl
glfw=github.com/go-gl/glfw/v3.2/glfw
Or, a command-line argument attached to go build defining constants that could look something like:
go build -Dgl=github.com/go-gl/gl/v3.3-core/gl -Dglfw=github.com/go-gl/glfw/v3.2/glfw
How is everyone else handling this currently?
See github.com/golang/go/wiki/Modules for the recommended way of managing package versions.

How to update imports when they change location

I see that in Go you can import packages directly from Github like:
import "github.com/MakeNowJust/heredoc"
I understand that the path I am seeing in import line is not an URL, but only the path the package is located in (normally relative to $GOROOT/src/pkg or $GOPATH/src). So the package heredoc is most probably located in the directory $GOPATH/src/github.com/MakeNowJust/heredoc.
Now let's say that the package developer decided to migrate the code repo to Bitbucket. So now the library URL is bitbucket.com/muchMoreCoolerName/heredoc. He also added some new features to the code repo.
My question is how will you get the updated code?
The only solution I can think of is changing all the imports to new URL and doing go get again. But changing the code for library update seems a little inconvenient.
If you just use go get and then import, there is no way around it, you will have to update the import paths to get the new code. However, if you use vendoring(a technique to keep your dependency with your code and also distribute it with them) you would be isolated from that move at least until you update. When you want to update, you could use a vendor functionality to keep the old import path but to sync with the other repo.
Frankly, I'd still use vendoring in anyway and just do a search and replace for the old import path when I decide to update, this is not that hard.
EDIT You can also use dep to manage dependencies if you haven't transitioned to modules yet.

how to organize GO project packages if it will hosted on different repos (GitHub & SourceForge)

Say I want to create a project and host it on GitHub,I HAVE TO create project struct like this:
src/github.com/user/
myproject/
main.go
util/
fileutil.go
and in the main.go ,I have to write the import as:
import github.com/user/myproject/util/fileutil
AND now I also want to host this project onto SourceForge, should I copy the whole project and modify the path ?? it seems not so good enough. Is there any other way to do that ? What I need is just create my project under src folder, and can be hosted to any repo as I wish, without changing the packages.
If developing an app and not a library
If you don't plan to have other projects "import" your own project (this is, if you are implementing an application and not a library), it might be possible for you to avoid any reference to github.com in your local paths.
Note: this is not the recommended approach, but from my tests it does work, you can compile, run and test your code if you structure it this way.
You can create your project structure as follows:
src/
myproject/
main.go
util/
fileutil.go
Then you can import like this:
import "myproject/util/fileutil"
You can then host the contents of the myproject folder anywhere without changing paths within the project files.
If developing a library
If you are actually developing a library others will be able to import, then it gets more complicated since those projects will actually need a full path to import your project.
You can create a "vanity" import path, like myproject.io/... by using the meta tag like described here:
https://golang.org/cmd/go/#hdr-Remote_import_paths
That way, when the go tool queries your myproject.io/ pages, you should respond with a header like this:
<meta name="go-import" content="myproject.io git https://github.com/user/myproject">
And then change that header you return if you decide to move away from github.
Note that this does not prevent users to import your project directly from github, if you want to avoid that you need to use the technique described in the canonical import path spec:
https://golang.org/doc/go1.4#canonicalimports

Golang project structure in an application versus a package

My organization uses Rails to develop its app but I'm attempting to re-write one of our back-end processes in Golang because it's much quicker.
I've structure my application with our company a namespace for my app (example.co), and a subfolder for each of the packages within my app.
Each library that I've included (e.g. sqlx, etc...) also has it's own folder.
src/
github.com/
jmoiron/
(sqlx package files)
example.co
my_app/
(my app package files)
model/
(model package files...)
However looking at other packages like sqlx, it appears they scrap this directory structure entirely and put all their files in the root directory
Is this because I'm writing an application and sqlx is a package that's meant to be included in other applications? Or is it just a difference in preference since there's no real accepted "standard"
I did this too on my first project. I have since learned:
the $GOPATH/bin/ pkg/ src/ layout is constructed by go get and similar commands
you can organize your .go files as a single flat project dir or with subfolders (caveat: all .go files in the same folder must have the same package name)
put other people's code in a /vendor directory inside your project root, if it is code your app needs to work (google this, it's the worst part of go imo)
put your own project under your gopath, symlink to it if you want it more accessible
So I would imagine your code could look something like:
/Users/user2490003/MyGoPath/
▾ src/github.com/user2490003/myproject/
▾ model/
user.go
▾ myapp/
myapp.go
▾ vendor/github.com/jmoiron/sqlx/
sqlx.go
main.go
Import the full package references, like this:
// main.go
package main
import (
github.com/jmoiron/sqlx
github.com/user2490003/myproject/myapp
github.com/user2490003/myproject/model
)
I would recommend to start with a layout that seems logical and works at the present moment and then refactor/restructure as needed when your applications grows and evolves.
Using your company namespace is reasonable - I would consider creating a directory for your app underneath it (such as company.co/my_app) and inside of it, subdirectories for library packages (for example, company.co/my_app/db etc.) as well as the cmd one that would contain directories for the actual executables (package main programs) that you want to produce: cmd/exe1, cmd/exe2 etc. This will allow you to have multiple executables as well as multiple library "subpackages" inside of the my_app which can be included independently with the corresponding import path.
Each library that I've included (e.g. sqlx, etc...) also has it's own folder.
If you are ok with using the latest version of dependencies from Github, you don't have to include the dependencies' code into your repositories but instead install them with go get into the build area. If you want to build from a local copy - and for corporate usage, it may be preferable for stability and audit track - you should put them in a vendor subdirectory, for example company.co/my_app/vendor/github.com/jmoiron/sqlx. This way you have control on when you upgrade to a newer version of the dependencies and assurance that the upstream changes will not break your build or otherwise affect your programs without your knowledge and until you have a chance to do thorough testing.

Organizing and testing a go project

I have been working on a multi-packages project in Go: my project involves several packages for each data structures or algorithms - https://github.com/arnauddri/algorithms
Each package can be tested separately and works fine. I can call any of the package in any other one.
At this stage I have several questions:
is there a way to 'unite' the packages like there is with node, binding all the module under a unique name? Here I would be looking to add a main.go file defining a package 'algo' and I could use any of the underlying packages with algo.heap, algo.queue, algo.stack...
every one of my package has tests and they work fine, however everytime I change a data structure for example, I check in every other package using this one that my tests still pass and that I havent broken anything. How can I make go test work from my root file to launch all the tests?
Any other feedback on my package layout is more than welcome and appreciated :)
Many thanks
There is no language feature that will unite packages.
You can call go test ./... to run all of your tests from your project root.

Resources