Skip to content

[nx.dev | Angular] Libraries as Git Submodule - DRY Principle

Georg Höller
Georg Höller
4 min read
[nx.dev | Angular] Libraries as Git Submodule - DRY Principle
Photo by Kelly Sikkema / Unsplash

Recently I published a post about my single project workspace structure using nx.dev. I mention that we are able to stick to the DRY principle even if we don't use nx.dev as a mono repo!

[Angular | nx.dev] Single Project Workspace Structure
The concept of a monorepo is great but not always doable because of all sorts of circumstances. For me the critical point always is git - I want each project to have its own repository! But this doesn’t mean you can’t use a monorepo framework for a single project. We

Setup

  • Code Editor - VS Code
  • Monorepo Framework for Angular - nx.dev
  • Project Structure from the previous post

Git Submodules

Submodules are great if you have to use code from another project. Submodules are nothing special  - it's just a git repository in a git repository.
Before i knew that submodules exists I used npm package for this use case. They seem handy if external people will use your code but if it remains inside your company than it's just too much overhead.

Content


New Library To Submodule

In the previous post we created some libraries:

Let's say that my authorization library gh-auth will contain some third party login possibilities (like google login). Would be nice if we don't have to rewrite the code in our next project - right?
If you start over with something new it's easy to create a new submodule because you don't have to handle the git history.

1. New Repository

Create a new git repository (using github.com) on your server/computer with the name of your library and clone it. In my case I called it gh-auth.
git clone <remoteUrl>

2. Add Source

I recommend using the nx CLI for creating libraries because it takes care of all the initial referencing (angular.json).
Create your libraries as usual in your nx.dev project and check if they are working. If you don't know how check my last post.
Afterwards open you explorer and cut out the whole content inside your library folder (gh-auth) and paste it to your newly created repository folder (which has the same name - gh-auth).
Finally commit your changes to your new repository.

git add .
git commit -m "message"
git push

3. Add Submodule

Switch back to your main project and delete the left-behind library folder (gh-auth). Check if both projects are synced and no changes are left.
Now open your git bash in the root folder of your project and add the submodule:
git submodule add remoteUrl local/url/to/gh-auth

If you are using VS code and switch to the source control tab you should now see both repositories:

The folder structure in the libs folder should now look exactly as it did before - just that VS code displays it in another color and adds an S to the end.

💡
When you have to clone a project with an existing submodule in it - don't forget to call git submodule init and git submodule update afterwards. Clone doesn't automatically fetch submodules.
Maybe leave a note for other contributors after you added a submodule.

Existing Library To Submodule

I will use the same example as above for this section. Only difference is that we already have a working library - in my case gh-auth - with a git history which we don't want to lose.

1. Duplicate your project

Clone the repository in which the library is located into a new folder which is called like the final library (gh-auth):
git clone <remoteUrl> local/gh-auth

2. Remove Remote Origin

As we want to create a new repository out of this folder remove the old origin:
git remote rm origin

3. Filter Git History

Now remove the git history except for our library sub folder:
git filter-branch --subdirectory-filter <gh-auth> -- --all

4. Add Origin and Push

Create a new remote repository and add the remote origin to the new folder:
git remote add origin <remoteUrl>
Afterwards you can push to your new repository
git push
If you get an exception you may have to set the upstream branch:
git push --set-upstream origin <branchName>

5. Add Submodule

It's the same like above: Add Submodule

Stackoverflow Reference

AngularDeveloper

Comments


Related Posts

Members Public

[Angular | Storybook] Tailwind, Directives, Content Projection, Icons and i18n

Install packages npm i -D @nx/storybook npm i -D @storybook/angular Create config nx g @nx/storybook:configuration <project-name> I created the config inside the main app to share some configs/modules. My stories are located at libs/shared/ui. That's why I had to

[Angular | Storybook] Tailwind, Directives, Content Projection, Icons and i18n
Members Public

[Angular | RxJS] BehaviorSubject with custom states

Whenever I call an api, often my frontend has to go through some different visualization steps. Imagine you have some kind of search input and a list which displays the results but you want to show an loading indicator, an error hint and something different when the result is empty.

[Angular | RxJS] BehaviorSubject with custom states
Members Public

[Angular] Dynamic App Config and Translations in a Submodule

When I'm setting up a new angular application, I always start with translation support and an external app config json loader. You should never start a new app without an internationalization (i18n) system - even if you only support one language! We are going to use the package

[Angular] Dynamic App Config and Translations in a Submodule