chore(FE): reduce main.js chunk size (#3486)

* refactor(FE/routes): lazy load DashboardWidget route

* refactor(FE/Styled): update antd import

* chore(FE): remove majority of import * and import only necessary items

* fix(FE): fix missing papa parse import

* fix(FE): fix missing papa parse import

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
This commit is contained in:
Kanishka Chowdhury 2023-09-06 19:00:00 +05:30 committed by GitHub
parent b1cee71621
commit 16d490fbe3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 59 additions and 48 deletions

View File

@ -1,5 +1,4 @@
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import DashboardWidget from 'pages/DashboardWidget';
import { RouteProps } from 'react-router-dom'; import { RouteProps } from 'react-router-dom';
import { import {
@ -8,6 +7,7 @@ import {
CreateAlertChannelAlerts, CreateAlertChannelAlerts,
CreateNewAlerts, CreateNewAlerts,
DashboardPage, DashboardPage,
DashboardWidget,
EditAlertChannelsAlerts, EditAlertChannelsAlerts,
EditRulesPage, EditRulesPage,
ErrorDetails, ErrorDetails,

View File

@ -2,14 +2,12 @@ import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api'; import { ErrorResponse, SuccessResponse } from 'types/api';
import * as loginPrecheck from 'types/api/user/loginPrecheck'; import { PayloadProps } from 'types/api/user/loginPrecheck';
import { Props } from 'types/api/user/signup'; import { Props } from 'types/api/user/signup';
const signup = async ( const signup = async (
props: Props, props: Props,
): Promise< ): Promise<SuccessResponse<null | PayloadProps> | ErrorResponse> => {
SuccessResponse<null | loginPrecheck.PayloadProps> | ErrorResponse
> => {
try { try {
const response = await axios.post(`/register`, { const response = await axios.post(`/register`, {
...props, ...props,

View File

@ -1,5 +1,5 @@
import { Chart, ChartTypeRegistry, Plugin } from 'chart.js'; import { Chart, ChartTypeRegistry, Plugin } from 'chart.js';
import * as ChartHelpers from 'chart.js/helpers'; import { getRelativePosition } from 'chart.js/helpers';
// utils // utils
import { ChartEventHandler, mergeDefaultOptions } from './utils'; import { ChartEventHandler, mergeDefaultOptions } from './utils';
@ -45,7 +45,7 @@ function createMousedownHandler(
return (ev): void => { return (ev): void => {
const { left, right } = chart.chartArea; const { left, right } = chart.chartArea;
let { x: startDragPositionX } = ChartHelpers.getRelativePosition(ev, chart); let { x: startDragPositionX } = getRelativePosition(ev, chart);
if (left > startDragPositionX) { if (left > startDragPositionX) {
startDragPositionX = left; startDragPositionX = left;
@ -74,7 +74,7 @@ function createMousemoveHandler(
const { left, right } = chart.chartArea; const { left, right } = chart.chartArea;
let { x: dragPositionX } = ChartHelpers.getRelativePosition(ev, chart); let { x: dragPositionX } = getRelativePosition(ev, chart);
if (left > dragPositionX) { if (left > dragPositionX) {
dragPositionX = left; dragPositionX = left;
@ -99,7 +99,7 @@ function createMouseupHandler(
return (ev): void => { return (ev): void => {
const { left, right } = chart.chartArea; const { left, right } = chart.chartArea;
let { x: endRelativePostionX } = ChartHelpers.getRelativePosition(ev, chart); let { x: endRelativePostionX } = getRelativePosition(ev, chart);
if (left > endRelativePostionX) { if (left > endRelativePostionX) {
endRelativePostionX = left; endRelativePostionX = left;

View File

@ -1,5 +1,5 @@
import { Chart, ChartEvent, ChartTypeRegistry, Plugin } from 'chart.js'; import { Chart, ChartEvent, ChartTypeRegistry, Plugin } from 'chart.js';
import * as ChartHelpers from 'chart.js/helpers'; import { getRelativePosition } from 'chart.js/helpers';
// utils // utils
import { ChartEventHandler, mergeDefaultOptions } from './utils'; import { ChartEventHandler, mergeDefaultOptions } from './utils';
@ -42,7 +42,7 @@ function createMousemoveHandler(
return (ev: ChartEvent | MouseEvent): void => { return (ev: ChartEvent | MouseEvent): void => {
const { left, right, top, bottom } = chart.chartArea; const { left, right, top, bottom } = chart.chartArea;
let { x, y } = ChartHelpers.getRelativePosition(ev, chart); let { x, y } = getRelativePosition(ev, chart);
if (left > x) { if (left > x) {
x = left; x = left;

View File

@ -1,4 +1,17 @@
import * as AntD from 'antd'; import {
Button,
ButtonProps,
Col,
ColProps,
Divider,
DividerProps,
Row,
RowProps,
Space,
SpaceProps,
TabsProps,
Typography,
} from 'antd';
import { TextProps } from 'antd/lib/typography/Text'; import { TextProps } from 'antd/lib/typography/Text';
import { TitleProps } from 'antd/lib/typography/Title'; import { TitleProps } from 'antd/lib/typography/Title';
import { HTMLAttributes } from 'react'; import { HTMLAttributes } from 'react';
@ -9,43 +22,43 @@ import { IStyledClass } from './types';
const styledClass = (props: IStyledClass): FlattenSimpleInterpolation | null => const styledClass = (props: IStyledClass): FlattenSimpleInterpolation | null =>
props.styledclass || null; props.styledclass || null;
type TStyledCol = AntD.ColProps & IStyledClass; type TStyledCol = ColProps & IStyledClass;
const StyledCol = styled(AntD.Col)<TStyledCol>` const StyledCol = styled(Col)<TStyledCol>`
${styledClass} ${styledClass}
`; `;
type TStyledRow = AntD.RowProps & IStyledClass; type TStyledRow = RowProps & IStyledClass;
const StyledRow = styled(AntD.Row)<TStyledRow>` const StyledRow = styled(Row)<TStyledRow>`
${styledClass} ${styledClass}
`; `;
type TStyledDivider = AntD.DividerProps & IStyledClass; type TStyledDivider = DividerProps & IStyledClass;
const StyledDivider = styled(AntD.Divider)<TStyledDivider>` const StyledDivider = styled(Divider)<TStyledDivider>`
${styledClass} ${styledClass}
`; `;
type TStyledSpace = AntD.SpaceProps & IStyledClass; type TStyledSpace = SpaceProps & IStyledClass;
const StyledSpace = styled(AntD.Space)<TStyledSpace>` const StyledSpace = styled(Space)<TStyledSpace>`
${styledClass} ${styledClass}
`; `;
type TStyledTabs = AntD.TabsProps & IStyledClass; type TStyledTabs = TabsProps & IStyledClass;
const StyledTabs = styled(AntD.Divider)<TStyledTabs>` const StyledTabs = styled(Divider)<TStyledTabs>`
${styledClass} ${styledClass}
`; `;
type TStyledButton = AntD.ButtonProps & IStyledClass; type TStyledButton = ButtonProps & IStyledClass;
const StyledButton = styled(AntD.Button)<TStyledButton>` const StyledButton = styled(Button)<TStyledButton>`
${styledClass} ${styledClass}
`; `;
const { Text } = AntD.Typography; const { Text } = Typography;
type TStyledTypographyText = TextProps & IStyledClass; type TStyledTypographyText = TextProps & IStyledClass;
const StyledTypographyText = styled(Text)<TStyledTypographyText>` const StyledTypographyText = styled(Text)<TStyledTypographyText>`
${styledClass} ${styledClass}
`; `;
const { Title } = AntD.Typography; const { Title } = Typography;
type TStyledTypographyTitle = TitleProps & IStyledClass; type TStyledTypographyTitle = TitleProps & IStyledClass;
const StyledTypographyTitle = styled(Title)<TStyledTypographyTitle>` const StyledTypographyTitle = styled(Title)<TStyledTypographyTitle>`
${styledClass} ${styledClass}

View File

@ -8,7 +8,7 @@ import dayjs from 'dayjs';
import { Pagination } from 'hooks/queryPagination'; import { Pagination } from 'hooks/queryPagination';
import { FlatLogData } from 'lib/logs/flatLogData'; import { FlatLogData } from 'lib/logs/flatLogData';
import { OrderPreferenceItems } from 'pages/Logs/config'; import { OrderPreferenceItems } from 'pages/Logs/config';
import * as Papa from 'papaparse'; import { unparse } from 'papaparse';
import { memo, useCallback, useMemo } from 'react'; import { memo, useCallback, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { Dispatch } from 'redux'; import { Dispatch } from 'redux';
@ -121,7 +121,7 @@ function LogControls(): JSX.Element | null {
}, [flattenLogData]); }, [flattenLogData]);
const downloadCsvFile = useCallback((): void => { const downloadCsvFile = useCallback((): void => {
const csv = Papa.unparse(flattenLogData); const csv = unparse(flattenLogData);
const csvBlob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); const csvBlob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
const csvUrl = URL.createObjectURL(csvBlob); const csvUrl = URL.createObjectURL(csvBlob);
const downloadLink = document.createElement('a'); const downloadLink = document.createElement('a');

View File

@ -2,7 +2,7 @@ import { DEBOUNCE_DELAY } from 'constants/queryBuilderFilterConfig';
import useDebounce from 'hooks/useDebounce'; import useDebounce from 'hooks/useDebounce';
import { IOption } from 'hooks/useResourceAttribute/types'; import { IOption } from 'hooks/useResourceAttribute/types';
import { isEqual, uniqWith } from 'lodash-es'; import { isEqual, uniqWith } from 'lodash-es';
import * as Papa from 'papaparse'; import { parse } from 'papaparse';
import { useCallback, useMemo, useState } from 'react'; import { useCallback, useMemo, useState } from 'react';
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse'; import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { OrderByPayload } from 'types/api/queryBuilder/queryBuilderData'; import { OrderByPayload } from 'types/api/queryBuilder/queryBuilderData';
@ -45,7 +45,7 @@ export const useOrderByFilter = ({
const getUniqValues = useCallback((values: IOption[]): IOption[] => { const getUniqValues = useCallback((values: IOption[]): IOption[] => {
const modifiedValues = values.map((item) => { const modifiedValues = values.map((item) => {
const match = Papa.parse(item.value, { delimiter: orderByValueDelimiter }); const match = parse(item.value, { delimiter: orderByValueDelimiter });
if (!match) return { label: item.label, value: item.value }; if (!match) return { label: item.label, value: item.value };
// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars
const [_, order] = match.data.flat() as string[]; const [_, order] = match.data.flat() as string[];
@ -141,7 +141,7 @@ export const useOrderByFilter = ({
const result = getUniqValues(validResult); const result = getUniqValues(validResult);
const orderByValues: OrderByPayload[] = result.map((item) => { const orderByValues: OrderByPayload[] = result.map((item) => {
const match = Papa.parse(item.value, { delimiter: orderByValueDelimiter }); const match = parse(item.value, { delimiter: orderByValueDelimiter });
if (!match) { if (!match) {
return { return {

View File

@ -1,5 +1,5 @@
import { IOption } from 'hooks/useResourceAttribute/types'; import { IOption } from 'hooks/useResourceAttribute/types';
import * as Papa from 'papaparse'; import { parse } from 'papaparse';
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse'; import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { import {
IBuilderQuery, IBuilderQuery,
@ -51,7 +51,7 @@ export function mapLabelValuePairs(
export function getLabelFromValue(arr: IOption[]): string[] { export function getLabelFromValue(arr: IOption[]): string[] {
return arr.flat().map((item) => { return arr.flat().map((item) => {
const match = Papa.parse(item.value, { delimiter: orderByValueDelimiter }); const match = parse(item.value, { delimiter: orderByValueDelimiter });
if (match) { if (match) {
const [key] = match.data as string[]; const [key] = match.data as string[];

View File

@ -1,5 +1,5 @@
import { OPERATORS } from 'constants/queryBuilder'; import { OPERATORS } from 'constants/queryBuilder';
import * as Papa from 'papaparse'; import { parse } from 'papaparse';
import { orderByValueDelimiter } from '../OrderByFilter/utils'; import { orderByValueDelimiter } from '../OrderByFilter/utils';
@ -25,7 +25,7 @@ export function getTagToken(tag: string): ITagToken {
tagKey: matchTagKey, tagKey: matchTagKey,
tagOperator: matchTagOperator, tagOperator: matchTagOperator,
tagValue: isInNInOperator(matchTagOperator) tagValue: isInNInOperator(matchTagOperator)
? Papa.parse(matchTagValue).data.flat() ? parse(matchTagValue).data.flat()
: matchTagValue, : matchTagValue,
} as ITagToken; } as ITagToken;
} }
@ -118,7 +118,7 @@ export function checkCommaInValue(str: string): string {
} }
export function getRemoveOrderFromValue(tag: string): string { export function getRemoveOrderFromValue(tag: string): string {
const match = Papa.parse(tag, { delimiter: orderByValueDelimiter }); const match = parse(tag, { delimiter: orderByValueDelimiter });
if (match) { if (match) {
const [key] = match.data.flat() as string[]; const [key] = match.data.flat() as string[];
return key; return key;

View File

@ -8,7 +8,7 @@ import {
StyledSpace, StyledSpace,
StyledTypography, StyledTypography,
} from 'components/Styled'; } from 'components/Styled';
import * as StyledStyles from 'components/Styled/styles'; import { Flex, Spacing } from 'components/Styled/styles';
import GanttChart, { ITraceMetaData } from 'container/GantChart'; import GanttChart, { ITraceMetaData } from 'container/GantChart';
import { getNodeById } from 'container/GantChart/utils'; import { getNodeById } from 'container/GantChart/utils';
import Timeline from 'container/Timeline'; import Timeline from 'container/Timeline';
@ -128,7 +128,7 @@ function TraceDetail({ response }: TraceDetailProps): JSX.Element {
const isGlobalTimeVisible = tree && traceMetaData.globalStart; const isGlobalTimeVisible = tree && traceMetaData.globalStart;
return ( return (
<StyledRow styledclass={[StyledStyles.Flex({ flex: 1 })]}> <StyledRow styledclass={[Flex({ flex: 1 })]}>
<StyledCol flex="auto" styledclass={styles.leftContainer}> <StyledCol flex="auto" styledclass={styles.leftContainer}>
<StyledRow styledclass={styles.flameAndTimelineContainer}> <StyledRow styledclass={styles.flameAndTimelineContainer}>
<StyledCol <StyledCol
@ -199,7 +199,7 @@ function TraceDetail({ response }: TraceDetailProps): JSX.Element {
<StyledRow <StyledRow
styledclass={[ styledclass={[
styles.traceDetailContentSpacing, styles.traceDetailContentSpacing,
StyledStyles.Spacing({ Spacing({
margin: '1.5rem 1rem 0.5rem', margin: '1.5rem 1rem 0.5rem',
}), }),
]} ]}

View File

@ -5,7 +5,7 @@ import {
tagRegexp, tagRegexp,
} from 'container/QueryBuilder/filters/QueryBuilderSearch/utils'; } from 'container/QueryBuilder/filters/QueryBuilderSearch/utils';
import { Option } from 'container/QueryBuilder/type'; import { Option } from 'container/QueryBuilder/type';
import * as Papa from 'papaparse'; import { parse } from 'papaparse';
import { KeyboardEvent, useCallback, useState } from 'react'; import { KeyboardEvent, useCallback, useState } from 'react';
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
@ -61,7 +61,7 @@ export const useAutoComplete = (
const matches = prev?.matchAll(tagRegexp); const matches = prev?.matchAll(tagRegexp);
const [match] = matches ? Array.from(matches) : []; const [match] = matches ? Array.from(matches) : [];
const [, , , matchTagValue] = match; const [, , , matchTagValue] = match;
const data = Papa.parse(matchTagValue).data.flat(); const data = parse(matchTagValue).data.flat();
return replaceStringWithMaxLength(prev, data as string[], value); return replaceStringWithMaxLength(prev, data as string[], value);
}); });
} }

View File

@ -4,8 +4,8 @@ import {
isExistsNotExistsOperator, isExistsNotExistsOperator,
isInNInOperator, isInNInOperator,
} from 'container/QueryBuilder/filters/QueryBuilderSearch/utils'; } from 'container/QueryBuilder/filters/QueryBuilderSearch/utils';
import { unparse } from 'papaparse';
// eslint-disable-next-line import/no-extraneous-dependencies // eslint-disable-next-line import/no-extraneous-dependencies
import * as Papa from 'papaparse';
import { useCallback, useEffect, useMemo, useState } from 'react'; import { useCallback, useEffect, useMemo, useState } from 'react';
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
@ -38,7 +38,7 @@ export const useTag = (
(query?.filters?.items || []).map((ele) => { (query?.filters?.items || []).map((ele) => {
if (isInNInOperator(getOperatorFromValue(ele.op))) { if (isInNInOperator(getOperatorFromValue(ele.op))) {
try { try {
const csvString = Papa.unparse([ele.value]); const csvString = unparse([ele.value]);
return `${ele.key?.key} ${getOperatorFromValue(ele.op)} ${csvString}`; return `${ele.key?.key} ${getOperatorFromValue(ele.op)} ${csvString}`;
} catch { } catch {
return `${ele.key?.key} ${getOperatorFromValue(ele.op)} ${ele.value}`; return `${ele.key?.key} ${getOperatorFromValue(ele.op)} ${ele.value}`;

View File

@ -14,7 +14,7 @@ import { useQuery } from 'react-query';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { SuccessResponse } from 'types/api'; import { SuccessResponse } from 'types/api';
import { PayloadProps } from 'types/api/user/getUser'; import { PayloadProps } from 'types/api/user/getUser';
import * as loginPrecheck from 'types/api/user/loginPrecheck'; import { PayloadProps as LoginPrecheckPayloadProps } from 'types/api/user/loginPrecheck';
import { import {
ButtonContainer, ButtonContainer,
@ -41,7 +41,7 @@ function SignUp({ version }: SignUpProps): JSX.Element {
const { t } = useTranslation(['signup']); const { t } = useTranslation(['signup']);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [precheck, setPrecheck] = useState<loginPrecheck.PayloadProps>({ const [precheck, setPrecheck] = useState<LoginPrecheckPayloadProps>({
sso: false, sso: false,
isUser: false, isUser: false,
}); });

View File

@ -2,7 +2,7 @@ import { User } from 'types/reducer/app';
import { ROLES } from 'types/roles'; import { ROLES } from 'types/roles';
import { Organization } from './getOrganization'; import { Organization } from './getOrganization';
import * as loginPrecheck from './loginPrecheck'; import { PayloadProps as LoginPrecheckPayloadProps } from './loginPrecheck';
export interface Props { export interface Props {
inviteId: string; inviteId: string;
@ -15,5 +15,5 @@ export interface PayloadProps {
role: ROLES; role: ROLES;
token: string; token: string;
organization: Organization['name']; organization: Organization['name'];
precheck?: loginPrecheck.PayloadProps; precheck?: LoginPrecheckPayloadProps;
} }

View File

@ -2,7 +2,7 @@
/* eslint-disable global-require */ /* eslint-disable global-require */
/// <reference types="@welldone-software/why-did-you-render" /> /// <reference types="@welldone-software/why-did-you-render" />
// ^ https://github.com/welldone-software/why-did-you-render/issues/161 // ^ https://github.com/welldone-software/why-did-you-render/issues/161
import * as React from 'react'; import React from 'react';
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
const whyDidYouRender = require('@welldone-software/why-did-you-render'); const whyDidYouRender = require('@welldone-software/why-did-you-render');