@overneath42/framewerk
v1.0.0-alpha.8
Published
A framework for managing scripting on top of server-rendered pages.
Downloads
1
Readme
Framewerk
A framework for managing scripting on top of server-rendered pages. (a.k.a. yet another JavaScript framework 😉)
What is Framewerk?
Many existing JavaScript frameworks are targeted toward JS-rendered single-page apps. However, there are many, many developers working on apps which are primarily server-rendered, yet have large amounts of scripting to enhance the user experience within those apps. Conventional wisdom is to isolate JavaScript to its own files to maintain separation of concerns — yet how do you then effectively integrate that scripting into your views? Or do you just give up and shove it into ad hoc <script>
tags within your view files?
Framewerk is an attempt to create a consistent interface for cleanly attaching complex scripting to view files. It was initially inspired by AngularJS. (Yes, the old, bad version.) It borrows a couple of ideas from AngularJS but has happily diverged in a different direction. It does not directly rely on jQuery, but can certainly coexist with it.
But what does it DO?
The core functionality of Framewerk operates in two sections.
Controllers
A Controller
contains selector string references, logic-heavy methods and view-based DOM operations. The Controller
is then activated by attaching a data-controller
attribute to the container element upon which the Controller
should operate.
Plugins
The Plugin
is a way to wrap a third-party plugin within a consistent, repeatable structure, allowing for safe, dynamic activation of plugins on an as-needed basis. This is designed to sidestep the following all-too-typical scenarios:
- manually calling a plugin initialization within a view-level
<script>
tag - activating the plugin on every page regardless of whether or not it's actually needed
Usage
Controllers
An individual Controller
is created by passing three values to a new instance:
name
: A unique slug name, which is also the value used fordata-controller
targets
: An object of unique keywords, with each storing aNodeList
of elements. This object is generated by thegetTargets
class method ofController
. Provide an object should be given an object with the keywords desired in the final object, and a selector string for each value.Ïevents
: An object where the keys are internal reference names for events, and the values are functions which will attach event listeners to the DOM. If aController
is initialized on a particular page, each function in this object will be called once after loading has completed.
The preferred way to do this is by creating a new function to set values for each of the above, and then return the new Controller
when the function is called. This allows you to use the values stored within targets
to target your event listeners.
import { Controller } from 'framewerk';
export default function myController() {
// this string will be used to match a `data-controller` attribute
const name = 'my-controller';
// this creates a list of DOM lookups and caches it for later use
const targets = Controller.getTargets({
main: '[data-target-main]',
secondary: '[data-target-secondary]'
});
// each function in this object will be called once
const events = {
mainTargetClick: () => {
targets.main.addEventListener('click', () => {
// do something when any element within `targets.main` is clicked.
});
}
}
// at the bottom, return a new Controller with the three values above
return new Controller({ name, targets, events });
}
All controllers should live in a separate folder (typically called /controllers
, but this doesn't really matter), and then imported as a single object in your main entry, along with the core fw
function.
import { fw } from 'framewerk';
// this should be shaped like an object of modules
import controllers from './controllers';
// pass `controllers` into the `fw` function, then call `initialize` to start it.
fw(controllers).initialize();
Important Note
This projects was created for my own personal use; therefore the API is tailored to my personal needs and highly opinionated as a result.