⚠️ this library is deprecated, please check out picoapp as an alternative with a very similar API
A simple script initiation pattern for modular websites. ~650bytes gzipped.
Micromanager provides a simple pattern to execute scripts on specific elements within your markup. It's a simple idea, but allows for easy componentization, re-use, and composition.
// app/components/say-hello.js
export default div => {
console.log(div) // <div id='hello'></div>
}
<html>
<head></head>
<body>
<div id='hello' data-component='say-hello'></div>
</body>
</html>
// index.js
import * as scripts from 'micromanager'
scripts.init({
component: '/components'
})
scripts.mount()
Micromanager also gives you the ability to access a cache of each active instance in your site.
// app/components/slideshow.js
import Flickity from 'flickity'
export default outer => {
const slideshow = new Flickity(outer)
return {
displayName: 'slideshow1',
unmount () {
slideshow.destroy()
},
next () {
slideshow.next()
},
previous () {
slideshow.previous()
}
}
}
<div id='slideshow' data-component='slideshow'>
<div class='slide'></div>
<div class='slide'></div>
<div class='slide'></div>
</div>
This allows you to control individual instances using the methods you return.
import * as scripts from 'micromanager'
const slideshow1 = scripts.cache.get('slideshow1')
slideshow1.next()
slideshow1.previous()
You can also leverage micromanager's API to unmount scripts between routes, if you're using some sort of PJAX library.
import router from './router.js'
import * as scripts from 'micromanager'
router.on('newRoute', () => {
scripts.umount() // unmount existing scripts
scripts.mount() // mount new scripts on new page
})
Micromanager uses an internal alias to your scripts directory. You can do this a variety of ways. Below is an example using babel-plugin-modules-resolver
and webpack.
// .babelrc
{
"plugins": [
['module-resolver', {
'root': ['.'],
'alias': {
'micromanagerRoot': 'app' // or 'path/to/your/scripts'
}
}]
]
}
// webpack.config.js
modules.exports = {
// ...
resolve: {
alias: {
micromanagerRoot: path.join(__dirname, 'app') // or 'path/to/your/scripts'
}
},
// ...
}
You can also just pass the relative path when mounting the scripts like so:
scripts.mount({micromanagerRoot: './app'})
That way you don't have to setup the aliases on webpack/babel.
Micromanager needs to know how you structure your project, and also how you would like to call each script within your markup structure.
// index.js
import * as scripts from 'micromanager'
scripts.init({
component: '/components' // with alias, 'app/components'
})
Each key
provided to init()
becomes the data-<attribute>
you define in your markup. These keys can be anything you want. Their value simply needs to point to the directory where you keep these specific scripts. This path is then joined to the micromanager
alias during compilation so that when compiled it becomes ./app/components/*.js
.
Once configured, create modules scripts according to the configuration you passed to init()
, define them in your markup using data attributes, and then mount all the scripts on each page load.
scripts.init({
component: '/components',
util: '/util'
})
// app/components/slideshow.js
export default outer => {}
// app/util/modal-trigger.js
export default outer => {}
<div data-component='slideshow'>...</div>
<div data-util='modal-trigger'>...</div>
scripts.mount()
Configures the names and paths of your script types. Accepts a single object where the keys are the types of scripts, and the values are the paths to each script type's directory.
import { init } from 'micromanager'
init({
component: '/components',
page: '/pages'
})
Scans DOM for defined script types and executes them on the element on which they are defined.
// app/components/say-hello.js
export default div => {
console.log(div) // <div id='hello'></div>
}
<div id='hello' data-component='say-hello'></div>
Iterates over internal cache of all active instances. If an unmount
method is found on an instance, it will be fired, and the instance will be deleted from the cache. This is usually done between pages when using a PJAX library.
import { unmount } from 'micromanager'
unmount()
Returns the instance identified by displayName
.
import { cache } from 'micromanager'
cache.get('slideshow') // { unmount() {}, ... }
displayName
defaults to the name of the script file i.e. data-component='slideshow'
would default to slideshow
unless you define a custom displayName
on the return of the instance.
// app/components/slideshow.js
export default outer => {
return {
displayName: 'slideshow1',
unmount () {}
}
}
Returns the entire instance cache.
- operator.js - A drop-in "PJAX" solution for fluid, smooth transitions between pages. 2.87kb gzipped. Zero stress. by estrattonbailey.
I first heard of this pattern from ScottPolhemus while working at Barrel. It was further developed by begodgrey, myself, and the rest of the team. Thanks y'all!
MIT License