Skip to main content

Application context

Context contains functionality of the application accessible to the plugins.

Currently, there are two kinds of contexts: Context and ReadonlyContext.

In the future, Context will be more fine-grain and provide only the functionalities required by a particular plugin. Each plugin will indicate what functionalities it needs, and the application can assess that information.

Accessing context

The (requested) context will be given to the plugin through the activate function:

// index.ts
import type { Context } '@just-web/app'

export function activate(context: Context) {
// ..snip..
}

The activate function will be called when the plugin is loaded.

The plugin can save the context locally and access it from its logics and components.

Testing with context

To test the plugin logics or components which uses the context, there are several ways to do it.

  • Dependency injection
  • seam injection
  • module mock

design

Besides the way just-web expose the context to the plugins, there are other ways to do that same thing.

In this section, we are going to take a look at these other approaches and understand the pros and cons of them.

Singleton context:

import { getContext } from '@just-web/app'

const Component = () => {
const ctx = getContext()
return <div>{ctx.format.i18n('hello')}</div>
}
  • 👍 easy to reference
  • 👎 only single application instance
  • 👎 create context first and config later, the context need to be pushed to just-web

Pass-in:

const Component = (props) => {
const { ctx } = props
return <div>{ctx.format.i18n('hello')}</div>
}
  • 👍 multiple applications
  • 👍 flexible
  • 👍 plugin makes the decision
  • 👎 cascade pass down
  • 👎 must be unique prop (justContext?), or will be hard to use

Activate:

let ctx
function activate(context) {
ctx = context
}

const Component = (props) => {
return <div>{ctx.format.i18n('hello')}</div>
}

// or
const Component = (props) => {
return <div>{Component.ctx.format.i18n('hello')}</div>
}
Component.ctx = ctx
  • 👍 activate() is needed anyway
  • 👍 multiple applications
  • 👍 no cascade pass down
  • 👍 easy to use (no need to pass in context)
  • 👍 plugin makes the decision