Commit 7e187a90 authored by 陈帅's avatar 陈帅

remove all code

parent 6639cbe4
...@@ -10,7 +10,6 @@ module.exports = { ...@@ -10,7 +10,6 @@ module.exports = {
jasmine: true, jasmine: true,
}, },
globals: { globals: {
ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: true, // preview.pro.ant.design only do not use in your production ; preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。
page: true, page: true,
}, },
rules: { rules: {
......
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
"overrides": [ "overrides": [
{ {
"files": ".prettierrc", "files": ".prettierrc",
"options": { "parser": "json" } "options": {
"parser": "json"
}
} }
] ]
} }
\ No newline at end of file
...@@ -121,7 +121,13 @@ export default { ...@@ -121,7 +121,13 @@ export default {
disableRedirectHoist: true, disableRedirectHoist: true,
cssLoaderOptions: { cssLoaderOptions: {
modules: true, modules: true,
getLocalIdent: (context, localIdentName, localName) => { getLocalIdent: (
context: {
resourcePath: string;
},
localIdentName: string,
localName: string,
) => {
if ( if (
context.resourcePath.includes('node_modules') || context.resourcePath.includes('node_modules') ||
context.resourcePath.includes('ant.design.pro.less') || context.resourcePath.includes('ant.design.pro.less') ||
...@@ -134,8 +140,8 @@ export default { ...@@ -134,8 +140,8 @@ export default {
const antdProPath = match[1].replace('.less', ''); const antdProPath = match[1].replace('.less', '');
const arr = slash(antdProPath) const arr = slash(antdProPath)
.split('/') .split('/')
.map(a => a.replace(/([A-Z])/g, '-$1')) .map((a: string) => a.replace(/([A-Z])/g, '-$1'))
.map(a => a.toLowerCase()); .map((a: string) => a.toLowerCase());
return `antd-pro${arr.join('-')}-${localName}`.replace(/--/g, '-'); return `antd-pro${arr.join('-')}-${localName}`.replace(/--/g, '-');
} }
return localName; return localName;
......
...@@ -54,9 +54,9 @@ ...@@ -54,9 +54,9 @@
"not ie <= 10" "not ie <= 10"
], ],
"dependencies": { "dependencies": {
"@ant-design/pro-layout": "^4.1.0", "@ant-design/pro-layout": "^4.2.0",
"@antv/data-set": "^0.10.1", "@antv/data-set": "^0.10.1",
"antd": "^3.16.1", "antd": "^3.18.1",
"bizcharts": "3.5.2-beta.1", "bizcharts": "3.5.2-beta.1",
"bizcharts-plugin-slider": "^2.1.1-beta.1", "bizcharts-plugin-slider": "^2.1.1-beta.1",
"classnames": "^2.2.6", "classnames": "^2.2.6",
......
...@@ -5,7 +5,3 @@ export const dva = { ...@@ -5,7 +5,3 @@ export const dva = {
}, },
}, },
}; };
export function render(oldRender) {
oldRender();
}
...@@ -6,7 +6,7 @@ import { IAuthorityType } from './CheckPermissions'; ...@@ -6,7 +6,7 @@ import { IAuthorityType } from './CheckPermissions';
interface IAuthorizedRoutePops { interface IAuthorizedRoutePops {
currentAuthority: string; currentAuthority: string;
component: React.ComponentClass<any, any>; component: React.ComponentClass<any, any>;
render: () => React.ReactNode; render: (props: any) => React.ReactNode;
redirectPath: string; redirectPath: string;
authority: IAuthorityType; authority: IAuthorityType;
} }
......
...@@ -17,12 +17,12 @@ export type IAuthorityType = ...@@ -17,12 +17,12 @@ export type IAuthorityType =
* @param { 通过的组件 | Passing components } target * @param { 通过的组件 | Passing components } target
* @param { 未通过的组件 | no pass components } Exception * @param { 未通过的组件 | no pass components } Exception
*/ */
const checkPermissions = ( const checkPermissions = <T, K>(
authority: IAuthorityType, authority: IAuthorityType,
currentAuthority: string | string[], currentAuthority: string | string[],
target: React.ComponentClass<any, any> | React.ReactNode, target: T,
Exception: React.ReactNode, Exception: K,
): React.ReactNode => { ): T | K | React.ReactNode => {
// 没有判定权限.默认查看所有 // 没有判定权限.默认查看所有
// Retirement authority, return target; // Retirement authority, return target;
if (!authority) { if (!authority) {
...@@ -52,7 +52,7 @@ const checkPermissions = ( ...@@ -52,7 +52,7 @@ const checkPermissions = (
} }
// Promise 处理 // Promise 处理
if (authority instanceof Promise) { if (authority instanceof Promise) {
return <PromiseRender ok={target} error={Exception} promise={authority} />; return <PromiseRender<T, K> ok={target} error={Exception} promise={authority} />;
} }
// Function 处理 // Function 处理
if (typeof authority === 'function') { if (typeof authority === 'function') {
...@@ -60,7 +60,7 @@ const checkPermissions = ( ...@@ -60,7 +60,7 @@ const checkPermissions = (
const bool = authority(currentAuthority); const bool = authority(currentAuthority);
// 函数执行后返回值是 Promise // 函数执行后返回值是 Promise
if (bool instanceof Promise) { if (bool instanceof Promise) {
return <PromiseRender ok={target} error={Exception} promise={bool} />; return <PromiseRender<T, K> ok={target} error={Exception} promise={bool} />;
} }
if (bool) { if (bool) {
return target; return target;
...@@ -75,10 +75,8 @@ const checkPermissions = ( ...@@ -75,10 +75,8 @@ const checkPermissions = (
export { checkPermissions }; export { checkPermissions };
const check = ( function check<T, K>(authority: IAuthorityType, target: T, Exception: K): T | K | React.ReactNode {
authority: IAuthorityType, return checkPermissions<T, K>(authority, CURRENT, target, Exception);
target: React.ComponentClass<any, any> | React.ReactNode, }
Exception: React.ReactNode,
): React.ReactNode => checkPermissions(authority, CURRENT, target, Exception);
export default check; export default check;
...@@ -4,9 +4,9 @@ import React from 'react'; ...@@ -4,9 +4,9 @@ import React from 'react';
// eslint-disable-next-line import/no-cycle // eslint-disable-next-line import/no-cycle
import { isComponentClass } from './Secured'; import { isComponentClass } from './Secured';
interface IPromiseRenderProps { interface IPromiseRenderProps<T, K> {
ok: React.ReactNode; ok: T;
error: React.ReactNode; error: K;
promise: Promise<any>; promise: Promise<any>;
} }
...@@ -14,8 +14,8 @@ interface IPromiseRenderState { ...@@ -14,8 +14,8 @@ interface IPromiseRenderState {
component: React.ComponentClass<any, any> | React.FunctionComponent<any>; component: React.ComponentClass<any, any> | React.FunctionComponent<any>;
} }
export default class PromiseRender extends React.Component< export default class PromiseRender<T, K> extends React.Component<
IPromiseRenderProps, IPromiseRenderProps<T, K>,
IPromiseRenderState IPromiseRenderState
> { > {
state: IPromiseRenderState = { state: IPromiseRenderState = {
...@@ -26,7 +26,10 @@ export default class PromiseRender extends React.Component< ...@@ -26,7 +26,10 @@ export default class PromiseRender extends React.Component<
this.setRenderComponent(this.props); this.setRenderComponent(this.props);
} }
shouldComponentUpdate = (nextProps: IPromiseRenderProps, nextState: IPromiseRenderState) => { shouldComponentUpdate = (
nextProps: IPromiseRenderProps<T, K>,
nextState: IPromiseRenderState,
) => {
const { component } = this.state; const { component } = this.state;
if (!isEqual(nextProps, this.props)) { if (!isEqual(nextProps, this.props)) {
this.setRenderComponent(nextProps); this.setRenderComponent(nextProps);
...@@ -36,7 +39,7 @@ export default class PromiseRender extends React.Component< ...@@ -36,7 +39,7 @@ export default class PromiseRender extends React.Component<
}; };
// set render Component : ok or error // set render Component : ok or error
setRenderComponent(props: IPromiseRenderProps) { setRenderComponent(props: IPromiseRenderProps<T, K>) {
const ok = this.checkIsInstantiation(props.ok); const ok = this.checkIsInstantiation(props.ok);
const error = this.checkIsInstantiation(props.error); const error = this.checkIsInstantiation(props.error);
props.promise props.promise
......
...@@ -9,4 +9,5 @@ Authorized.AuthorizedRoute = AuthorizedRoute; ...@@ -9,4 +9,5 @@ Authorized.AuthorizedRoute = AuthorizedRoute;
Authorized.check = check; Authorized.check = check;
const RenderAuthorize = renderAuthorize(Authorized); const RenderAuthorize = renderAuthorize(Authorized);
export default RenderAuthorize; export default RenderAuthorize;
/* eslint-disable import/no-mutable-exports */
let CURRENT: string | string[] = 'NULL'; let CURRENT: string | string[] = 'NULL';
type CurrentAuthorityType = string | string[] | (() => typeof CURRENT);
/** /**
* use authority or getAuthority * use authority or getAuthority
* @param {string|()=>String} currentAuthority * @param {string|()=>String} currentAuthority
*/ */
const renderAuthorize = (Authorized: any) => ( const renderAuthorize = <T>(Authorized: T): ((currentAuthority: CurrentAuthorityType) => T) => (
currentAuthority: string | string[] | (() => typeof CURRENT), currentAuthority: CurrentAuthorityType,
) => { ) => {
if (currentAuthority) { if (currentAuthority) {
if (typeof currentAuthority === 'function') { if (typeof currentAuthority === 'function') {
...@@ -24,4 +24,4 @@ const renderAuthorize = (Authorized: any) => ( ...@@ -24,4 +24,4 @@ const renderAuthorize = (Authorized: any) => (
}; };
export { CURRENT }; export { CURRENT };
export default (Authorized: any) => renderAuthorize(Authorized); export default <T>(Authorized: T) => renderAuthorize<T>(Authorized);
import 'jest';
import { urlToList } from './pathTools';
describe('test urlToList', () => {
it('A path', () => {
expect(urlToList('/userinfo')).toEqual(['/userinfo']);
});
it('Secondary path', () => {
expect(urlToList('/userinfo/2144')).toEqual(['/userinfo', '/userinfo/2144']);
});
it('Three paths', () => {
expect(urlToList('/userinfo/2144/addr')).toEqual([
'/userinfo',
'/userinfo/2144',
'/userinfo/2144/addr',
]);
});
});
// /userinfo/2144/id => ['/userinfo','/useinfo/2144,'/userindo/2144/id']
// eslint-disable-next-line import/prefer-default-export
export function urlToList(url: string) {
const urllist = url.split('/').filter(i => i);
return urllist.map((urlItem, index) => `/${urllist.slice(0, index + 1).join('/')}`);
}
...@@ -3,7 +3,6 @@ import RightContent from '@/components/GlobalHeader/RightContent'; ...@@ -3,7 +3,6 @@ import RightContent from '@/components/GlobalHeader/RightContent';
import { connect } from 'dva'; import { connect } from 'dva';
import React, { useState } from 'react'; import React, { useState } from 'react';
import logo from '../assets/logo.svg'; import logo from '../assets/logo.svg';
import { import {
BasicLayout as BasicLayoutComponents, BasicLayout as BasicLayoutComponents,
BasicLayoutProps as BasicLayoutComponentsProps, BasicLayoutProps as BasicLayoutComponentsProps,
...@@ -23,21 +22,20 @@ export type BasicLayoutContext = { [K in 'location']: BasicLayoutProps[K] } & { ...@@ -23,21 +22,20 @@ export type BasicLayoutContext = { [K in 'location']: BasicLayoutProps[K] } & {
}; };
const BasicLayout: React.FC<BasicLayoutProps> = props => { const BasicLayout: React.FC<BasicLayoutProps> = props => {
const { dispatch, children, route, settings } = props; const { dispatch, children, settings } = props;
const { routes, authority } = route!;
/** /**
* constructor * constructor
*/ */
useState(() => { useState(() => {
dispatch!({ type: 'user/fetchCurrent' }); dispatch!({ type: 'user/fetchCurrent' });
dispatch!({ type: 'settings/getSetting' }); dispatch!({ type: 'settings/getSetting' });
dispatch!({ type: 'menu/getMenuData', payload: { routes, authority } });
}); });
/** /**
* init variables * init variables
*/ */
const handleMenuCollapse = (payload: boolean) => const handleMenuCollapse = (payload: boolean) =>
dispatch!({ type: 'global/changeLayoutCollapsed', payload }); dispatch!({ type: 'global/changeLayoutCollapsed', payload });
return ( return (
<> <>
<BasicLayoutComponents <BasicLayoutComponents
...@@ -65,9 +63,7 @@ const BasicLayout: React.FC<BasicLayoutProps> = props => { ...@@ -65,9 +63,7 @@ const BasicLayout: React.FC<BasicLayoutProps> = props => {
); );
}; };
export default connect(({ global, settings, menu: menuModel }: ConnectState) => ({ export default connect(({ global, settings }: ConnectState) => ({
collapsed: global.collapsed, collapsed: global.collapsed,
settings, settings,
menuData: menuModel.menuData,
breadcrumbNameMap: menuModel.breadcrumbNameMap,
}))(BasicLayout); }))(BasicLayout);
import SelectLang from '@/components/SelectLang'; import SelectLang from '@/components/SelectLang';
import GlobalFooter from '@/components/GlobalFooter'; import GlobalFooter from '@/components/GlobalFooter';
import { ConnectProps, ConnectState } from '@/models/connect'; import { ConnectProps } from '@/models/connect';
import getPageTitle from '@/utils/getPageTitle';
import { Icon } from 'antd'; import { Icon } from 'antd';
import { connect } from 'dva';
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import DocumentTitle from 'react-document-title'; import DocumentTitle from 'react-document-title';
import { formatMessage } from 'umi-plugin-locale'; import { formatMessage } from 'umi-plugin-locale';
import Link from 'umi/link'; import Link from 'umi/link';
import logo from '../assets/logo.svg'; import logo from '../assets/logo.svg';
import styles from './UserLayout.less'; import styles from './UserLayout.less';
import { MenuDataItem } from '@ant-design/pro-layout'; import { MenuDataItem, getPageTitle, getMenuData } from '@ant-design/pro-layout';
const links = [ const links = [
{ {
...@@ -42,19 +40,23 @@ export interface UserLayoutProps extends ConnectProps { ...@@ -42,19 +40,23 @@ export interface UserLayoutProps extends ConnectProps {
} }
class UserLayout extends Component<UserLayoutProps> { class UserLayout extends Component<UserLayoutProps> {
componentDidMount() {
const { dispatch, route } = this.props;
const { routes, authority } = route!;
dispatch!({
type: 'menu/getMenuData',
payload: { routes, authority },
});
}
render() { render() {
const { children, location, breadcrumbNameMap } = this.props; const {
route = {
routes: [],
},
} = this.props;
const { routes = [] } = route;
const { children, location } = this.props;
const { breadcrumb } = getMenuData(routes, this.props);
return ( return (
<DocumentTitle title={getPageTitle(location!.pathname, breadcrumbNameMap)}> <DocumentTitle
title={getPageTitle({
pathname: location!.pathname,
breadcrumb,
formatMessage,
})}
>
<div className={styles.container}> <div className={styles.container}>
<div className={styles.lang}> <div className={styles.lang}>
<SelectLang /> <SelectLang />
...@@ -78,7 +80,4 @@ class UserLayout extends Component<UserLayoutProps> { ...@@ -78,7 +80,4 @@ class UserLayout extends Component<UserLayoutProps> {
} }
} }
export default connect(({ menu: menuModel }: ConnectState) => ({ export default UserLayout;
menuDaDocumentTitleta: menuModel.menuData,
breadcrumbNameMap: menuModel.breadcrumbNameMap,
}))(UserLayout);
...@@ -2,11 +2,10 @@ import { EffectsCommandMap } from 'dva'; ...@@ -2,11 +2,10 @@ import { EffectsCommandMap } from 'dva';
import { AnyAction } from 'redux'; import { AnyAction } from 'redux';
import { RouterTypes } from 'umi'; import { RouterTypes } from 'umi';
import { GlobalModelState } from './global'; import { GlobalModelState } from './global';
import { MenuModelState } from './menu';
import { UserModelState } from './user'; import { UserModelState } from './user';
import { DefaultSettings as SettingModelState } from '../../config/defaultSettings'; import { DefaultSettings as SettingModelState } from '../../config/defaultSettings';
import { MenuDataItem } from '@ant-design/pro-layout'; import { MenuDataItem } from '@ant-design/pro-layout';
export { GlobalModelState, MenuModelState, SettingModelState, UserModelState }; export { GlobalModelState, SettingModelState, UserModelState };
export type Effect = ( export type Effect = (
action: AnyAction, action: AnyAction,
...@@ -39,7 +38,6 @@ export interface ConnectState { ...@@ -39,7 +38,6 @@ export interface ConnectState {
global: GlobalModelState; global: GlobalModelState;
loading: Loading; loading: Loading;
settings: SettingModelState; settings: SettingModelState;
menu: MenuModelState;
user: UserModelState; user: UserModelState;
} }
......
import { MenuDataItem } from '@ant-design/pro-layout';
import Authorized from '@/utils/Authorized';
import { Effect } from 'dva';
import isEqual from 'lodash/isEqual';
import memoizeOne from 'memoize-one';
import { Reducer } from 'redux';
import { formatMessage } from 'umi-plugin-react/locale';
import { IRoute } from 'umi-types';
import defaultSettings from '../../config/defaultSettings';
// Conversion router to menu.
function formatter(
data: MenuDataItem[],
parentAuthority?: string[] | string,
parentName?: string,
): MenuDataItem[] {
return data
.filter(item => item.name && item.path)
.map(item => {
const locale = `${parentName || 'menu'}.${item.name!}`;
// if enableMenuLocale use item.name,
// close menu international
const name = defaultSettings.menu.disableLocal
? item.name!
: formatMessage({ id: locale, defaultMessage: item.name! });
const result: MenuDataItem = {
...item,
name,
locale,
routes: void 0,
authority: item.authority || parentAuthority,
};
if (item.routes) {
const children = formatter(item.routes, item.authority, locale);
// Reduce memory usage
result.children = children;
}
return result;
});
}
const memoizeOneFormatter = memoizeOne(formatter, isEqual);
/**
* get SubMenu or Item
*/
const getSubMenu: (item: MenuDataItem) => MenuDataItem = item => {
if (
Array.isArray(item.children) &&
!item.hideChildrenInMenu &&
item.children.some(child => (child.name ? true : false))
) {
const children = filterMenuData(item.children);
if (children.length) return { ...item, children };
}
return { ...item, children: void 0 };
};
/**
* filter menuData
*/
const filterMenuData = (menuData: MenuDataItem[] = []): MenuDataItem[] => {
return menuData
.filter(item => item.name && !item.hideInMenu)
.map(item => Authorized.check<any, any>(item.authority!, getSubMenu(item), null))
.filter(item => item);
};
/**
* 获取面包屑映射
* @param MenuDataItem[] menuData 菜单配置
*/
const getBreadcrumbNameMap = (menuData: MenuDataItem[]) => {
const routerMap: { [key: string]: MenuDataItem } = {};
const flattenMenuData: (data: MenuDataItem[]) => void = data => {
data.forEach(menuItem => {
if (menuItem.children) {
flattenMenuData(menuItem.children);
}
// Reduce memory usage
routerMap[menuItem.path] = menuItem;
});
};
flattenMenuData(menuData);
return routerMap;
};
const memoizeOneGetBreadcrumbNameMap = memoizeOne(getBreadcrumbNameMap, isEqual);
export interface MenuModelState {
menuData: MenuDataItem[];
routerData: IRoute[];
breadcrumbNameMap: object;
}
export interface MenuModelType {
namespace: 'menu';
state: MenuModelState;
effects: {
getMenuData: Effect;
};
reducers: {
save: Reducer<MenuModelState>;
};
}
const MenuModel: MenuModelType = {
namespace: 'menu',
state: {
menuData: [],
routerData: [],
breadcrumbNameMap: {},
},
effects: {
*getMenuData({ payload }, { put }) {
const { routes, authority } = payload;
const originalMenuData = memoizeOneFormatter(routes, authority);
const menuData = filterMenuData(originalMenuData);
const breadcrumbNameMap = memoizeOneGetBreadcrumbNameMap(originalMenuData);
yield put({
type: 'save',
payload: { menuData, breadcrumbNameMap, routerData: routes },
});
},
},
reducers: {
save(state, action) {
return {
...state,
...action.payload,
};
},
},
};
export default MenuModel;
...@@ -7,7 +7,6 @@ import React from 'react'; ...@@ -7,7 +7,6 @@ import React from 'react';
import Redirect from 'umi/redirect'; import Redirect from 'umi/redirect';
interface AuthComponentProps extends ConnectProps { interface AuthComponentProps extends ConnectProps {
routerData: Route[];
user: UserModelState; user: UserModelState;
} }
...@@ -26,12 +25,20 @@ const getRouteAuthority = (path: string, routeData: Route[]) => { ...@@ -26,12 +25,20 @@ const getRouteAuthority = (path: string, routeData: Route[]) => {
return authorities; return authorities;
}; };
const AuthComponent: React.FC<AuthComponentProps> = ({ children, location, routerData, user }) => { const AuthComponent: React.FC<AuthComponentProps> = ({
children,
route = {
routes: [],
},
location,
user,
}) => {
const { currentUser } = user; const { currentUser } = user;
const { routes = [] } = route;
const isLogin = currentUser && currentUser.name; const isLogin = currentUser && currentUser.name;
return ( return (
<Authorized <Authorized
authority={getRouteAuthority(location!.pathname, routerData)!} authority={getRouteAuthority(location!.pathname, routes)!}
noMatch={isLogin ? <Redirect to="/exception/403" /> : <Redirect to="/user/login" />} noMatch={isLogin ? <Redirect to="/exception/403" /> : <Redirect to="/user/login" />}
> >
{children} {children}
...@@ -39,7 +46,6 @@ const AuthComponent: React.FC<AuthComponentProps> = ({ children, location, route ...@@ -39,7 +46,6 @@ const AuthComponent: React.FC<AuthComponentProps> = ({ children, location, route
); );
}; };
export default connect(({ menu: menuModel, user }: ConnectState) => ({ export default connect(({ user }: ConnectState) => ({
routerData: menuModel.routerData,
user, user,
}))(AuthComponent); }))(AuthComponent);
import isEqual from 'lodash/isEqual';
import memoizeOne from 'memoize-one';
import pathToRegexp from 'path-to-regexp';
import { formatMessage } from 'umi-plugin-react/locale';
import defaultSettings from '../../config/defaultSettings';
import { MenuDataItem } from '@/components/SiderMenu/BaseMenu';
const { menu, title } = defaultSettings;
export const matchParamsPath = (
pathname: string,
breadcrumbNameMap: { [path: string]: MenuDataItem },
): MenuDataItem => {
const pathKey = Object.keys(breadcrumbNameMap).find(key => pathToRegexp(key).test(pathname));
return breadcrumbNameMap[pathKey!];
};
const getPageTitle = (
pathname: string,
breadcrumbNameMap: { [path: string]: MenuDataItem },
): string => {
const currRouterData = matchParamsPath(pathname, breadcrumbNameMap);
if (!currRouterData) {
return title;
}
const pageName = menu.disableLocal
? currRouterData.name
: formatMessage({
id: currRouterData.locale || currRouterData.name!,
defaultMessage: currRouterData.name,
});
return `${pageName} - ${title}`;
};
export default memoizeOne(getPageTitle, isEqual);
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
"jsx": "react", "jsx": "react",
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"moduleResolution": "node", "moduleResolution": "node",
"rootDirs": ["/src", "/test", "/mock", "./typings"],
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"noImplicitReturns": true, "noImplicitReturns": true,
"suppressImplicitAnyIndexErrors": true, "suppressImplicitAnyIndexErrors": true,
...@@ -21,7 +20,6 @@ ...@@ -21,7 +20,6 @@
"@/*": ["./src/*"] "@/*": ["./src/*"]
} }
}, },
"include": ["./src", "config/defaultSettings.ts"],
"exclude": [ "exclude": [
"node_modules", "node_modules",
"build", "build",
......
declare module 'slash2'; declare module 'slash2';
declare module 'antd-pro-merge-less'; declare module 'antd-pro-merge-less';
declare module 'antd-theme-webpack-plugin'; declare module 'antd-theme-webpack-plugin';
declare let ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: 'site' | undefined;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment