npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@e1011/core-micro-frontend

v1.0.2

Published

Micro frontend framework, based on web component

Downloads

35

Readme

VeraCode Micro Frontend tooling library

🏠 Homepage

Install and use

Install

npm add core-micro-frontend

Use

import in the file where cmf-wrapper is instantiated

import { cmf } from 'core-micro-frontend';

cmf();

or link the UMD bundle (downloadable from this repository, or server from voltron in future...) umd/cmf-bundle.js

and link in the html of your app or page...

<script type="text/javascript" src="./cmf-bundle.js"></script>

Note: when using web components in Typescript project, the custom elements must be declared, e.g.:


declare global {
  namespace JSX {
    interface IntrinsicElements {
      'cmf-wrapper': CMFWrapperType
    }
  }
}

when importin cmf-wrapper from the core-micro-frontend the declaration is part of the types in library already...

actual instantiation inside HTML, JSX:

  <cmf-wrapper
    jsFiles={JSON.stringify([JS_URL])}
    cssFiles={JSON.stringify([CSS_URL])}
    // identifiyng this instance of cmf-wrapper and making it unique in the DOM, when mupliple instances of the same mdoule (from the smae JS_URL) are loaded
    mountId='my-component-id'
    // useful if bundle in JS_URL defines this custom element...
    mountTag='my-component'
    loader
  />

Example of muplitple JS and css files:

  <cmf-wrapper
    jsFiles={JSON.stringify([JS_URL, JS_URL_LIB])}
    cssFiles={JSON.stringify([CSS_URL, CSS_URL_FONTS])}
    mountId='my-component-id'
    // bundle in JS_URL declares this custom element...
    mountTag='my-component'
    loader
  />

