ColdFusion Summit Notes: Making Modules - Utilizing Reusable Code through ColdBox Modules, Eric Peterson

October 04, 2019

What’s A Module?

  • at its simplest: any reusable packaged functionality
  • that’s useless definition, we need more substance
  • a “function” could be a “module”
  • a full on parsing lib could also be a module

So What Defines A Module?

  • modules are reusable.
  • they are versioned, preferably semantically versioned
  • 1.2.3
  • breaking.feature.fix
  • unless the number to the far left changes, i should be able to keep installing updates without my code breaking.
  • modules can depend on other modules
  • modules have dependencies
  • modules are shared on ForgeBox (opinion shared as fact)

Why Use Modules?

  • modules encapsulate complexity
  • easier to test modules, in isolation
  • can enforce coding standards

Do I Need to Use ColdBox To Use Modules?

Benefits of Modules Without ColdBox

  • versioning
  • dependency management
  • installation location by convention (or setting)

What Do I Need to Make A Module?

  • code that’s used across multiple apps, make it a module
  • you need 1 file: box.json
  • describes your module:
  • version
  • dependencies
  • module type
  • installation data
  • package scripts
  • other metadata
  • (very similar to npm’s package.json)

don’t -need- ColdBox but you get super powers with it
ColdBox modules are self-contained ColdBox apps
what does that mean?
full MVC sub-application in each module
models
interceptors (event listeners)
and more

also need a ModuleConfig.cfc file
this is what turns the “module” into a “ColdBox module”
tells ColdBox “I’m a module and this is what you need to do before i can start being used”
“go load these other modules, get this installation data, etc”

common properties:
name - name of your module
entrypoint - the default route into this module (i.e. /api/v1)
cfmapping - adds a mapping of the given name available thru the rest of your app
dependencies - other modules that this one needs in order to run
autoMapModels - auto wire Models up via WireBox

ModuleConfig.cfc methods
configure() - only interacts with this module, use onLoad() for cross-module, cross framework dependencies
some modules don’t have any configuration needed.

this.autoMapModels = true

auto map all your models into this namespace:

{modelName}@{ModuleName}

advanced WireBox integration

configure()
binder.map( “DefaultGrammar” ).
to( “#moduleMapping#”.modesl.grammars.MYssqlGrammar” );

ModuleConfig Is Also An Intercepter

intercepters are like events that are raised and listened to
ala jQuery’s onClick() except they can be “on” whatever i want
ColdBox lifecycle, etc,
own modules can announce their own things

Examples of Modules

Single Purpose modules

Utility Libraries

  • BCrypt - how to hash and check passwords
  • cbvalidation - a way to make sure data coming in matches the format your’e expecting (email, string, etc)
  • mementifier - lib used to turn components into structs and arrays to return an API, and does it very quickly.

API Wrappers

Interceptors

Frameworks

  • qb
  • Quick - ORM lib (that uses qb)
  • Hyper - HTTP library that gives you a more fluid syntax for composing a little nicer code from when dealing with cfhttp

Lots more too!

Where Do We Find Modules?

  • ForgeBox!
  • Other module locations
  • Git repo, and not put it on ForgeBox
  • pros: still get versioning, can change it public/private
  • cons: no semantic versioning ranges
  • no ForgeBox slugs
  • if dealing w/ a private repo, you also have to deal private ssh keys which are a pain

Modules_App folder

  • this is a convention in ColdBox apps
  • when you install a module in a ColdBox app, it goes in “modules” folder, which ignores any source control on your app - like the “node_modules” folder in javascript
  • modules_app = this is a folder for my app, I am managing them here, do not install them anywhere else.
  • usually used for APIs or when we’re starting a new module and we’re not sure how it’s going to “fit” yet — we’ll play with it inside the app first before making its own separate “thing”
  • pros: committed in your repo
    private to your application
    easy to iterate on and develop
    great for internal API versions
  • cons: no reuse outside your project
    no versions

Modules Are Easier to Test

  • you have removed all of the surrounding application
  • nothing gets in your way
  • removed the “mental code” around it
  • focusing on 1 piece, nothing to distract you.

Integration testing is also easier with modules
because you can make a “ColdBox app” just for your tests!

Even if most of the module is a unit testable thing
usually you have 1 integration test that at least shows that the module registered correctly, so we know the ModuleConfig isn’t messed up.

Scaffolding Modules

  • create box.json
  • create ModuleConfig.cfc
  • scaffold tests folder
  • copy over Travis CI config
  • create git repo
  • create github repo

For ColdBox apps:

coldbox create app

making a module as simple as starting a ColdBox app:

install cb-module-template
module scaffold my-awesome-module "It will blow your mind!"

Recap:
they help you build reusable code
they help you use reusable code other people built

Slide deck: http://slides.com/elpete/making-modules/#/
Eric on Twitter: @_elpete
Github: elpete
dev.elpete.com