Template projects and code duplication

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

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

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

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

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

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

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store