Skip to content

Commit

Permalink
🚨 add linter/prettier and fix errors (#98)
Browse files Browse the repository at this point in the history
  • Loading branch information
howel52 authored and kuitos committed Oct 8, 2019
1 parent fc2f1eb commit e9885af
Show file tree
Hide file tree
Showing 16 changed files with 140 additions and 191 deletions.
10 changes: 10 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const fabric = require('@umijs/fabric');

module.exports = {
...fabric.eslint,
rules: {
...fabric.eslint.rules,
'@typescript-eslint/prefer-interface': 0,
'no-return-assign': 0
},
};
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ yarn.lock
esm
lib
package-lock.json
.eslintcache
5 changes: 5 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const fabric = require('@umijs/fabric');

module.exports = {
...fabric.prettier,
};
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
"prepush": "npm run lint",
"release": "np --no-cleanup --yolo --no-publish",
"prepublishOnly": "npm run lint && npm run build",
"lint": "tslint 'src/**/*.ts'",
"lint": "eslint --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src && npm run lint:prettier",
"lint:prettier": "check-prettier lint",
"prettier": "prettier -c --write **/*",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
Expand All @@ -42,14 +44,15 @@
},
"devDependencies": {
"@types/lodash": "^4.14.129",
"@umijs/fabric": "^1.1.10",
"babel-plugin-import": "^1.12.1",
"check-prettier": "^1.0.3",
"concurrently": "^4.1.2",
"father-build": "^1.7.0",
"husky": "^2.3.0",
"np": "^5.0.3",
"prettier": "^1.18.2",
"rimraf": "^3.0.0",
"tslint": "^5.16.0",
"tslint-eslint-rules": "^5.4.0",
"typescript": "^3.4.5"
}
}
41 changes: 24 additions & 17 deletions src/effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,35 @@ if (process.env.NODE_ENV === 'development') {
}

export function setDefaultMountApp(defaultAppLink: string) {

window.addEventListener('single-spa:no-app-change', () => {
const mountedApps = getMountedApps();
if (!mountedApps.length) {
navigateToUrl(defaultAppLink);
}
}, { once: true });
window.addEventListener(
'single-spa:no-app-change',
() => {
const mountedApps = getMountedApps();
if (!mountedApps.length) {
navigateToUrl(defaultAppLink);
}
},
{ once: true },
);
}

export function runDefaultMountEffects(defaultAppLink: string) {
console.warn('runDefaultMountEffects will be removed in next version, please use setDefaultMountApp instead!');
console.warn(
'runDefaultMountEffects will be removed in next version, please use setDefaultMountApp instead!',
);
setDefaultMountApp(defaultAppLink);
}

export function runAfterFirstMounted(effect: () => void) {

window.addEventListener('single-spa:first-mount', () => {

if (process.env.NODE_ENV === 'development') {
console.timeEnd(firstMountLogLabel);
}

effect();
}, { once: true });
window.addEventListener(
'single-spa:first-mount',
() => {
if (process.env.NODE_ENV === 'development') {
console.timeEnd(firstMountLogLabel);
}

effect();
},
{ once: true },
);
}
6 changes: 2 additions & 4 deletions src/hijackers/historyListener.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/array-type */

