添加测试后,NodeJs JavaScript react-scripts-ts 堆内存不足崩溃
NodeJs JavaScript heap out of memory crash on react-scripts-ts after adding tests
我有一个 React + TypeScript 项目。自从几天前,我的 webstorm IDE 崩溃了(JavaScript 堆内存不足)on every update that I make to codes。我正在使用 nodeJs 12.3.1、typescript 3.7.5、react 16.12.0、react-scripts-ts 3.1.0、webstorm 2021.2,我的 OS 是 windows 10.
自那时以来,我所做的唯一重大更改是添加了一堆测试(准确地说是 48 个测试和 5000 行代码)。这些测试是使用 jest 和 enzyme 编写的。这些测试包括模拟一些 API 和事件,以及安装元素以检查它们的存在和状态。我应该说所有这些测试都会通过。
我的问题是,为什么每次更改代码后 nodeJs 都会中断? react-scripts-ts start
在 hot reloads
上做什么?写测试的时候要不要考虑一些具体的隐藏点?
如果能提供任何帮助或线索来找出问题,我将不胜感激。
PS:我很乐意分享任何必要的信息以帮助澄清问题。
这是其中一个测试的代码:
import * as React from 'react';
import * as Adapter from 'enzyme-adapter-react-16';
import * as enzyme from 'enzyme';
import DonutObjectKpi from './donutObjectKpi';
import {
ChartType,
DashboardItemType,
DonutChartProps,
NamedKpiSeriesSelector,
} from '../../../../utils/dashboardUtils/dashboardItem/props';
import KpiDefinition from '../../../../../model/kpi/customKpi/kpiDefinition';
import Kpi from '../../../../../model/kpi/kpi';
import KpiDefinitionType from '../../../../../model/kpi/kpiDefinitionType';
import { CHART_REFRESH_RATE } from '../../../../../config/constants';
import { Button, HorizontalLayout, IconButton, PieChartType, Table } from '../../../../view';
import { InputLabeledField } from '../../../../../modules/panels/baseCrud/layouts';
import { EnumDropDown } from '../../../../input';
import BuildOption from '../../../dropdown/buildOption/component';
enzyme.configure({adapter: new Adapter()});
describe('ObjectKpiItem Test', () => {
let chartType = ChartType.DONUT;
let showTitle = true;
let title: string | undefined = 'Test';
let cancelModal: boolean = false;
let dataModal: DonutChartProps | undefined;
let changeType: boolean = false;
const obj = {value: '1', label: 'item1'};
const resourceObj = {value: '2', label: 'item2'};
const kpiDef: KpiDefinition = {
kpi: Kpi.DB2Z_DSCDBAT,
type: KpiDefinitionType.OBJECT_KPI,
monitoringObject: {id: '3', presentation: 'item3'},
};
const description = 'donut Test';
const selectors: NamedKpiSeriesSelector[] = [
{kpi: Kpi.ACTIVE_DIRECTORY_COMPUTERS_COUNT, kpiDefinition: kpiDef, objectId: '1', objectIdName: 'item1'},
{kpi: Kpi.ACTIVE_DIRECTORY_DISABLED_USERS_COUNT, kpiDefinition: kpiDef, objectId: '2', objectIdName: 'item2'},
{kpi: Kpi.HBASE_REGION_SERVER_STORE_FILE_SIZE_20210, kpiDefinition: kpiDef, objectId: '3', objectIdName: 'item3'},
];
it('check render:', () => {
const wrapper = enzyme.mount(
<DonutObjectKpi
onObjectKpiChartTypeChange={(newType, showTitleRes, titleRes) => {
chartType = newType;
showTitle = showTitleRes;
title = titleRes;
}}
showTitle={showTitle}
chartType={chartType}
title={title}
objectId={obj}
onCancel={() => cancelModal = true}
submitModal={(data: DonutChartProps) => dataModal = data}
onDashboardItemTypeChange={() => changeType = true}
/>,
);
expect(wrapper.find(InputLabeledField).length).toEqual(8);
expect(wrapper.find(Table).length).toEqual(2);
expect(wrapper.find(IconButton).length).toEqual(1);
expect(wrapper.find(EnumDropDown).length).toEqual(9); // 4 self + 5 border table
});
it('check change value:', () => {
const wrapper = enzyme.mount(
<DonutObjectKpi
onObjectKpiChartTypeChange={(newType, showTitleRes, titleRes) => {
chartType = newType;
showTitle = showTitleRes;
title = titleRes;
}}
showTitle={showTitle}
chartType={chartType}
title={title}
objectId={obj}
onCancel={() => cancelModal = true}
submitModal={(data: DonutChartProps) => dataModal = data}
onDashboardItemTypeChange={() => changeType = true}
data={{
title,
showTitle: true,
selectors,
chartType: ChartType.DONUT,
type: PieChartType.KPI,
dashboardItemType: DashboardItemType.OBJECT_KPI,
interval: CHART_REFRESH_RATE,
description,
}}
/>,
);
wrapper.setState({
resourceId: resourceObj,
kpiDefinition: kpiDef,
objectId: obj,
selectors,
title,
});
wrapper.update();
wrapper.find(IconButton).last().simulate('click');
expect(dataModal).not.toEqual(undefined);
expect(dataModal!.title).toEqual(title);
expect(dataModal!.description).toEqual(description);
expect(dataModal!.chartType).toEqual(chartType);
expect(dataModal!.selectors.length).toEqual(selectors.length);
expect(dataModal!.dashboardItemType).toEqual(DashboardItemType.OBJECT_KPI);
});
it('check cancel modal:', () => {
const newObj = {value: '2', label: 'item2'};
const newResourceObj = {value: '3', label: 'item3'};
const newKpiDef: KpiDefinition = {
kpi: Kpi.HBASE_REGION_SERVER_NUM_OF_HLOG_FILE_20206,
type: KpiDefinitionType.OBJECT_KPI,
monitoringObject: {id: '4', presentation: 'item4'},
};
const newSelectors: NamedKpiSeriesSelector[] = [
{kpi: Kpi.ACTIVE_DIRECTORY_COMPUTERS_COUNT, kpiDefinition: kpiDef, objectId: '1', objectIdName: 'item1'},
{kpi: Kpi.ACTIVE_DIRECTORY_DISABLED_USERS_COUNT, kpiDefinition: kpiDef, objectId: '2', objectIdName: 'item2'},
{kpi: Kpi.HBASE_REGION_SERVER_STORE_FILE_SIZE_20210, kpiDefinition: kpiDef, objectId: '3', objectIdName: 'item3'},
{kpi: Kpi.HBASE_REGION_SERVER_NUM_OF_REGIONS_20204, kpiDefinition: kpiDef, objectId: '4', objectIdName: 'item4'},
];
const wrapper = enzyme.mount(
<DonutObjectKpi
onObjectKpiChartTypeChange={(newType, showTitleRes, titleRes) => {
chartType = newType;
showTitle = showTitleRes;
title = titleRes;
}}
showTitle={showTitle}
chartType={chartType}
title={title}
objectId={newObj}
onCancel={() => cancelModal = true}
submitModal={(data: DonutChartProps) => dataModal = data}
onDashboardItemTypeChange={() => changeType = true}
data={{
title,
showTitle: true,
selectors,
chartType: ChartType.DONUT,
type: PieChartType.KPI,
dashboardItemType: DashboardItemType.OBJECT_KPI,
interval: CHART_REFRESH_RATE,
description,
}}
/>,
);
wrapper.setState({
resourceId: newResourceObj,
kpiDefinition: newKpiDef,
objectId: newObj,
selectors: newSelectors,
title,
});
wrapper.update();
expect(dataModal!.selectors.length).toEqual(selectors.length);
expect(cancelModal).toEqual(false);
wrapper.find(Button).at(1).simulate('click');
expect(dataModal!.selectors.length).not.toEqual(newSelectors.length);
expect(cancelModal).toEqual(true);
});
it('check change type:', () => {
const wrapper = enzyme.mount(
<DonutObjectKpi
onObjectKpiChartTypeChange={(newType, showTitleRes, titleRes) => {
chartType = newType;
showTitle = showTitleRes;
title = titleRes;
}}
showTitle={showTitle}
chartType={chartType}
title={title}
objectId={obj}
onCancel={() => cancelModal = true}
submitModal={(data: DonutChartProps) => dataModal = data}
onDashboardItemTypeChange={() => changeType = true}
data={{
title,
showTitle: true,
selectors,
chartType: ChartType.DONUT,
type: PieChartType.KPI,
dashboardItemType: DashboardItemType.OBJECT_KPI,
interval: CHART_REFRESH_RATE,
description,
}}
/>,
);
wrapper.find(InputLabeledField).first().find(EnumDropDown).first().find('div').at(1).simulate('click');
const type = wrapper.find(InputLabeledField).first().find(EnumDropDown).first();
expect(changeType).toEqual(false);
type.find(BuildOption).first().find(HorizontalLayout).first().find('div').first().simulate('click');
expect(changeType).toEqual(true);
});
});
对于可能遇到我的问题的任何人,我找到的解决方法是从typescript
编译 中排除所有测试文件。这是我的 tsconfig.json
中的排除部分(我添加了最后两行):
"exclude": [
"node_modules",
"build",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts",
"src/**/*.test.ts",
"src/**/*.test.tsx"
]
我应该提一下,关于内存使用的优化测试没有帮助。
我有一个 React + TypeScript 项目。自从几天前,我的 webstorm IDE 崩溃了(JavaScript 堆内存不足)on every update that I make to codes。我正在使用 nodeJs 12.3.1、typescript 3.7.5、react 16.12.0、react-scripts-ts 3.1.0、webstorm 2021.2,我的 OS 是 windows 10.
自那时以来,我所做的唯一重大更改是添加了一堆测试(准确地说是 48 个测试和 5000 行代码)。这些测试是使用 jest 和 enzyme 编写的。这些测试包括模拟一些 API 和事件,以及安装元素以检查它们的存在和状态。我应该说所有这些测试都会通过。
我的问题是,为什么每次更改代码后 nodeJs 都会中断? react-scripts-ts start
在 hot reloads
上做什么?写测试的时候要不要考虑一些具体的隐藏点?
如果能提供任何帮助或线索来找出问题,我将不胜感激。
PS:我很乐意分享任何必要的信息以帮助澄清问题。
这是其中一个测试的代码:
import * as React from 'react';
import * as Adapter from 'enzyme-adapter-react-16';
import * as enzyme from 'enzyme';
import DonutObjectKpi from './donutObjectKpi';
import {
ChartType,
DashboardItemType,
DonutChartProps,
NamedKpiSeriesSelector,
} from '../../../../utils/dashboardUtils/dashboardItem/props';
import KpiDefinition from '../../../../../model/kpi/customKpi/kpiDefinition';
import Kpi from '../../../../../model/kpi/kpi';
import KpiDefinitionType from '../../../../../model/kpi/kpiDefinitionType';
import { CHART_REFRESH_RATE } from '../../../../../config/constants';
import { Button, HorizontalLayout, IconButton, PieChartType, Table } from '../../../../view';
import { InputLabeledField } from '../../../../../modules/panels/baseCrud/layouts';
import { EnumDropDown } from '../../../../input';
import BuildOption from '../../../dropdown/buildOption/component';
enzyme.configure({adapter: new Adapter()});
describe('ObjectKpiItem Test', () => {
let chartType = ChartType.DONUT;
let showTitle = true;
let title: string | undefined = 'Test';
let cancelModal: boolean = false;
let dataModal: DonutChartProps | undefined;
let changeType: boolean = false;
const obj = {value: '1', label: 'item1'};
const resourceObj = {value: '2', label: 'item2'};
const kpiDef: KpiDefinition = {
kpi: Kpi.DB2Z_DSCDBAT,
type: KpiDefinitionType.OBJECT_KPI,
monitoringObject: {id: '3', presentation: 'item3'},
};
const description = 'donut Test';
const selectors: NamedKpiSeriesSelector[] = [
{kpi: Kpi.ACTIVE_DIRECTORY_COMPUTERS_COUNT, kpiDefinition: kpiDef, objectId: '1', objectIdName: 'item1'},
{kpi: Kpi.ACTIVE_DIRECTORY_DISABLED_USERS_COUNT, kpiDefinition: kpiDef, objectId: '2', objectIdName: 'item2'},
{kpi: Kpi.HBASE_REGION_SERVER_STORE_FILE_SIZE_20210, kpiDefinition: kpiDef, objectId: '3', objectIdName: 'item3'},
];
it('check render:', () => {
const wrapper = enzyme.mount(
<DonutObjectKpi
onObjectKpiChartTypeChange={(newType, showTitleRes, titleRes) => {
chartType = newType;
showTitle = showTitleRes;
title = titleRes;
}}
showTitle={showTitle}
chartType={chartType}
title={title}
objectId={obj}
onCancel={() => cancelModal = true}
submitModal={(data: DonutChartProps) => dataModal = data}
onDashboardItemTypeChange={() => changeType = true}
/>,
);
expect(wrapper.find(InputLabeledField).length).toEqual(8);
expect(wrapper.find(Table).length).toEqual(2);
expect(wrapper.find(IconButton).length).toEqual(1);
expect(wrapper.find(EnumDropDown).length).toEqual(9); // 4 self + 5 border table
});
it('check change value:', () => {
const wrapper = enzyme.mount(
<DonutObjectKpi
onObjectKpiChartTypeChange={(newType, showTitleRes, titleRes) => {
chartType = newType;
showTitle = showTitleRes;
title = titleRes;
}}
showTitle={showTitle}
chartType={chartType}
title={title}
objectId={obj}
onCancel={() => cancelModal = true}
submitModal={(data: DonutChartProps) => dataModal = data}
onDashboardItemTypeChange={() => changeType = true}
data={{
title,
showTitle: true,
selectors,
chartType: ChartType.DONUT,
type: PieChartType.KPI,
dashboardItemType: DashboardItemType.OBJECT_KPI,
interval: CHART_REFRESH_RATE,
description,
}}
/>,
);
wrapper.setState({
resourceId: resourceObj,
kpiDefinition: kpiDef,
objectId: obj,
selectors,
title,
});
wrapper.update();
wrapper.find(IconButton).last().simulate('click');
expect(dataModal).not.toEqual(undefined);
expect(dataModal!.title).toEqual(title);
expect(dataModal!.description).toEqual(description);
expect(dataModal!.chartType).toEqual(chartType);
expect(dataModal!.selectors.length).toEqual(selectors.length);
expect(dataModal!.dashboardItemType).toEqual(DashboardItemType.OBJECT_KPI);
});
it('check cancel modal:', () => {
const newObj = {value: '2', label: 'item2'};
const newResourceObj = {value: '3', label: 'item3'};
const newKpiDef: KpiDefinition = {
kpi: Kpi.HBASE_REGION_SERVER_NUM_OF_HLOG_FILE_20206,
type: KpiDefinitionType.OBJECT_KPI,
monitoringObject: {id: '4', presentation: 'item4'},
};
const newSelectors: NamedKpiSeriesSelector[] = [
{kpi: Kpi.ACTIVE_DIRECTORY_COMPUTERS_COUNT, kpiDefinition: kpiDef, objectId: '1', objectIdName: 'item1'},
{kpi: Kpi.ACTIVE_DIRECTORY_DISABLED_USERS_COUNT, kpiDefinition: kpiDef, objectId: '2', objectIdName: 'item2'},
{kpi: Kpi.HBASE_REGION_SERVER_STORE_FILE_SIZE_20210, kpiDefinition: kpiDef, objectId: '3', objectIdName: 'item3'},
{kpi: Kpi.HBASE_REGION_SERVER_NUM_OF_REGIONS_20204, kpiDefinition: kpiDef, objectId: '4', objectIdName: 'item4'},
];
const wrapper = enzyme.mount(
<DonutObjectKpi
onObjectKpiChartTypeChange={(newType, showTitleRes, titleRes) => {
chartType = newType;
showTitle = showTitleRes;
title = titleRes;
}}
showTitle={showTitle}
chartType={chartType}
title={title}
objectId={newObj}
onCancel={() => cancelModal = true}
submitModal={(data: DonutChartProps) => dataModal = data}
onDashboardItemTypeChange={() => changeType = true}
data={{
title,
showTitle: true,
selectors,
chartType: ChartType.DONUT,
type: PieChartType.KPI,
dashboardItemType: DashboardItemType.OBJECT_KPI,
interval: CHART_REFRESH_RATE,
description,
}}
/>,
);
wrapper.setState({
resourceId: newResourceObj,
kpiDefinition: newKpiDef,
objectId: newObj,
selectors: newSelectors,
title,
});
wrapper.update();
expect(dataModal!.selectors.length).toEqual(selectors.length);
expect(cancelModal).toEqual(false);
wrapper.find(Button).at(1).simulate('click');
expect(dataModal!.selectors.length).not.toEqual(newSelectors.length);
expect(cancelModal).toEqual(true);
});
it('check change type:', () => {
const wrapper = enzyme.mount(
<DonutObjectKpi
onObjectKpiChartTypeChange={(newType, showTitleRes, titleRes) => {
chartType = newType;
showTitle = showTitleRes;
title = titleRes;
}}
showTitle={showTitle}
chartType={chartType}
title={title}
objectId={obj}
onCancel={() => cancelModal = true}
submitModal={(data: DonutChartProps) => dataModal = data}
onDashboardItemTypeChange={() => changeType = true}
data={{
title,
showTitle: true,
selectors,
chartType: ChartType.DONUT,
type: PieChartType.KPI,
dashboardItemType: DashboardItemType.OBJECT_KPI,
interval: CHART_REFRESH_RATE,
description,
}}
/>,
);
wrapper.find(InputLabeledField).first().find(EnumDropDown).first().find('div').at(1).simulate('click');
const type = wrapper.find(InputLabeledField).first().find(EnumDropDown).first();
expect(changeType).toEqual(false);
type.find(BuildOption).first().find(HorizontalLayout).first().find('div').first().simulate('click');
expect(changeType).toEqual(true);
});
});
对于可能遇到我的问题的任何人,我找到的解决方法是从typescript
编译 中排除所有测试文件。这是我的 tsconfig.json
中的排除部分(我添加了最后两行):
"exclude": [
"node_modules",
"build",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts",
"src/**/*.test.ts",
"src/**/*.test.tsx"
]
我应该提一下,关于内存使用的优化测试没有帮助。