diff --git a/docs/ilc_app_interface.md b/docs/ilc_app_interface.md
index 82861def..470a1d94 100644
--- a/docs/ilc_app_interface.md
+++ b/docs/ilc_app_interface.md
@@ -16,7 +16,7 @@ ILC also supports apps that have client side rendering only.
During the course of a single-spa page, registered applications are loaded, bootstrapped (initialized), mounted, unmounted, and unloaded.
ILC (with the help of the [single-spa](https://single-spa.js.org/)) provides hooks into each phase via `lifecycles`.
-See more information about the [lifecycle functions here](https://single-spa.js.org/docs/building-applications#lifecyle-props).
+See more information about the [lifecycle functions here](https://single-spa.js.org/docs/building-applications/#lifecyle-props).
### Custom props that are passed to every app
@@ -25,3 +25,27 @@ See more information about the [lifecycle functions here](https://single-spa.js.
* `getCurrentBasePath(): string` - returns same value as `basePath` param in `routerProps` query parameter
* `errorHandler(error, errorInfo = {}): void` - app MUST use it to propagate all unhandled errors
* `appId` - Unique application ID, if same app will be rendered twice on a page - it will get different IDs
+
+
+### Init code during app bundle loading
+
+Sometimes you need to run some initialization code right after app bundle will be loaded in the browser and usually you
+want to be able to pass some configuration properties to that code.
+
+ILC allows you to export a function called `mainSpa(props)` that will receive application properties that were defined in
+_Registry_ in it's first argument.
+This function should return an object with "single-spa" [lifecycle functions](https://single-spa.js.org/docs/building-applications/#lifecyle-props).
+
+**Example of possible use case:**
+```javascript
+// File specified as Webpack entry point
+export const mainSpa = (props) => {
+ if (props.publicPath) {
+ __webpack_public_path__ = props.publicPath;
+ } else {
+ console.warn(`Can't determine value of the "__webpack_public_path__", falling back to default one...`);
+ }
+
+ return require('./app-bootstrap'); // Returns: {bootstrap: () => {}, mount: () => {}, unmount: () => {}}
+};
+```
\ No newline at end of file
diff --git a/ilc/client.js b/ilc/client.js
index 9669b77f..195a4ed6 100644
--- a/ilc/client.js
+++ b/ilc/client.js
@@ -49,7 +49,7 @@ selectSlotsToRegister([...registryConf.routes, registryConf.specialRoutes['404']
}
return Promise.all(waitTill)
- .then(v => v[0].mainSpa !== undefined ? v[0].mainSpa(appConf.initProps || {}) : v[0]);
+ .then(v => v[0].mainSpa !== undefined ? v[0].mainSpa(appConf.props || {}) : v[0]);
},
isActiveFactory(router, appName, slotName),
{
diff --git a/ilc/server/tailor/configs-injector.js b/ilc/server/tailor/configs-injector.js
index f226e5a1..69f29779 100644
--- a/ilc/server/tailor/configs-injector.js
+++ b/ilc/server/tailor/configs-injector.js
@@ -140,7 +140,7 @@ module.exports = class ConfigsInjector {
#getPolyfillUrl = () => this.#cdnUrl === null ? '/_ilc/polyfill.min.js' : urljoin(this.#cdnUrl, '/polyfill.min.js');
#getSPAConfig = (registryConfig) => {
- const apps = _.mapValues(registryConfig.apps, v => _.pick(v, ['spaBundle', 'cssBundle', 'dependencies', 'props', 'initProps', 'kind']));
+ const apps = _.mapValues(registryConfig.apps, v => _.pick(v, ['spaBundle', 'cssBundle', 'dependencies', 'props', 'kind']));
const spaConfig = JSON.stringify(_.omit({...registryConfig, apps}, ['templates']));
return ``;
diff --git a/registry/client/src/appRoutes/Edit.js b/registry/client/src/appRoutes/Edit.js
index 6a2dc1c0..7562c9f5 100755
--- a/registry/client/src/appRoutes/Edit.js
+++ b/registry/client/src/appRoutes/Edit.js
@@ -65,7 +65,7 @@ const InputForm = ({mode = 'edit', ...props}) => {
{ id: 'essential', name: 'Essential' },
{ id: 'regular', name: 'Regular' },
]} />
-
+
diff --git a/registry/client/src/apps/Edit.js b/registry/client/src/apps/Edit.js
index 99982f54..bc6409db 100755
--- a/registry/client/src/apps/Edit.js
+++ b/registry/client/src/apps/Edit.js
@@ -54,8 +54,7 @@ const InputForm = ({mode = 'edit', ...props}) => {
-
-
+
);
diff --git a/registry/client/src/apps/dataTransform.js b/registry/client/src/apps/dataTransform.js
index 4fc36215..1b99fe33 100644
--- a/registry/client/src/apps/dataTransform.js
+++ b/registry/client/src/apps/dataTransform.js
@@ -9,18 +9,12 @@ export function transformGet(app) {
if (app.props) {
app.props = JSON.stringify(app.props);
}
- if (app.initProps) {
- app.initProps = JSON.stringify(app.initProps);
- }
}
export function transformSet(app) {
if (app.props) {
app.props = JSON.parse(app.props);
}
- if (app.initProps) {
- app.initProps = JSON.parse(app.initProps);
- }
if (app.dependencies) {
app.dependencies = app.dependencies.reduce((acc, v) => {
acc[v.key] = v.value;
diff --git a/registry/server/apps/interfaces/index.ts b/registry/server/apps/interfaces/index.ts
index 2038ecbc..ac60bb47 100644
--- a/registry/server/apps/interfaces/index.ts
+++ b/registry/server/apps/interfaces/index.ts
@@ -9,7 +9,6 @@ export default interface App {
props?: string, // JSON({ [propName: string]: any })
configSelector?: string,
ssr: string, // JSON({ src: string, timeout: number })
- initProps?: string, // JSON({ [propName: string]: any })
}
export const appNameSchema = Joi.string().trim().min(1);
@@ -25,7 +24,6 @@ const commonApp = {
src: Joi.string().trim().uri().required(),
timeout: Joi.number().required(),
}),
- initProps: Joi.object().default({}),
kind: Joi.string().valid('primary', 'essential', 'regular'),
};
diff --git a/registry/server/apps/routes/createApp.ts b/registry/server/apps/routes/createApp.ts
index 2bedf44b..aaac2995 100644
--- a/registry/server/apps/routes/createApp.ts
+++ b/registry/server/apps/routes/createApp.ts
@@ -22,7 +22,7 @@ const validateRequestBeforeCreateApp = validateRequestFactory([{
const createApp = async (req: Request, res: Response): Promise => {
const app = req.body;
- await db('apps').insert(stringifyJSON(['dependencies', 'props', 'ssr', 'initProps', 'configSelector'], app));
+ await db('apps').insert(stringifyJSON(['dependencies', 'props', 'ssr', 'configSelector'], app));
const [savedApp] = await db.select().from('apps').where('name', app.name);
diff --git a/registry/server/apps/routes/updateApp.ts b/registry/server/apps/routes/updateApp.ts
index 8f4a21ba..b8ddf281 100644
--- a/registry/server/apps/routes/updateApp.ts
+++ b/registry/server/apps/routes/updateApp.ts
@@ -43,7 +43,7 @@ const updateApp = async (req: Request, res: Response): P
return;
}
- await db('apps').where({ name: appName }).update(stringifyJSON(['dependencies', 'props', 'ssr', 'initProps', 'configSelector'], app));
+ await db('apps').where({ name: appName }).update(stringifyJSON(['dependencies', 'props', 'ssr', 'configSelector'], app));
const [updatedApp] = await db.select().from('apps').where('name', appName);
diff --git a/registry/server/migrations/20200518134531_apps_initProps_removal.ts b/registry/server/migrations/20200518134531_apps_initProps_removal.ts
new file mode 100644
index 00000000..77e39e7f
--- /dev/null
+++ b/registry/server/migrations/20200518134531_apps_initProps_removal.ts
@@ -0,0 +1,16 @@
+import * as Knex from "knex";
+
+
+export async function up(knex: Knex): Promise {
+ return knex.schema.table('apps', function (table) {
+ table.dropColumn('initProps');
+ })
+}
+
+
+export async function down(knex: Knex): Promise {
+ return knex.schema.createTable('apps', table => {
+ table.json('initProps');
+ });
+}
+
diff --git a/registry/server/routes/config.ts b/registry/server/routes/config.ts
index 47171480..ae21cca9 100644
--- a/registry/server/routes/config.ts
+++ b/registry/server/routes/config.ts
@@ -25,7 +25,6 @@ router.get('/', async (req, res) => {
data.apps = apps.reduce((acc, v) => {
v.ssr = JSON.parse(v.ssr);
v.dependencies = JSON.parse(v.dependencies);
- v.initProps = JSON.parse(v.initProps);
v.props = JSON.parse(v.props);
if (sharedProps.length && v.configSelector !== null) {
JSON.parse(v.configSelector).forEach((configSelectorName: string) => {
diff --git a/registry/server/seeds/01_apps.ts b/registry/server/seeds/01_apps.ts
index ab4e28d5..acb0497c 100644
--- a/registry/server/seeds/01_apps.ts
+++ b/registry/server/seeds/01_apps.ts
@@ -15,7 +15,6 @@ export async function seed(knex: Knex): Promise {
src: 'http://localhost:8235/',
timeout: 1000,
}),
- initProps: '{}',
props: '{}',
kind: 'essential',
}, {
@@ -27,7 +26,6 @@ export async function seed(knex: Knex): Promise {
rxjs: 'https://unpkg.com/rxjs@6.4.0/bundles/rxjs.umd.js',
'@portal/fetchWithCache': `http://${publicHost}:8238/fetchWithCache.js`,
}),
- initProps: '{}',
props: JSON.stringify({
publicPath: `http://${publicHost}:8236/`
}),
@@ -38,7 +36,6 @@ export async function seed(knex: Knex): Promise {
dependencies: JSON.stringify({
'@portal/fetchWithCache': `http://${publicHost}:8238/fetchWithCache.js`,
}),
- initProps: '{}',
props: '{}',
kind: 'primary',
}, {
@@ -51,9 +48,6 @@ export async function seed(knex: Knex): Promise {
}),
assetsDiscoveryUrl: 'http://127.0.0.1:8239/_spa/dev/assets-discovery',
dependencies: '{}',
- initProps: JSON.stringify({
- publicPath: `http://${publicHost}:8239/dist/`
- }),
props: JSON.stringify({
publicPath: `http://${publicHost}:8239/dist/`
}),
@@ -66,14 +60,12 @@ export async function seed(knex: Knex): Promise {
timeout: 1000,
}),
dependencies: '{}',
- initProps: '{}',
props: '{}',
kind: 'primary',
}, {
name: '@portal/fetchWithCache',
spaBundle: `http://${publicHost}:8238/fetchWithCache.js`,
dependencies: '{}',
- initProps: '{}',
props: '{}',
kind: 'essential',
},
diff --git a/registry/tests/apps.spec.ts b/registry/tests/apps.spec.ts
index d591b372..6c11c25c 100644
--- a/registry/tests/apps.spec.ts
+++ b/registry/tests/apps.spec.ts
@@ -16,7 +16,6 @@ const example = {
kind: 'primary',
// dependencies: {},
// props: {},
- // initProps: {},
}),
updated: Object.freeze({
name: '@portal/ncTestAppReactssr',
@@ -38,9 +37,6 @@ const example = {
assetsPath: 'http://127.0.0.1:3001/uisamplereactUpdated',
locationStrategy: 'browserHistoryUpdated',
},
- initProps: {
- assetsPath: 'http://127.0.0.1:3001/uisamplereact',
- },
}),
};
example.encodedName = encodeURIComponent(example.correct.name);
@@ -65,7 +61,6 @@ describe(`Tests ${example.url}`, () => {
assetsDiscoveryUrl: 789,
dependencies: 456,
props: 789,
- initProps: 456,
};
let response = await request.post(example.url)
@@ -82,7 +77,6 @@ describe(`Tests ${example.url}`, () => {
'"props" must be of type object\n' +
'"configSelector" must be an array\n' +
'"ssr" must be of type object\n' +
- '"initProps" must be of type object\n' +
'"name" must be a string'
);
@@ -193,7 +187,6 @@ describe(`Tests ${example.url}`, () => {
assetsDiscoveryUrl: 789,
dependencies: 456,
props: 789,
- initProps: 456,
kind: 'origin',
};
@@ -211,7 +204,6 @@ describe(`Tests ${example.url}`, () => {
'"props" must be of type object\n' +
'"configSelector" must be an array\n' +
'"ssr" must be of type object\n' +
- '"initProps" must be of type object\n' +
'"kind" must be one of [primary, essential, regular]'
);
expect(response.body).deep.equal({});