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?
- No!
- cflib functions
- cfmlparser
- etc
- can all be 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