From 78df5e2af7a9d065ecbb46263022c79fefc245c5 Mon Sep 17 00:00:00 2001 From: daysai Date: Thu, 31 Oct 2019 18:19:28 +0800 Subject: [PATCH 01/11] fix: rm localUrl api --- src/AppRouter.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/AppRouter.tsx b/src/AppRouter.tsx index 0ee8707d..52d876c3 100644 --- a/src/AppRouter.tsx +++ b/src/AppRouter.tsx @@ -156,8 +156,7 @@ export default class AppRouter extends React.Component Date: Thu, 31 Oct 2019 18:20:05 +0800 Subject: [PATCH 02/11] fix: rm localUrl --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b407de7..9fab5560 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ice/stark", - "version": "1.0.0", + "version": "1.0.1", "description": "Icestark is a JavaScript library for multiple projects, Ice workbench solution.", "scripts": { "build": "rm -rf lib && tsc", From 2b6b22cd28318a3aa849dba9d38e7b8a00c97bf7 Mon Sep 17 00:00:00 2001 From: Ya Zhuang Date: Tue, 5 Nov 2019 17:37:16 +0800 Subject: [PATCH 03/11] chore: migrate testing-library ref https://github.com/testing-library/dom-testing-library/issues/260 --- jest.setup.ts | 1 + package.json | 7 ++++--- packages/icestark-app/tests/index.spec.tsx | 2 -- tests/index.spec.tsx | 5 +---- 4 files changed, 6 insertions(+), 9 deletions(-) create mode 100644 jest.setup.ts diff --git a/jest.setup.ts b/jest.setup.ts new file mode 100644 index 00000000..666127af --- /dev/null +++ b/jest.setup.ts @@ -0,0 +1 @@ +import '@testing-library/jest-dom/extend-expect'; diff --git a/package.json b/package.json index 2b407de7..c4b936d3 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,8 @@ "@commitlint/cli": "^7.5.2", "@commitlint/config-conventional": "^7.5.0", "@ice/spec": "^0.1.4", + "@testing-library/react": "^9.3.2", + "@testing-library/jest-dom": "^4.2.3", "@types/jest": "^24.0.12", "@types/node": "^12.0.0", "@types/path-to-regexp": "^1.7.0", @@ -54,17 +56,16 @@ "@types/url-parse": "^1.4.3", "codecov": "^3.4.0", "eslint": "^5.16.0", - "stylelint": "^10.1.0", "husky": "^2.2.0", "jest": "^24.7.1", - "jest-dom": "^3.4.0", "react": "^16.7.0", "react-dom": "^16.7.0", - "react-testing-library": "^7.0.0", + "stylelint": "^10.1.0", "ts-jest": "^24.0.2", "typescript": "^3.4.4" }, "jest": { + "setupFilesAfterEnv": ["./jest.setup.ts"], "coverageDirectory": "./coverage/", "collectCoverage": true, "preset": "ts-jest" diff --git a/packages/icestark-app/tests/index.spec.tsx b/packages/icestark-app/tests/index.spec.tsx index 9d6af95e..ea2a7558 100644 --- a/packages/icestark-app/tests/index.spec.tsx +++ b/packages/icestark-app/tests/index.spec.tsx @@ -1,5 +1,3 @@ -import 'jest-dom/extend-expect'; - import { getBasename, getMountNode, diff --git a/tests/index.spec.tsx b/tests/index.spec.tsx index d213dd22..b1c4a867 100644 --- a/tests/index.spec.tsx +++ b/tests/index.spec.tsx @@ -1,8 +1,5 @@ -import 'react-testing-library/cleanup-after-each'; -import 'jest-dom/extend-expect'; - import * as React from 'react'; -import { render } from 'react-testing-library'; +import { render } from '@testing-library/react'; import { AppRouter, AppRoute, AppLink, appHistory } from '../src/index'; import matchPath from '../src/matchPath'; import { loadAssets } from '../src/handleAssets'; From bb3d0c89b780c207f50e40c4a70c01a519430672 Mon Sep 17 00:00:00 2001 From: daysai Date: Wed, 6 Nov 2019 16:47:50 +0800 Subject: [PATCH 04/11] feat: add AppRoute render/component props --- package.json | 6 +- packages/icestark-app/package.json | 4 +- packages/icestark-app/tests/index.spec.tsx | 2 +- src/AppRoute.tsx | 37 +--- src/AppRouter.tsx | 55 +++-- src/handleAssets.ts | 2 +- tests/index.spec.tsx | 229 +++++++++++++++++---- 7 files changed, 248 insertions(+), 87 deletions(-) diff --git a/package.json b/package.json index 9fab5560..d4386ac0 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,8 @@ "@commitlint/cli": "^7.5.2", "@commitlint/config-conventional": "^7.5.0", "@ice/spec": "^0.1.4", + "@testing-library/jest-dom": "^4.2.3", + "@testing-library/react": "^9.3.2", "@types/jest": "^24.0.12", "@types/node": "^12.0.0", "@types/path-to-regexp": "^1.7.0", @@ -54,13 +56,11 @@ "@types/url-parse": "^1.4.3", "codecov": "^3.4.0", "eslint": "^5.16.0", - "stylelint": "^10.1.0", "husky": "^2.2.0", "jest": "^24.7.1", - "jest-dom": "^3.4.0", "react": "^16.7.0", "react-dom": "^16.7.0", - "react-testing-library": "^7.0.0", + "stylelint": "^10.1.0", "ts-jest": "^24.0.2", "typescript": "^3.4.4" }, diff --git a/packages/icestark-app/package.json b/packages/icestark-app/package.json index 3334547b..183abe22 100644 --- a/packages/icestark-app/package.json +++ b/packages/icestark-app/package.json @@ -38,14 +38,14 @@ "@commitlint/cli": "^7.5.2", "@commitlint/config-conventional": "^7.5.0", "@ice/spec": "^0.1.4", + "@testing-library/jest-dom": "^4.2.3", "@types/jest": "^24.0.12", "@types/node": "^12.0.0", "codecov": "^3.4.0", "eslint": "^5.16.0", - "stylelint": "^10.1.0", "husky": "^2.2.0", "jest": "^24.7.1", - "jest-dom": "^3.4.0", + "stylelint": "^10.1.0", "ts-jest": "^24.0.2", "typescript": "^3.4.4" }, diff --git a/packages/icestark-app/tests/index.spec.tsx b/packages/icestark-app/tests/index.spec.tsx index 9d6af95e..53d69ef7 100644 --- a/packages/icestark-app/tests/index.spec.tsx +++ b/packages/icestark-app/tests/index.spec.tsx @@ -1,4 +1,4 @@ -import 'jest-dom/extend-expect'; +import '@testing-library/jest-dom/extend-expect'; import { getBasename, diff --git a/src/AppRoute.tsx b/src/AppRoute.tsx index 7b4eed1d..71ecc9a8 100644 --- a/src/AppRoute.tsx +++ b/src/AppRoute.tsx @@ -1,7 +1,6 @@ import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { loadAssets, emptyAssets } from './handleAssets'; -import { ICESTSRK_NOT_FOUND } from './constant'; import { setCache, getCache } from './cache'; const statusElementId = 'icestarkStatusContainer'; @@ -35,11 +34,12 @@ export interface AppConfig { export interface AppRouteProps extends AppConfig { path: string | string[]; - url: string | string[]; + url?: string | string[]; useShadow?: boolean; ErrorComponent?: any; LoadingComponent?: any; - NotFoundComponent?: any; + component?: React.ReactElement; + render?: () => React.ReactElement; forceRenderCount?: number; onAppEnter?: (appConfig: AppConfig) => void; onAppLeave?: (appConfig: AppConfig) => void; @@ -60,8 +60,6 @@ function getAppConfig(appRouteProps: AppRouteProps): AppConfig { 'useShadow', 'ErrorComponent', 'LoadingComponent', - 'NotFoundComponent', - 'useShadow', 'onAppEnter', 'onAppLeave', ]; @@ -84,8 +82,6 @@ export default class AppRoute extends React.Component { const { - path, url, title, rootId, ErrorComponent, LoadingComponent, - NotFoundComponent, useShadow, onAppEnter, onAppLeave, @@ -162,7 +156,7 @@ export default class AppRoute extends React.Componentjs bundle loaded error, + onRouteChange: () => {}, + ErrorComponent: ({ err }) =>
{err}
, NotFoundComponent:
NotFound
, useShadow: false, }; @@ -76,15 +78,21 @@ export default class AppRouter extends React.Component { - this.setState({ url: ICESTSRK_NOT_FOUND }); - }); + window.addEventListener('icestark:not-found', this.triggerNotFound); } componentWillUnmount() { this.unHijackHistory(); + window.removeEventListener('icestark:not-found', this.triggerNotFound); } + /** + * Trigger NotFound + */ + triggerNotFound = () => { + this.setState({ url: ICESTSRK_NOT_FOUND }); + }; + /** * Hijack window.history */ @@ -103,7 +111,7 @@ export default class AppRouter extends React.Component { window.history.pushState = this.originalPush; @@ -144,6 +152,17 @@ export default class AppRouter extends React.Component { + return React.isValidElement(Component) ? ( + React.cloneElement(Component, props) + ) : ( + + ); + }; + render() { const { NotFoundComponent, @@ -156,7 +175,7 @@ export default class AppRouter extends React.Component - ); + return this.renderElement(NotFoundComponent, {}); } } diff --git a/src/handleAssets.ts b/src/handleAssets.ts index 05ac0cb1..4180528a 100644 --- a/src/handleAssets.ts +++ b/src/handleAssets.ts @@ -39,7 +39,7 @@ function loadAsset( element.addEventListener( 'error', () => { - callback(isCss ? undefined : new Error(`JS asset loaded error: ${url}`)); + callback(isCss ? undefined : `JS asset loaded error: ${url}`); }, false, ); diff --git a/tests/index.spec.tsx b/tests/index.spec.tsx index d213dd22..dee70030 100644 --- a/tests/index.spec.tsx +++ b/tests/index.spec.tsx @@ -1,11 +1,12 @@ -import 'react-testing-library/cleanup-after-each'; -import 'jest-dom/extend-expect'; +import '@testing-library/react/cleanup-after-each'; +import '@testing-library/jest-dom/extend-expect'; import * as React from 'react'; -import { render } from 'react-testing-library'; +import { render, fireEvent } from '@testing-library/react'; import { AppRouter, AppRoute, AppLink, appHistory } from '../src/index'; import matchPath from '../src/matchPath'; -import { loadAssets } from '../src/handleAssets'; +import { loadAssets, recordAssets } from '../src/handleAssets'; +import { setCache, getCache } from '../src/cache'; describe('AppRouter', () => { test('render the AppRouter', () => { @@ -14,43 +15,137 @@ describe('AppRouter', () => { useShadow: false, NotFoundComponent:
NotFound
, }; - const { container, getByTestId } = render(); + const { getByTestId } = render(); - const appRouteNode = container.querySelector('.ice-stark-loaded'); const textNode = getByTestId('icestarkDefalut'); - expect(appRouteNode.childNodes.length).toBe(2); expect(textNode).toHaveTextContent('NotFound'); expect(props.onRouteChange).toHaveBeenCalledTimes(1); + + window.history.pushState({}, 'test', '/#/test'); + expect(props.onRouteChange).toHaveBeenCalledTimes(2); + + window.history.replaceState({ forceRender: true }, 'test2', '/#/test2'); + expect(props.onRouteChange).toHaveBeenCalledTimes(3); }); -}); -describe('AppRoute', () => { - test('render the AppRoute', () => { + test('test for AppRoute Component', () => { + window.history.pushState({}, 'test', '/'); + const props = { - path: '/', - url: [], - title: '主页', - useShadow: false, + onRouteChange: jest.fn(), LoadingComponent:
Loading
, }; - const { container } = render(); + const { container, rerender, unmount, getByText } = render( + + test} /> + , + ); + + expect(container.innerHTML).toContain('test'); + expect(props.onRouteChange).toHaveBeenCalledTimes(1); + + rerender( + + ( +
+ test + + +
+ )} + /> +
, + ); + + expect(container.innerHTML).toContain('test'); + expect(props.onRouteChange).toHaveBeenCalledTimes(1); + + fireEvent.click(getByText(/Jump NotFound/i)); + expect(container.innerHTML).toContain('NotFound'); + + fireEvent.click(getByText(/Jump Hash/i)); + expect(props.onRouteChange).toHaveBeenCalledTimes(2); + + /** + * test for HashType + */ + rerender( + + + , + ); const appRouteNode = container.querySelector('.ice-stark-loading'); + expect(container.innerHTML).toContain('Loading'); expect(appRouteNode.childNodes.length).toBe(2); - }); - test('render the AppRoute without LoadingComponent', () => { - const props = { - path: '/', - url: [], - title: '主页', - useShadow: false, - }; - const { container } = render(); + /** + * Load assets error + */ + rerender( + + + , + ); + expect(container.innerHTML).toContain('Loading'); - const appRouteNode = container.querySelector('.ice-stark-loading'); - expect(appRouteNode.childNodes.length).toBe(1); + const dynamicScript = document.querySelector('[icestark=dynamic]'); + expect(dynamicScript.id).toBe('icestark-js-0'); + expect(dynamicScript.getAttribute('src')).toBe('//icestark.com/js/index.js'); + + dynamicScript.dispatchEvent(new ErrorEvent('error')); + expect(container.innerHTML).toContain('JS asset loaded error: //icestark.com/js/index.js'); + + /** + * Load assets success + */ + setCache('appLeave', () => {}); + + // HTMLElement.attachShadow = jest.fn(); + + rerender( + + + , + ); + expect(getCache('appLeave')).toBeNull(); + + // js load success + const dynamicScriptLoaded = document.querySelector('script[icestark=dynamic]'); + expect(dynamicScriptLoaded.getAttribute('id')).toBe('icestark-js-0'); + expect(dynamicScriptLoaded.getAttribute('type')).toBe('text/javascript'); + expect(dynamicScriptLoaded.getAttribute('src')).toBe('//icestark.com/js/index.js'); + + dynamicScriptLoaded.dispatchEvent(new Event('load')); + expect(container.querySelector('.ice-stark-loading').childNodes.length).toBe(1); + + // css load success + const dynamicLinkLoaded = document.querySelector('link[icestark=dynamic]'); + expect(dynamicLinkLoaded.getAttribute('id')).toBe('icestark-css-0'); + expect(dynamicLinkLoaded.getAttribute('rel')).toBe('stylesheet'); + expect(dynamicLinkLoaded.getAttribute('href')).toBe('//icestark.com/css/index.css'); + + dynamicLinkLoaded.dispatchEvent(new Event('load')); + expect(container.querySelector('.ice-stark-loaded').childNodes.length).toBe(1); + + unmount(); }); }); @@ -58,34 +153,68 @@ describe('AppLink', () => { test('render the AppLink', () => { const className = 'ice-stark-test'; const props = { - to: 'www.taobao.com', + to: '/test', className, }; const TestText = 'This is a test'; - const { container } = render({TestText}); + const { container, getByText, rerender } = render({TestText}); const appLinkNode = container.querySelector(`.${className}`); expect(appLinkNode).toHaveTextContent(TestText); expect(appLinkNode).toHaveAttribute('href'); + + const mockPushState = jest.fn(); + window.history.pushState = mockPushState; + + fireEvent.click(getByText(/This is a test/i)); + expect(mockPushState.mock.calls.length).toBe(1); + + rerender( + + {TestText} + , + ); + const mockReplaceState = jest.fn(); + window.history.replaceState = mockReplaceState; + + fireEvent.click(getByText(/This is a test/i)); + expect(mockReplaceState.mock.calls.length).toBe(1); }); }); describe('matchPath', () => { test('matchPath', () => { - expect(matchPath('/test/123', { path: '/test' })).not.toBeNull(); - expect(matchPath('/test/123', { path: '/test/:id' })).not.toBeNull(); - expect(matchPath('/test/123', { path: '/test', exact: true })).toBeNull(); + let match = matchPath('/test/123'); + expect(match).toBeNull(); + + match = matchPath('/test/123', '/test'); + expect(match.url).toBe('/test'); + + match = matchPath('/test/123', { path: '/test' }); + expect(match.url).toBe('/test'); + + match = matchPath('/test/123', { path: '/test/:id' }); + expect(match.url).toBe('/test/123'); + expect(match.params.id).toBe('123'); + + match = matchPath('/test/123', { path: ['/test/:id', '/test/:id/detail'] }); + expect(match.url).toBe('/test/123'); + expect(match.path).toBe('/test/:id'); + expect(match.params.id).toBe('123'); + + match = matchPath('/test/123', { path: '/test', exact: true }); + expect(match).toBeNull(); }); }); -describe('loadAssets', () => { +describe('handleAssets', () => { test('loadAssets', () => { loadAssets( [ - 'http://icestark.com/test.js', - 'http://icestark.com/test.css', - 'http://icestark.com/test1.js', + 'http://icestark.com/js/index.js', + 'http://icestark.com/css/index.css', + 'http://icestark.com/js/test1.js', ], false, jest.fn(), @@ -94,10 +223,36 @@ describe('loadAssets', () => { const jsElement0 = document.getElementById('icestark-js-0'); const jsElement1 = document.getElementById('icestark-js-1'); - expect((jsElement0 as HTMLScriptElement).src).toEqual('http://icestark.com/test.js'); + expect((jsElement0 as HTMLScriptElement).src).toEqual('http://icestark.com/js/index.js'); expect((jsElement0 as HTMLScriptElement).async).toEqual(false); - expect((jsElement1 as HTMLScriptElement).src).toEqual('http://icestark.com/test1.js'); + expect((jsElement1 as HTMLScriptElement).src).toEqual('http://icestark.com/js/test1.js'); expect((jsElement1 as HTMLScriptElement).async).toEqual(false); + + recordAssets(); + + expect(jsElement0.getAttribute('icestark')).toEqual('static'); + expect(jsElement1.getAttribute('icestark')).toEqual('static'); + }); + + test('recordAssets', () => { + const jsElement = document.createElement('script'); + jsElement.id = 'icestark-script'; + + const linkElement = document.createElement('link'); + linkElement.id = 'icestark-link'; + + const styleElement = document.createElement('style'); + styleElement.id = 'icestark-style'; + + document.body.appendChild(jsElement); + document.body.appendChild(linkElement); + document.body.appendChild(styleElement); + + recordAssets(); + + expect(jsElement.getAttribute('icestark')).toEqual('static'); + expect(linkElement.getAttribute('icestark')).toEqual('static'); + expect(styleElement.getAttribute('icestark')).toEqual('static'); }); }); From df80d50583a61a1262c26b43b714182e4f50a09b Mon Sep 17 00:00:00 2001 From: daysai Date: Wed, 6 Nov 2019 17:22:28 +0800 Subject: [PATCH 05/11] chore: rm setupFilesAfterEnv --- jest.setup.ts | 1 - package.json | 3 --- 2 files changed, 4 deletions(-) delete mode 100644 jest.setup.ts diff --git a/jest.setup.ts b/jest.setup.ts deleted file mode 100644 index 666127af..00000000 --- a/jest.setup.ts +++ /dev/null @@ -1 +0,0 @@ -import '@testing-library/jest-dom/extend-expect'; diff --git a/package.json b/package.json index c62b2800..3f67c1da 100644 --- a/package.json +++ b/package.json @@ -65,9 +65,6 @@ "typescript": "^3.4.4" }, "jest": { - "setupFilesAfterEnv": [ - "./jest.setup.ts" - ], "coverageDirectory": "./coverage/", "collectCoverage": true, "preset": "ts-jest" From e7cdaccad5a7c320a1b965bfa2cff19dee7a836e Mon Sep 17 00:00:00 2001 From: daysai Date: Tue, 12 Nov 2019 21:17:01 +0800 Subject: [PATCH 06/11] fix: adjust for cr --- src/AppRoute.tsx | 2 +- src/AppRouter.tsx | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/AppRoute.tsx b/src/AppRoute.tsx index 71ecc9a8..e95fc38a 100644 --- a/src/AppRoute.tsx +++ b/src/AppRoute.tsx @@ -39,7 +39,7 @@ export interface AppRouteProps extends AppConfig { ErrorComponent?: any; LoadingComponent?: any; component?: React.ReactElement; - render?: () => React.ReactElement; + render?: (props?: object) => React.ReactElement; forceRenderCount?: number; onAppEnter?: (appConfig: AppConfig) => void; onAppLeave?: (appConfig: AppConfig) => void; diff --git a/src/AppRouter.tsx b/src/AppRouter.tsx index 0039b597..3757dd9c 100644 --- a/src/AppRouter.tsx +++ b/src/AppRouter.tsx @@ -52,6 +52,17 @@ function getHashPath(hash: string = '/'): string { return searchIndex === -1 ? hashPath : hashPath.substr(0, searchIndex); } +/** + * Render Component + */ +function renderComponent(Component: any, props = {}): React.ReactElement { + return React.isValidElement(Component) ? ( + React.cloneElement(Component, props) + ) : ( + + ); +} + export default class AppRouter extends React.Component { private originalPush: OriginalStateFunction = window.history.pushState; @@ -152,17 +163,6 @@ export default class AppRouter extends React.Component { - return React.isValidElement(Component) ? ( - React.cloneElement(Component, props) - ) : ( - - ); - }; - render() { const { NotFoundComponent, @@ -212,11 +212,11 @@ export default class AppRouter extends React.Component Date: Tue, 12 Nov 2019 21:22:34 +0800 Subject: [PATCH 07/11] fix: adjust JS asset to js asset --- src/handleAssets.ts | 2 +- tests/index.spec.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/handleAssets.ts b/src/handleAssets.ts index 4180528a..2e862555 100644 --- a/src/handleAssets.ts +++ b/src/handleAssets.ts @@ -39,7 +39,7 @@ function loadAsset( element.addEventListener( 'error', () => { - callback(isCss ? undefined : `JS asset loaded error: ${url}`); + callback(isCss ? undefined : `js asset loaded error: ${url}`); }, false, ); diff --git a/tests/index.spec.tsx b/tests/index.spec.tsx index dee70030..48f48245 100644 --- a/tests/index.spec.tsx +++ b/tests/index.spec.tsx @@ -111,7 +111,7 @@ describe('AppRouter', () => { expect(dynamicScript.getAttribute('src')).toBe('//icestark.com/js/index.js'); dynamicScript.dispatchEvent(new ErrorEvent('error')); - expect(container.innerHTML).toContain('JS asset loaded error: //icestark.com/js/index.js'); + expect(container.innerHTML).toContain('js asset loaded error: //icestark.com/js/index.js'); /** * Load assets success From b0a0a19e7f468855daafc2ba24800b7decee25a5 Mon Sep 17 00:00:00 2001 From: daysai Date: Wed, 13 Nov 2019 10:30:27 +0800 Subject: [PATCH 08/11] fix: rm useless cleanup-after-each --- tests/index.spec.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/index.spec.tsx b/tests/index.spec.tsx index 48f48245..62547c9b 100644 --- a/tests/index.spec.tsx +++ b/tests/index.spec.tsx @@ -1,4 +1,3 @@ -import '@testing-library/react/cleanup-after-each'; import '@testing-library/jest-dom/extend-expect'; import * as React from 'react'; From 324f9e95f6d64690e321f19fccd51fd886db5dc8 Mon Sep 17 00:00:00 2001 From: daysai Date: Wed, 13 Nov 2019 11:25:01 +0800 Subject: [PATCH 09/11] feat: add AppRouteComponentProps ts --- src/AppRoute.tsx | 22 +++++++++++++++++++++- src/AppRouter.tsx | 10 +++++++--- src/appHistory.ts | 15 ++++++++++----- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/AppRoute.tsx b/src/AppRoute.tsx index e95fc38a..387ff857 100644 --- a/src/AppRoute.tsx +++ b/src/AppRoute.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import * as ReactDOM from 'react-dom'; +import { AppHistory } from './appHistory'; import { loadAssets, emptyAssets } from './handleAssets'; import { setCache, getCache } from './cache'; @@ -22,6 +23,25 @@ interface AppRouteState { // "hashbang" - “ajax crawlable” (deprecated by Google) hashes like #!/ and #!/sunshine/lollipops type hashType = 'hashbang' | 'noslash' | 'slash'; +interface match { + params: Params; + isExact: boolean; + path: string; + url: string; +} + +interface Location { + pathname: string; + query: Query; + hash: string; +} + +export interface AppRouteComponentProps { + match: match; + location: Location; + history: AppHistory; +} + export interface AppConfig { title?: string; hashType?: boolean | hashType; @@ -39,7 +59,7 @@ export interface AppRouteProps extends AppConfig { ErrorComponent?: any; LoadingComponent?: any; component?: React.ReactElement; - render?: (props?: object) => React.ReactElement; + render?: (props?: AppRouteComponentProps) => React.ReactElement; forceRenderCount?: number; onAppEnter?: (appConfig: AppConfig) => void; onAppLeave?: (appConfig: AppConfig) => void; diff --git a/src/AppRouter.tsx b/src/AppRouter.tsx index 3757dd9c..37ba18d1 100644 --- a/src/AppRouter.tsx +++ b/src/AppRouter.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import * as urlParse from 'url-parse'; -import { AppConfig, AppRouteProps } from './AppRoute'; +import { AppConfig, AppRouteProps, AppRouteComponentProps } from './AppRoute'; import appHistory from './appHistory'; import matchPath from './matchPath'; import { recordAssets } from './handleAssets'; @@ -53,7 +53,7 @@ function getHashPath(hash: string = '/'): string { } /** - * Render Component + * Render Component, compatible with Component and */ function renderComponent(Component: any, props = {}): React.ReactElement { return React.isValidElement(Component) ? ( @@ -209,7 +209,11 @@ export default class AppRouter extends React.Component { +export interface AppHistory { + push(path: string): void; + replace(path: string): void; +} + +const appHistory: AppHistory = { + push: (path: string) => { window.history.pushState( { forceRender: true, }, null, - url, + path, ); }, - replace: (url: string) => { + replace: (path: string) => { window.history.replaceState( { forceRender: true, }, null, - url, + path, ); }, }; From 5b7f6a3fa240fd6d995832963b3b733e492d9356 Mon Sep 17 00:00:00 2001 From: daysai Date: Wed, 13 Nov 2019 11:25:44 +0800 Subject: [PATCH 10/11] chore: update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3f67c1da..959e357a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ice/stark", - "version": "1.0.1", + "version": "1.1.0", "description": "Icestark is a JavaScript library for multiple projects, Ice workbench solution.", "scripts": { "build": "rm -rf lib && tsc", From 2e114a50b75cfe686b750f9564b948e31e8e4b96 Mon Sep 17 00:00:00 2001 From: daysai Date: Wed, 13 Nov 2019 11:47:31 +0800 Subject: [PATCH 11/11] fix: interface match to Match --- src/AppRoute.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AppRoute.tsx b/src/AppRoute.tsx index 387ff857..6148c5d0 100644 --- a/src/AppRoute.tsx +++ b/src/AppRoute.tsx @@ -23,7 +23,7 @@ interface AppRouteState { // "hashbang" - “ajax crawlable” (deprecated by Google) hashes like #!/ and #!/sunshine/lollipops type hashType = 'hashbang' | 'noslash' | 'slash'; -interface match { +interface Match { params: Params; isExact: boolean; path: string; @@ -37,7 +37,7 @@ interface Location { } export interface AppRouteComponentProps { - match: match; + match: Match; location: Location; history: AppHistory; }