Skip to content

Commit

Permalink
Release/2.7.2 (#527)
Browse files Browse the repository at this point in the history
* fix(icestark): fix isAssetExist type statement (#525)
* fix: 🐛 set actual basename when `activePath` is an array (#529)

✅ Closes: #526

Co-authored-by: 1ncounter <[email protected]>
Co-authored-by: 唐澜 <[email protected]>
  • Loading branch information
3 people authored Mar 24, 2022
1 parent 0dca796 commit 2289f25
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 61 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

See [https://github.com/ice-lab/icestark/releases](https://github.com/ice-lab/icestark/releases) for what has changed in each version of icestark.

## 2.7.2

- [fix] set actual basename when `activePath` is an array. ([#526](https://github.com/ice-lab/icestark/issues/526))

## 2.7.1

- [feat] improve DX a lot.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "icestark-monorepo",
"version": "2.7.1",
"version": "2.7.2",
"private": true,
"description": "Icestark is a JavaScript library for multiple projects, Ice workbench solution.",
"scripts": {
Expand Down
26 changes: 26 additions & 0 deletions packages/icestark/__tests__/AppRouter.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,30 @@ describe('AppRouter', () => {

unmount();
})


test('app-multi-paths', async () => {
(fetch as FetchMock).mockResponseOnce(umdSourceWithSetLibrary.toString());
const { container, unmount } = render(
<AppRouter>
<AppRoute
loadScriptMode="fetch"
name="seller"
path={["/seller", "/seller2"]}
title="小二"
url={[
'//icestark.com/index.js'
]}
/>
</AppRouter>
);
window.history.pushState({}, 'test', '/seller2');
expect(container.innerHTML).toContain('Loading')
expect(getCache('basename')).toBe('/seller2');

await delay(1000);
expect(container.innerHTML).toContain('商家平台')

unmount();
})
})
38 changes: 21 additions & 17 deletions packages/icestark/__tests__/checkActive.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import '@testing-library/jest-dom/extend-expect';
import checkActive, { matchPath, getPathname, formatPath } from '../src/util/checkActive';
import findActivePath, { matchPath, getPathname, formatPath } from '../src/util/checkActive';

describe('checkActive', () => {
test('matchPath - path options', () => {
Expand Down Expand Up @@ -54,44 +54,48 @@ describe('checkActive', () => {

test('checkActive', () => {
// empty activePath
let checkFnc = checkActive();
let checkFnc = findActivePath();
expect(checkFnc('/test/123')).toBeTruthy();

// type `string`
checkFnc = checkActive(formatPath('/test', {}));
expect(checkFnc('/test/123')).toBeTruthy();
checkFnc = findActivePath(formatPath('/test', {}));
expect(checkFnc('/test/123')).toEqual('/test');

checkFnc = checkActive(formatPath('/test', { exact: true }));
checkFnc = findActivePath(formatPath('/test', { exact: true }));
expect(checkFnc('/test/123')).toBeFalsy();

// type `string[]`
checkFnc = checkActive(formatPath(['/test', '/seller'], {}));
expect(checkFnc('/test/123')).toBeTruthy();
checkFnc = findActivePath(formatPath(['/test', '/seller'], {}));
expect(checkFnc('/test/123')).toEqual('/test');

checkFnc = checkActive(formatPath(['/test', '/seller'], { exact: true }));
checkFnc = findActivePath(formatPath(['/test', '/seller'], { exact: true }));
expect(checkFnc('/test/123')).toBeFalsy();

// type `PathData`
checkFnc = checkActive(formatPath({ value: '/test' }, {}));
expect(checkFnc('/test/123')).toBeTruthy();
checkFnc = findActivePath(formatPath({ value: '/test' }, {}));
expect(checkFnc('/test/123')).toEqual('/test');

checkFnc = checkActive(formatPath({ value: '/test', exact: true }, {}));
checkFnc = findActivePath(formatPath({ value: '/test', exact: true }, {}));
expect(checkFnc('/test/123')).toBeFalsy();

// type `PathData[]`
checkFnc = checkActive([{ value: '/test' }, { value: '/seller' }]);
expect(checkFnc('/test/123')).toBeTruthy();
checkFnc = findActivePath([{ value: '/test' }, { value: '/seller' }]);
expect(checkFnc('/test/123')).toEqual('/test');

// type `MixedPathData`
checkFnc = checkActive(formatPath(['/test', { value: '/seller' }]));
expect(checkFnc('/test/123')).toBeTruthy();
checkFnc = findActivePath(formatPath(['/test', { value: '/seller' }]));
expect(checkFnc('/test/123')).toEqual('/test');

// type `ActiveFn`
checkFnc = checkActive((url: string) => url.includes('/test'));
checkFnc = findActivePath((url: string) => url.includes('/test'));
expect(checkFnc('/test/123')).toBeTruthy();

// `undefined`
checkFnc = checkActive(formatPath());
checkFnc = findActivePath(formatPath());
expect(checkFnc('/test/123')).toBeTruthy();

// matched idx
checkFnc = findActivePath(formatPath(['/test', '/seller'], {}));
expect(checkFnc('/seller')).toEqual('/seller');
})
});
2 changes: 1 addition & 1 deletion packages/icestark/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ice/stark",
"version": "2.7.1",
"version": "2.7.2",
"description": "Icestark is a JavaScript library for multiple projects, Ice workbench solution.",
"scripts": {
"build": "rm -rf lib && tsc",
Expand Down
3 changes: 2 additions & 1 deletion packages/icestark/src/AppRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import renderComponent from './util/renderComponent';
import { AppHistory } from './appHistory';
import { unloadMicroApp, BaseConfig, createMicroApp } from './apps';
import { converArray2String } from './util/helpers';
import { PathData } from './util/checkActive';
import { callCapturedEventListeners, resetCapturedEventListeners } from './util/capturedListeners';
import isEqual from 'lodash.isequal';

import type { PathData } from './util/checkActive';

interface AppRouteState {
showComponent: boolean;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/icestark/src/AppRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { ICESTSRK_ERROR, ICESTSRK_NOT_FOUND } from './util/constant';
import start, { unload } from './start';
import { AppConfig, MicroApp } from './apps';
import { doPrefetch, Prefetch } from './util/prefetch';
import checkActive, { AppRoutePath, formatPath } from './util/checkActive';
import findActivePath, { AppRoutePath, formatPath } from './util/checkActive';
import { converArray2String, isFunction, mergeFrameworkBaseToPath } from './util/helpers';
import type { Fetch } from './util/globalConfiguration';

Expand Down Expand Up @@ -227,7 +227,7 @@ export default class AppRouter extends React.Component<AppRouterProps, AppRouter

element = child;

match = checkActive(compatPath)(url);
match = !!findActivePath(compatPath)(url);
}
});

Expand Down
28 changes: 19 additions & 9 deletions packages/icestark/src/apps.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Sandbox, { SandboxConstructor, SandboxProps } from '@ice/sandbox';
import isEmpty from 'lodash.isempty';
import { NOT_LOADED, NOT_MOUNTED, LOADING_ASSETS, UNMOUNTED, LOAD_ERROR, MOUNTED } from './util/constant';
import checkUrlActive, { ActivePath, PathOption, formatPath } from './util/checkActive';
import findActivePathCurry, { ActivePath, PathOption, formatPath } from './util/checkActive';
import {
createSandbox,
getUrlAssets,
Expand All @@ -20,6 +20,7 @@ import { ErrorCode, formatErrMessage } from './util/error';
import globalConfiguration, { temporaryState } from './util/globalConfiguration';

import type { StartConfiguration } from './util/globalConfiguration';
import type { FindActivePathReturn } from './util/checkActive';

export type ScriptAttributes = string[] | ((url: string) => string[]);

Expand Down Expand Up @@ -61,7 +62,10 @@ export interface BaseConfig extends PathOption {
*/
umd?: boolean;
loadScriptMode?: LoadScriptMode;
checkActive?: (url: string) => boolean;
/**
* @private will be prefixed with `_` for it is internal.
*/
findActivePath?: FindActivePathReturn;
appAssets?: Assets;
props?: object;
cached?: boolean;
Expand Down Expand Up @@ -131,13 +135,13 @@ export function registerMicroApp(appConfig: AppConfig, appLifecyle?: AppLifecylc

const { basename: frameworkBasename } = globalConfiguration;

const checkActive = checkUrlActive(mergeFrameworkBaseToPath(activePathArray, frameworkBasename));
const findActivePath = findActivePathCurry(mergeFrameworkBaseToPath(activePathArray, frameworkBasename));

const microApp = {
status: NOT_LOADED,
...appConfig,
appLifecycle: appLifecyle,
checkActive,
findActivePath,
};

microApps.push(microApp);
Expand Down Expand Up @@ -353,16 +357,20 @@ export async function createMicroApp(
return null;
}

const { container, basename, activePath, configuration: userConfiguration } = appConfig;
const { container, basename, activePath, configuration: userConfiguration, findActivePath } = appConfig;

if (container) {
setCache('root', container);
}

const { basename: frameworkBasename, fetch } = userConfiguration;
const { fetch } = userConfiguration;

if (shouldSetBasename(activePath, basename)) {
setCache('basename', getAppBasename(activePath, frameworkBasename, basename));
let pathString = findActivePath(window.location.href);

// When use `createMicroApp` lonely, `activePath` maybe not provided.
pathString = typeof pathString === 'string' ? pathString : '';
setCache('basename', getAppBasename(pathString, basename));
}

switch (appConfig.status) {
Expand Down Expand Up @@ -392,8 +400,10 @@ export async function createMicroApp(
export async function mountMicroApp(appName: string) {
const appConfig = getAppConfig(appName);
// check current url before mount
if (appConfig && appConfig.checkActive(window.location.href) && appConfig.status !== MOUNTED) {
if (appConfig.mount) {
const shouldMount = appConfig?.mount && appConfig?.findActivePath(window.location.href);

if (shouldMount) {
if (appConfig?.mount) {
await appConfig.mount({ container: appConfig.container, customProps: appConfig.props });
}
updateAppConfig(appName, { status: MOUNTED });
Expand Down
2 changes: 1 addition & 1 deletion packages/icestark/src/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function reroute(url: string, type: RouteType | 'init' | 'popstate'| 'has
const unmountApps = [];
const activeApps = [];
getMicroApps().forEach((microApp: AppConfig) => {
const shouldBeActive = microApp.checkActive(url);
const shouldBeActive = !!microApp.findActivePath(url);
if (shouldBeActive) {
activeApps.push(microApp);
} else {
Expand Down
23 changes: 15 additions & 8 deletions packages/icestark/src/util/checkActive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,25 +81,32 @@ export const formatPath = (activePath?: ActivePath, options: PathOption = {}): P
* @param activePath
* @returns
*/
const checkActive = (activePath?: PathData[] | ActiveFn) => {
const findActivePath = (activePath?: PathData[] | ActiveFn): (url?: string) => string | boolean => {
// Always activate app when activePath is not specified.
if (!activePath) {
return () => true;
}

// If pass fucntion to activePath, just returns
if (isFunction(activePath)) {
return activePath;
return (url: string) => activePath(url);
}

return (url: string) => activePath
.map((rule) => {
return (checkUrl: string) => matchPath(checkUrl, rule);
})
.some((functionalRule) => functionalRule(url));
return (url: string) => {
// Record matched index
let matchedPath;
const isActive = activePath.some((path) => {
matchedPath = path?.value;
return matchPath(url, path);
});

return isActive ? matchedPath : false;
};
};

export default checkActive;
export type FindActivePathReturn = ReturnType<typeof findActivePath>;

export default findActivePath;

const HashPathDecoders = {
hashbang: (path: string) => (path.charAt(0) === '!' ? path.substr(1) : path),
Expand Down
2 changes: 1 addition & 1 deletion packages/icestark/src/util/handleAssets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export interface ILifecycleProps {
customProps?: object;
}

function isAssetExist(element: HTMLScriptElement | HTMLLIElement, type: 'script' | 'link') {
function isAssetExist(element: HTMLScriptElement | HTMLLinkElement, type: 'script' | 'link') {
const urlAlias = type === 'script' ? 'src' : 'href';

return Array.from(document.getElementsByTagName(type))
Expand Down
23 changes: 4 additions & 19 deletions packages/icestark/src/util/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { PathData, AppRoutePath, ActiveFn, ActivePath } from './checkActive';
import type { PathData, AppRoutePath, ActiveFn, ActivePath, FindActivePathReturn } from './checkActive';

export const isDev = process.env.NODE_ENV === 'development';

Expand Down Expand Up @@ -96,35 +96,20 @@ export function addLeadingSlash(path: string): string {
return path.charAt(0) === '/' ? path : `/${path}`;
}

/**
* It's difficult to dig out the actual path url, so comes the
* following function.
*/
export const getActualUrlFromPath = (path: AppRoutePath): string => {
if (Array.isArray(path)) {
return (typeof path[0] === 'string' ? path[0] : path[0].value);
}
if (isObject<PathData>(path)) {
return path.value;
}
return path;
};

/**
* Get basename for micro apps to use handily.
* A properly formatted basename has a leading slash, but not trailing slash.
*/
export const getAppBasename = (path: AppRoutePath = '', frameworkBase?: string, appBase?: string): string => {
const actualPath = addLeadingSlash(getActualUrlFromPath(path));
export const getAppBasename = (path = '', appBase?: string): string => {
const actualPath = addLeadingSlash(path);

const leadingSlashFrameworkBase = frameworkBase && addLeadingSlash(frameworkBase);
const leadingSlashAppBase = appBase && addLeadingSlash(appBase);

/**
* It's preferable to use `??` bewteen leadingSlashAppBase and actualPath. But some
* users already use the misunderstanding `basename=''`, which we have to keep things the way they are.
*/
return `${leadingSlashFrameworkBase}${leadingSlashAppBase || actualPath}`;
return `${leadingSlashAppBase || actualPath}`;
};

/**
Expand Down
1 change: 0 additions & 1 deletion website/docs/api/ice-stark.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ interface AppConfig {
basename?: string;
umd?: boolean;
loadScriptMode?: 'fetch' | 'script' | 'import';
checkActive?: (url: string) => boolean;
appAssets?: Assets;
props?: object;
cached?: boolean;
Expand Down

0 comments on commit 2289f25

Please sign in to comment.