← Back to Home

It's Time to Separate: Own or Delegate?

It's an art to know where to write our own code versus to use someone else's. We don't want to write too much code since we need to maintain them. We also don't want to depend on others' too much, especially given the recent supply chain attacks. Here are 3 examples that show how I struck the right balance.

1. ember-codemod-pod-to-octane

ember-codemod-pod-to-octane, the first codemod that I wrote, ended up simplifying the later ones. To name a few:

Why? It helped me reduce the number of folder structures to consider: The structure is always flat or nested. Never pod. You may ask: There are Ember projects that still colocate route-related files. Shouldn't I support them?

Each case increases how much code I need to write and maintain. I claim that the rate of increase is quadratic (i.e. not linear) due to the combinatorial effect among the options.

Flat and nested already make up 2 cases. Pod creates 2 more, because a project may have set a pod path. So the quadratic rate implies, every codemod I want to write will take 4 times the effort. (Imagine having to support the classic layout, too. Thankfully, there's a codemod for that.)

By focusing on just flat and nested, I have time to write more codemods and to pursue other things in life.

2. ember-codemod-sort-invocations

ember-codemod-sort-invocations standardizes how arguments, attributes, and modifiers are listed in templates.

It's a complete rewrite of ember-template-lint‘s attribute-order, which has a long-standing bug that causes process to hang. In my opinion, no one has been able to fix it because the code had handled formatting by computing character and line positions (hard to understand and change).

ember-codemod-sort-invocations works by delegating formatting to prettier so that it can focus on doing one thing well: Sorting.

The solution uses the same dependency as ember-template-lint, so I could even port the solution as a new rule called sort-invocations. You can integrate sort-invocations into your CI by updating ember-template-lint to 7.9.2 or higher.

3. sublime-syntax-definition-template-tag

For a long time, I didn't have syntax highlighting for *.{gjs,gts} files (files with a <template> tag) since I am the lone user of Sublime Text. One day, I decided to make the plugin myself. It felt daunting cause I had never written one before, never mind understood how syntax highlighting works.

Luckily, Sublime Text already supported composition and inheritance well, and I knew that *.{gjs,gts} files are nothing more than *.{js,ts} files with some Handlebars code inside. Why not reuse the plugins for JavaScript, TypeScript, and Handlebars, whose syntax highlighting has been tested out for years? Indeed, all I had to do was to locate the <template> tags.

GitLab users face a similar issue today. While syntax highlighting occurs when a user views a file in the repository, it doesn't when the user looks at a diff in pull requests. The reason is, GitLab uses a different dependency named rouge for pull requests.

Since there is a small number of GitLab users who use Ember, we can't wait for GitLab to implement syntax highlighting for *.{gjs,gts} in rouge. I believe we can solve the problem on our own if we delegate responsibilities like in sublime-syntax-definition-template-tag.