Template projects and code duplication

Tomas Bjerre
3 min readOct 3, 2020

--

This is my story on how I eliminate code duplication within an organization having many similar applications. I will be talking about frontend projects using NPM, but the solution can be applied to any kind of project.

Scenario

Lets say you are working within an organization. You have 10 teams developing frontend applications. Each application will be deployed on the same website. They provide different features, but share many things like colors, test frameworks, mock objects, general code structure…

You have a “template project” that has all the latest common features.

Whenever you start a new project, you copy that template project and start working from there.

I will be using React Boilerplate as an example of such a template project.

Problem

I would say, the main problem here is maintenance.

The applications typically have different names in package.json and different content in the app folder.

When features are improved in the template project, you want these features applied to all projects that once copied it.

Developers may add features to the applications and not bother adding them to the template project.

Solution

First of all, try to add as much as you can into shared libraries. Let the template project depend on shared packages. But that will not solve everything. You will still have something left in the template project. If you move something to a shared package, the template project will still have to specify that package and version.

Perhaps you want all applications to share the same:

  • .editorconfig
  • .gitattributes
  • .travis.yml

Perhaps you want applications to have supersets of:

  • package.json
  • .gitignore

Create a dictator

I created a concept with a “dictator”. The dictator has “dictatables” that dictates the file system when used in an application. I created a tool that I call dictator-builder, it implements features needed by a dictator. Using that tool I created a dictator, my example here is dictator-react-boilerplate.

The dictator-react-boilerplate contains the entire react-boilerplate template code. It is configured within a dictatable. The dictatable looks something like:

{
"message": "Copy react-boilerplate",
"actions": [
{
"beSupersetOfJsonFile": "react-boilerplate/package.json",
"target": "package.json"
},
{
"copyFrom": "react-boilerplate",
"target": "."
},
{
"haveLineContaining": ["*.tgz"],
"target": ".gitignore"
}
]
}

Which means:

  • Let the package.json in an application be a superset of the package.json in the dictator.
  • Copy all files from folder react-boilerplate to root
  • Add “*.tgz” to .gitignore

Use the dictator

You can run the dictator as a command line tool , if not using NPM:

npx dictator-react-boilerplate

I use the dictator by specifying it in my package.json:

{
"name": "react-boilerplate-example",
"version": "1.2.3",
"description": "asdasasd",
"scripts": {
"prepare": "dictator-react-boilerplate"
},
"devDependencies": {
"dictator-react-boilerplate": "0.0.8"
}
}

This means, when I run npm install, the dictator will be applied and dictate my application.

The dictated application can choose to have control of some parts of the application. In my case I have a .dictatorconfig.json in the root of the application containing:

{
"ignore": [
"/README.md",
"/.github/*",
"/.github/**/*",
"/app",
"/package-lock.json",
"/Changelod.md"
]
}

To use a new version of the template project, I just update the version in my package.json!

Here is an example using this dictator:
https://github.com/tomasbjerre/dictator-react-boilerplate-example

--

--