Modules
Components by nature should be re-used. This is easy when the component will only be used within a single application. How can you write a component once and use it in multiple applications?
A set of components can be shared as a module using a package manager or publishing it to a URL.
By packaging your components into a module, it can be imported into other applications and re-used multiple times.
Consuming a module
The following example shows how to consume a module from a shared library.
// import the required FicusJS functions
import { createComponent, use } from 'https://unpkg.com/ficusjs?module'
// import the renderer and html tagged template literal from the lit-html library
import { html, renderer } from 'https://unpkg.com/ficusjs-renderers@latest/dist/lit-html.js'
// import component library from a local path
import { module } from './path/to/component-module.esm.js'
// import the components into your application
use(module, { renderer, html })
// in your template, use the component
createComponent('my-component', {
renderer,
render () {
return html`<div>
<shared-component></shared-component>
</div>`
}
})
use
function
The use
function will import a module of components into your application ready to use.
// import the use function
import { use } from 'https://unpkg.com/ficusjs?module'
// import the renderer and html tagged template literal from the lit-html library
import { html, renderer } from 'https://unpkg.com/ficusjs-renderers@latest/dist/lit-html.js'
// import component module from a local path
import { module } from './path/to/component-module.esm.js'
// import the components into your application
use(module, { renderer, html })
The following arguments must be provided to the use
function:
Property | Type | Description |
---|---|---|
module |
object |
The imported module |
helpers |
object |
A helpers object for passing to components. This must contain the renderer function as a named property |
The helpers
object must contain the renderer
function as named property. Additional helpers can be provided in the helpers
object and will be passed to the module. For example; the html
tagged template literal can be passed for module components to return HTML content.
// pass the renderer and the html tagged template literal to the module for rendering
use(module, { renderer, html })
Creating a module
A module is a set of functions for creating components, stores and/or events. This ensures just the definitions will be shared without the overhead of bundling the FicusJS runtime.
Modules should be minified to optimise load.
A single Javascript file exports a named object module
exposing a create
method.
The shared module create
method will be invoked by the use
function in the context of the running application and is passed a single object
argument.
It is the responsibility of the create
method to use the object
argument to create components, stores or events (anything required by the module).
// Export a module object that is invoked by the `use` function
export const module = {
create (helpers) {
// create stuff here
}
}
Async create
method
You can return a Promise
from the create
method that contains async operations.
// use async/await
export const module = {
async create (helpers) {
await asyncFunction()
}
}
// return a Promise
export const module = {
create (helpers) {
return asyncFunction()
}
}
If returning a Promise
, the calling module must handle the response before continuing execution.
When using the all features build
When using the all features build dist/index.js
, the helpers object
will contain the following properties.
Property | Type | Description |
---|---|---|
createComponent |
function |
The createComponent function |
renderer |
function |
The renderer function for component rendering |
createEventBus |
function |
The createEventBus function |
createPersist |
function |
The createPersist function |
createStore |
function |
The createStore function |
getEventBus |
function |
The getEventBus function |
getStore |
function |
The getStore function |
use |
function |
The use for loading modules internally |
Additional arguments provided in the helpers
object will be passed to the module. For example; the html
tagged template literal can be passed for module components to return HTML content.
// Export a module object that is invoked by the `use` function
export const module = {
create (helpers) {
// create stuff here
}
}
The following example creates a component, a store and imports another module for use internally.
import { module as anotherModule } from './path/to/another-module.esm.js'
function createSharedComponent (renderer, html, getStore) {
return {
renderer,
store: getStore('test.store'),
render () {
if (this.store.state.hideComponent) {
return ''
}
return html`<span>Shared component</span>`
}
}
}
// Export a module object that is invoked by the `use` function
export const module = {
create ({ createComponent, renderer, html, createStore, getStore, use }) {
// create stores
createStore('test.store', { /* store options */ })
// create components
createComponent('shared-component', createSharedComponent(renderer, html, getStore))
// import and use another module
use(anotherModule, { renderer, html })
}
}
When using the component build only
When using the component only dist/component.js
without stores and events, the helpers object
argument will contain the following properties:
Property | Type | Description |
---|---|---|
createComponent |
function |
The createComponent function |
renderer |
function |
The renderer function for component rendering |
use |
function |
The use function for loading modules internally |
Additional arguments provided in the helpers
object will be passed to the module. For example; the html
tagged template literal can be passed for module components to return HTML content.
// Export a module object that is invoked by the `use` function
export const module = {
create (helpers) {
// create components here
}
}