CMFWrapper

  • Is a custom element (i.e. web component), that will handle load of JS and CSS files of your library/module bundle.
  • loads JS, CSS in non blocking way, either via fetch and then encapsualates loaded JS in IIFE (https://developer.mozilla.org/en-US/docs/Glossary/IIFE), and injects two params: loadedJSMountPointId and loadedJSAPI
    • loadedJSMountPointId is key where to find created HTMLElement to mount your application UI tree (react, angular,...)

    • declare anywhere, but preferably before referencing:

    • declare let loadedJSMountPointId: string;
      
      declare let loadedJSAPI: Record<string, unknown>;

      or in case of Javascript, global variables dont need special declration, but we need to overcome lintint errors, on such way is adding this simple comment:

       /*global loadedJSMountPointId, loadedJSAPI */

The reference to the root/mounting HTMLElement is obtained in the loaded module:

const mountElement = window.cmf[Symbol.for(loadedJSMountPointId) as typeof Symbol];

window.cmf is namespace for this library, will hold references to all CMF wrappers in the parent app/page. Eventually could also hold reference to some communication channel or eventBus etc.

loadedJSAPI is object of serializable information, pertinent to the loaded module, and coming from the CUIModule interface. Plus config property, which is deserialized config attribute from cmf-wrapper. (config is also passed in serialized form to the mounting div (of id mountId) created by cmf wrapper or custom element of value from mountTag)

export type LoadedJSAPI = Pick<CUIModule, 'jsFiles' | 'cssFiles' | 'mountId' | 'mountTag' | 'config'>;

CMFWrapper extends HTMLElement

  /**
   * An array of JavaScript file URLs to load for the module/app.
   */
  jsFiles: string[] | null

  /**
   * An array of CSS file URLs, not mandatory CSS files custom to the JS files above.
   */
  cssFiles: string[] | null

  /**
   * The ID of the element to which the loaded JS module should mount.
   * If `mountTag` is filled, `mountId` is optional.
   * The custom element will have an ID of either `mountId` or `mountTag`.
   */
  mountId: string | null

  /**
   * The name of the element to create by CMF wrapper, in case loaded modules declare a custom element.
   */
  mountTag: string | null

  /**
   * Specifies whether to add the 'nomodule' attribute to the script tag
   * (not recommended for older browser compatibility).
   */
  esmodule: boolean

  /**
   * Prevents the creation of a shadow root (only for debugging or special cases).
   */
  noshadow: boolean

  /**
   * Specifies whether to load JavaScript and CSS via `src` and `href` attributes in script and link tags respectively.
   */
  inline: boolean

  /**
   * Specifies whether the CMF wrapper is responsible for inserting loader UI into the mount element.
   */
  loader: boolean

  /**
   * The custom event type dispatched from JavaScript when the module is done and ready.
   */
  cmfEventName: string | null

  /**
   * Additional parameters passed to the CMF wrapper's `config` attribute.
   */
  config?: string | null

  /**
   * Arbitrary `data-*` attributes that will be propagated to the created `div` element
   * with the ID of `mountId` or custom element of `mountTag`.
   * @see [HTMLElement.dataset](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset)
   * @experimental
   */
  nonce?: string

  /**
   * For non inline link and script tags, hides mountPoint element till all js and css files are loaded.
   */
  nonInlineHideUntilLoaded?: boolean

Versions

  • ES module exports version as constant
import { cmf, version } from 'core-micro-frontend';

cmf();

console.log('CMF version', version);
  • UMD bundle has version baked in as firstline comment
// cmf-wrapper version 1.0.30;
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define
....

CMF Namespace

The CMF (CoreUI Micro Frontend) namespace is a TypeScript module for managing and configuring micro frontends within your web application. This namespace provides a structured way to handle configurations, version management, and mount points for micro frontend modules.

createCMFNameSpace

Description

This function creates the CMF namespace and returns an instance of CMFType. It sets up the CMF instance with default values and proxies for various properties.

Returns

  • CMFType: An instance of CMFType representing the CMF namespace.

Example

import { createCMFNameSpace } from './webComponentWrapper';

const cmf = createCMFNameSpace();

getCMFNamespace (or getCMFWindowNamespace)

Description

This function retrieves or creates the CMF window namespace. If the window object is defined, it returns the existing CMF namespace or creates a new one if it doesn't exist.

Returns

  • CMFType | null: The CMF window namespace or null if window is undefined.

Example

import { getCMFNamespace } from './webComponentWrapper';

const cmf = getCMFNamespace();

if (cmf) {
  // You can now use the CMF namespace.
  console.log(cmf.versions);
}

CMF Type

The CMFType represents the structure of the CMF namespace and includes the following properties and methods:

/**
   * Stores the version information for different components or modules within the CMF.
   */
  versions: Record<string, unknown>

  /**
   * Maintains a record of mounting points (HTML elements) for various components or modules.
   */
  mountPoints: Record<symbol, HTMLElement>

  /**
   * Internal instance of CMF, containing version and optional wrapper information.
   */
  __instanceCMF: {
    version: string
    CMFWrapper?: CMFWrapperType
  }

  /**
   * Adds application-specific configuration to the CMF.
   * @param appId  The unique identifier for the application. Defaults to 'CMF_APP'.
   * @param config The configuration object for the application.
   * @returns `void` or `boolean` indicating success or failure of the operation.
   */
  addAppConfig: <T = DefaultConfig>(appId?: string, config: CMFConfigType<T>) => void | boolean

  /**
   * Retrieves the configuration for a specific application by its ID.
   * @param appId  The unique identifier for the application. Defaults to 'CMF_APP'.
   * @returns The configuration object for the specified application.
   */
  getAppConfig: <T = DefaultConfig>(appId?: string) => CMFConfigType<T>

  /**
   * Adds user-specific information to the application configuration in CMF.
   * @param appId  The unique identifier for the application. Defaults to 'CMF_APP'.
   * @param config The user-specific configuration object.
   * @returns `void` or `boolean` indicating success or failure of the operation.
   */
  addAppUserInfo: <T = DefaultUserConfig>(appId?: string, config: CMFUserType<T>) => void | boolean

  /**
   * Retrieves user-specific information for a specific application by its ID.
   * @param appId  The unique identifier for the application. Defaults to 'CMF_APP'.
   * @returns The user-specific configuration object for the specified application.
   */
  getAppUserInfo: <T = DefaultUserConfig>(appId?: string) => CMFUserType<T>

  /**
   * Optional: Instance of PeregrineMQApi, if integrated within CMF.
   */
  peregrineMQ?: PeregrineMQApi

  /**
   * A collection of helper functions or utilities used within CMF.
   */
  helpers?: Record<string | symbol, (...rest: any[]) => any>

Global Window Object

The CMF namespace is intended to be used as a global object attached to the window object in a browser environment. When you include the CMF namespace, it augments the global window object with the following property:

  • cmf: The CMF namespace (CMFType).

Example

// After including the CMF namespace, you can access it globally as follows:
window.cmf.addAppConfig('myApp', { /* ... */ });

// access the saved config
window.cmf.getAppConfig('myApp');

// getCMFNamespace() is shorthand for window.cmf
// acces userInfo when loaded in CMF_MOTHER_APP:
getCMFNamespace().getAppUserInfo('CUI-CMF_MOTHER_APP');

Please ensure that you include the CMF namespace appropriately in your application and follow the provided documentation to manage micro frontends effectively.

Versions

  • ES, UMD have accessible versions as map of actual CMFWrapper classes (incase of multiple versions in one page)
window.cmf.versions['1.30.0']

Mount points

Known limitations

As this is web component with shadow dom, all limitations arise from that.

  • React Bootstrap: Some libraries create new Elements as high in DOM tree as possible (Modal in React bootstrap), this can be adjusted by container property
  • event bubling is limited
  • not all styling is able to penetrate shadowdom
  • event listener targets
  • etc.

Development of this library:

Install

npm install

Run tests

npm run test

Run lint and tests

npm run prepush

Run build

npm run build

build will run prepush as well

Author

👤 [email protected]

Show your support

Give a ⭐️ if this project helped you!


This README was generated with ❤️ by readme-md-generator