/**
* @author Kuitos
* @since 2019-04-11
Expand All @@ -6,19 +8,16 @@
import { isFunction, noop } from 'lodash';

export default function hijack() {

// FIXME umi unmount feature request
// @see http://gitlab.alipay-inc.com/bigfish/bigfish/issues/1154
let rawHistoryListen = (..._: any[]) => noop;
const historyListeners: Array<typeof noop> = [];
const historyUnListens: Array<typeof noop> = [];

if ((window as any).g_history && isFunction((window as any).g_history.listen)) {

rawHistoryListen = (window as any).g_history.listen.bind((window as any).g_history);

(window as any).g_history.listen = (listener: typeof noop) => {

historyListeners.push(listener);

const unListen = rawHistoryListen(listener);
Expand All @@ -33,7 +32,6 @@ export default function hijack() {
}

return function free() {

let rebuild = noop;

/*
Expand Down
2 changes: 0 additions & 2 deletions src/hijackers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ import hijackTimer from './timer';
import hijackWindowListener from './windowListener';

export function hijack(): Freer[] {

return [
hijackTimer(),
hijackWindowListener(),
hijackHistoryListener(),
];

}
1 change: 0 additions & 1 deletion src/hijackers/timer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { noop } from 'lodash';
import { sleep } from '../utils';

export default function hijack() {

const rawWindowInterval = window.setInterval;
const rawWindowTimeout = window.setTimeout;
const timerIds: number[] = [];
Expand Down
25 changes: 17 additions & 8 deletions src/hijackers/windowListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,39 @@
import { noop } from 'lodash';

export default function hijack() {

const listenerMap = new Map<string, EventListenerOrEventListenerObject[]>();
const rawAddEventListener = window.addEventListener;
const rawRemoveEventListener = window.removeEventListener;

window.addEventListener =
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions) => {
window.addEventListener = (
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
) => {
const listeners = listenerMap.get(type) || [];
listenerMap.set(type, [...listeners, listener]);
return rawAddEventListener.call(window, type, listener, options);
};

window.removeEventListener =
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions) => {
window.removeEventListener = (
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
) => {
const storedTypeListeners = listenerMap.get(type);
if (storedTypeListeners && storedTypeListeners.length && storedTypeListeners.indexOf(listener) !== -1) {
if (
storedTypeListeners && storedTypeListeners.length
&& storedTypeListeners.indexOf(listener) !== -1
) {
storedTypeListeners.splice(storedTypeListeners.indexOf(listener), 1);
}
return rawRemoveEventListener.call(window, type, listener, options);
};

return function free() {

listenerMap.forEach((listeners, type) => [...listeners].forEach(listener => window.removeEventListener(type, listener)));
listenerMap
.forEach((listeners, type) => [...listeners]
.forEach(listener => window.removeEventListener(type, listener)));
window.addEventListener = rawAddEventListener;
window.removeEventListener = rawRemoveEventListener;

Expand Down
48 changes: 30 additions & 18 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/array-type */

