Lessons from open-source: Use nested functions for logic encapsulation and separation of concerns.

Lessons from open-source: Use nested functions for logic encapsulation and separation of concerns.

This lesson is picked from @next/mdx package. In this article, you will learn how next.js source code applies encapsulation and separation of concerns with nested functions in @next/mdx package.

Compile nested inside createFormatAwareProcessors function

createFormatAwareProcessors returns an object with two properties extnames, compile.

compile here is a function that encapsulates processing logic.

You could have just let createFormatAwareProcessors do the processing logic but, context and proximity matter when you write functions and to decide what they (functions) should return. This is why you have ‘extnames’ property returned by createFormatAwareProcessors along with ‘compile’.

By returning a function (compile), the external code using this processor can decide when to call it. It provides a level of abstraction, allowing the external code to control when and how the compilation should occur, giving more flexibility and control.

This design choice makes your code more modular and allows for better organization and reuse of the processing logic.

Conclusion:

You can encapsulate logic in a nested function (function within a function). To have more control over triggering a logic, you can simply return this function along with other properties in the object.

The following is a snippet from nextjs source code, an object returned by createFormatAwareProcessors:

return {
  extnames:
  compileOptions.format === 'md'
  ? mdExtensions
  : compileOptions.format === 'mdx'
  ? mdxExtensions
  : mdExtensions.concat(mdxExtensions),
  compile,
}

I just admire the fact that the compile function is used to encapsulate logic and to create separation of concerns because you might want to put certain logic processing on hold until you reach/meet some criteria.