1.0.0-alpha.8 • Published 6 years ago

@overneath42/framewerk v1.0.0-alpha.8

Weekly downloads
-
License
MIT
Repository
github
Last release
6 years ago

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 for data-controller
  • targets: An object of unique keywords, with each storing a NodeList of elements. This object is generated by the getTargets class method of Controller. 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 a Controller 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.