/**
* @author Kuitos
* @since 2019-04-25
Expand Down Expand Up @@ -32,22 +34,29 @@ function toArray<T>(array: T | T[]): T[] {
return Array.isArray(array) ? array : [array];
}

function execHooksChain<T extends object>(hooks: Array<Lifecycle<T>>, app: RegistrableApp<T>): Promise<any> {
function execHooksChain<T extends object>(
hooks: Array<Lifecycle<T>>,
app: RegistrableApp<T>,
): Promise<any> {
if (hooks.length) {
return hooks.reduce((chain, hook) => chain.then(() => hook(app)), Promise.resolve());
}

return Promise.resolve();
}

async function validateSingularMode<T extends object>(validate: StartOpts['singular'], app: RegistrableApp<T>): Promise<boolean> {
async function validateSingularMode<T extends object>(
validate: StartOpts['singular'],
app: RegistrableApp<T>,
): Promise<boolean> {
return typeof validate === 'function' ? validate(app) : !!validate;
}

class Deferred<T> {

promise: Promise<T>;

resolve!: (value?: T | PromiseLike<T>) => void;

reject!: (reason?: any) => void;

constructor() {
Expand All @@ -58,21 +67,28 @@ class Deferred<T> {
}
}

export function registerMicroApps<T extends object = {}>(apps: Array<RegistrableApp<T>>, lifeCycles: LifeCycles<T> = {}) {

const { beforeUnmount = [], afterUnmount = [], afterMount = [], beforeMount = [], beforeLoad = [] } = lifeCycles;
export function registerMicroApps<T extends object = {}>(
apps: Array<RegistrableApp<T>>,
lifeCycles: LifeCycles<T> = {},
) {
const {
beforeUnmount = [],
afterUnmount = [],
afterMount = [],
beforeMount = [],
beforeLoad = [],
} = lifeCycles;
microApps = [...microApps, ...apps];

let prevAppUnmountedDeferred: Deferred<void>;

apps.forEach(app => {

const { name, entry, render, activeRule, props = {} } = app;

registerApplication(name,
registerApplication(
name,

async ({ name: appName }) => {

// 获取入口 html 模板及脚本加载器
const { template: appContent, execScripts } = await importEntry(entry);
// as single-spa load and bootstrap new app parallel with other apps unmounting
Expand Down Expand Up @@ -105,12 +121,9 @@ export function registerMicroApps<T extends object = {}>(apps: Array<Registrable
}

return {
bootstrap: [
bootstrapApp,
],
bootstrap: [bootstrapApp],
mount: [
async () =>
await validateSingularMode(singularMode, app) ? prevAppUnmountedDeferred && prevAppUnmountedDeferred.promise : void 0,
async () => (await validateSingularMode(singularMode, app) ? prevAppUnmountedDeferred && prevAppUnmountedDeferred.promise : undefined),
async () => execHooksChain(toArray(beforeMount), app),
// 添加 mount hook, 确保每次应用加载前容器 dom 结构已经设置完毕
async () => render({ appContent, loading: true }),
Expand All @@ -120,15 +133,14 @@ export function registerMicroApps<T extends object = {}>(apps: Array<Registrable
async () => render({ appContent, loading: false }),
async () => execHooksChain(toArray(afterMount), app),
// initialize the unmount defer after app mounted and resolve the defer after it unmounted
async () => await validateSingularMode(singularMode, app) ? prevAppUnmountedDeferred = new Deferred<void>() : void 0,
async () => (await validateSingularMode(singularMode, app) ? (prevAppUnmountedDeferred = new Deferred<void>()) : undefined),
],
unmount: [
async () => execHooksChain(toArray(beforeUnmount), app),
unmount,
unmountSandbox,
async () => execHooksChain(toArray(afterUnmount), app),
async () =>
await validateSingularMode(singularMode, app) ? prevAppUnmountedDeferred && prevAppUnmountedDeferred.resolve() : void 0,
async () => (await validateSingularMode(singularMode, app) ? prevAppUnmountedDeferred && prevAppUnmountedDeferred.resolve() : undefined),
],
};
},
Expand All @@ -149,7 +161,7 @@ let useJsSandbox = false;
let singularMode: StartOpts['singular'] = false;

export function start(opts: StartOpts = {}) {

// eslint-disable-next-line no-underscore-dangle
window.__POWERED_BY_QIANKUN__ = true;

const { prefetch = true, jsSandbox = true, singular = true } = opts;
Expand Down
16 changes: 9 additions & 7 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@
* @since 2019-05-16
*/

export type render = (props: { appContent: string, loading: boolean }) => any;
export type Entry = string | {
scripts?: string[];
styles?: string[];
html?: string;
};
export type render = (props: { appContent: string; loading: boolean }) => any;
export type Entry =
| string
| {
scripts?: string[];
styles?: string[];
html?: string;
};

export type RegistrableApp<T extends object = {}> = {
name: string; // app name
entry: Entry; // app entry
entry: Entry; // app entry
render: render;
activeRule: (location: Location) => boolean;
props?: T; // props pass through to app
Expand Down
29 changes: 14 additions & 15 deletions src/prefetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,28 @@ import { RegistrableApp } from './interfaces';
* @param entry
*/
export function prefetch(entry: Entry) {

const requestIdleCallback = window.requestIdleCallback || noop;

requestIdleCallback(async () => {
const { getExternalScripts, getExternalStyleSheets } = await importEntry(entry);
requestIdleCallback(getExternalStyleSheets);
requestIdleCallback(getExternalScripts);
});

}

export function prefetchAfterFirstMounted(apps: RegistrableApp[]) {

window.addEventListener('single-spa:first-mount', () => {

const mountedApps = getMountedApps();
const notMountedApps = apps.filter(app => mountedApps.indexOf(app.name) === -1);

if (process.env.NODE_ENV === 'development') {
console.log('prefetch starting...', notMountedApps);
}

notMountedApps.forEach(app => prefetch(app.entry));
}, { once: true });

window.addEventListener(
'single-spa:first-mount',
() => {
const mountedApps = getMountedApps();
const notMountedApps = apps.filter(app => mountedApps.indexOf(app.name) === -1);

if (process.env.NODE_ENV === 'development') {
console.log('prefetch starting...', notMountedApps);
}

notMountedApps.forEach(app => prefetch(app.entry));
},
{ once: true },
);
}
Loading

0 comments on commit e9885af

Please sign in to comment.