Skip to content

Parcels

Overview⚓︎

ILC / single-spa Parcel is a framework, and language-agnostic component that acts as a reusable piece of functionality meant to be mounted manually by an application via a manual function call (not by ILC). You can choose any language for your Parcel, and the resulting Parcel can be as large as an application or as small as a component. The only requirement is that a Parcel should export the correct lifecycle events.

In ILC, your website can contain multiple applications and each application may also export Parcels.

You can export Parcels from the application's bundle only.

If you are using only one framework, it is recommended to use native framework components (for example, React, Vue, and Angular components) over Parcels, as Parcels act as an intermediary layer which may complicate components' interoperation.

Demo and examples⚓︎

React⚓︎

Go to http://ilc-demo.namecheap.technology/people and click Open in the main window. This action will render Vue.js application inside React application.

Parcel export⚓︎

Parcel export

import ilcAdapterReact, { ParcelLifecycleFnProps } from 'ilc-adapter-react';
import Root from './root.component';

export default {
    ...ilcAdapterReact<AppLifecycleFnProps>({
        rootComponent: Root,
    }),
    parcels: {
        person: ilcAdapterReact<ParcelLifecycleFnProps>({
            loadRootComponent: () => import('./person.parcel.js').then(property('default')),
        }),
    },
};
import React from 'react';
import { ParcelLifecycleFnProps } from 'ilc-adapter-react';

export default (props: ParcelLifecycleFnProps) => {
    return <div>Hello world</div>;
};

Link to the full code

Parcel usage⚓︎

Parcel usage

import Parcel from 'ilc-adapter-react/parcel';

export default () => (
    <div>
        <Parcel
            loadingConfig={{ appName: '@portal/planets', parcelName: 'planet' }}
            wrapWith="div"
            customParam1="testProp"
        />
    </div>
);

Link to the full code

Vue.js⚓︎

Go to http://ilc-demo.namecheap.technology/planets and click Open in the main window. This action will render React.js application inside Vue.js application.

Parcel export⚓︎

Parcel export

import Vue from 'vue';
import App from './App.vue';
import PlanetParcel from './planet-parcel.vue';
import singleSpaVue from 'ilc-adapter-vue';

export default {
    ...singleSpaVue({
        Vue,
        appOptions: {
            render(h) {
                return h(App, {
                    props: {
                        mountParcel: this.mountParcel,
                    }
                })
            },
        }
    }),
    parcels: {
        planet: singleSpaVue({
            Vue,
            appOptions: {
                render(h) {
                    return h(PlanetParcel, {
                        props: {
                            id: this.id,
                            mountParcel: this.mountParcel,
                        }
                    })
                },
            }
        })
    }
};

Link to the full code

Parcel usage⚓︎

Parcel usage

import Parcel from 'ilc-adapter-react/parcel';

export default () => (
    <div>
        <Parcel
            loadingConfig={{ appName: '@portal/planets', parcelName: 'planet' }}
            wrapWith="div"
            customParam1="testProp"
        />
    </div>
);

Link to the full code

Component that uses Parcel

<template>
<div>
    <Parcel
        :config="parcelConfig()"
        :mountParcel="mountParcel"
        :parcelProps="getParcelProps()"
    />
</div>
</template>
<script>
import Parcel from 'single-spa-vue/dist/esm/parcel';

export default {
components: {
    Parcel,
},
data() {
    return {
    parcelConfig: () => window.ILC.importParcelFromApp('@portal/people', 'person')
    }
},
methods: {
    getParcelProps() {
    return {
        id: 1,
    }
    },
},
inject: ['mountParcel'],
}
</script>

Application's root component

ILC uses provide()/inject to pass mountParcel function to all child components:

<script>
export default {
    props: ['mountParcel'],
    provide() {
        return {
            mountParcel: this.mountParcel
        }
    }
}
</script>

API⚓︎

ILC Parcels are 95% compatible with single-spa API but there are the following features from our side: