Vite support (#85)

* renamed js files to jsx where appropriate w/ burnettk

* removed unused import to unknown module w/ burnettk

* load React from jsx files explicitly w/ burnettk

* fixed tests w/ burnettk

---------

Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
jasquat 2024-04-15 18:39:39 +00:00 committed by GitHub
parent 30084ae2e7
commit 50956e496b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 302 additions and 265 deletions

View File

@ -1,3 +1,4 @@
import React from 'react';
import { useService } from 'bpmn-js-properties-panel';
import { SelectEntry } from '@bpmn-io/properties-panel';
import { findDataObjects } from '../DataObjectHelpers';
@ -24,59 +25,63 @@ export function DataObjectSelect(props) {
const commandStack = props.commandStack;
const debounce = useService('debounceInput');
const getValue = () => {
return element.businessObject.dataObjectRef.id
}
return element.businessObject.dataObjectRef.id;
};
const setValue = value => {
const setValue = (value) => {
const businessObject = element.businessObject;
const dataObjects = findDataObjects(businessObject.$parent)
const dataObjects = findDataObjects(businessObject.$parent);
for (const dataObject of dataObjects) {
if (dataObject.$type === 'bpmn:DataObject' && dataObject.id === value) {
commandStack.execute('element.updateModdleProperties', {
element: element,
moddleElement: businessObject,
properties: {
dataObjectRef: dataObject
}
dataObjectRef: dataObject,
},
});
// Construct the new name by : the dataObject name and the current state
const stateName = businessObject.dataState && businessObject.dataState.name ? businessObject.dataState.name : '';
const newName = stateName ? `${dataObject.name} [${stateName}]` : dataObject.name;
const stateName =
businessObject.dataState && businessObject.dataState.name
? businessObject.dataState.name
: '';
const newName = stateName
? `${dataObject.name} [${stateName}]`
: dataObject.name;
// Update the name property of the DataObjectReference
commandStack.execute('element.updateProperties', {
element: element,
properties: {
name: newName
}
name: newName,
},
});
}
}
}
};
const getOptions = value => {
const getOptions = (value) => {
const businessObject = element.businessObject;
const parent = businessObject.$parent;
let dataObjects = findDataObjects(parent);
let options = [];
dataObjects.forEach(dataObj => {
options.push({ label: dataObj.id, value: dataObj.id })
dataObjects.forEach((dataObj) => {
options.push({ label: dataObj.id, value: dataObj.id });
});
return options;
}
return <SelectEntry
id={'selectDataObject'}
element={element}
description={"Select the Data Object this represents."}
label={"Which Data Object does this reference?"}
getValue={getValue}
setValue={setValue}
getOptions={getOptions}
debounce={debounce}
/>;
};
return (
<SelectEntry
id={'selectDataObject'}
element={element}
description={'Select the Data Object this represents.'}
label={'Which Data Object does this reference?'}
getValue={getValue}
setValue={setValue}
getOptions={getOptions}
debounce={debounce}
/>
);
}

View File

@ -1,3 +1,4 @@
import React from 'react';
import {
ListGroup,
CheckboxEntry,
@ -7,16 +8,20 @@ import { is, isAny } from 'bpmn-js/lib/util/ModelUtil';
import scriptGroup, { SCRIPT_TYPE } from './SpiffScriptGroup';
import {
ServiceTaskParameterArray,
ServiceTaskOperatorSelect, ServiceTaskResultTextInput,
ServiceTaskOperatorSelect,
ServiceTaskResultTextInput,
} from './SpiffExtensionServiceProperties';
import {OPTION_TYPE, spiffExtensionOptions, SpiffExtensionSelect} from './SpiffExtensionSelect';
import {SpiffExtensionLaunchButton} from './SpiffExtensionLaunchButton';
import {SpiffExtensionTextArea} from './SpiffExtensionTextArea';
import {SpiffExtensionTextInput} from './SpiffExtensionTextInput';
import {SpiffExtensionCheckboxEntry} from './SpiffExtensionCheckboxEntry';
import {hasEventDefinition} from 'bpmn-js/lib/util/DiUtil';
import { PropertyDescription } from 'bpmn-js-properties-panel/';
import {setExtensionValue} from "../extensionHelpers";
import {
OPTION_TYPE,
spiffExtensionOptions,
SpiffExtensionSelect,
} from './SpiffExtensionSelect';
import { SpiffExtensionLaunchButton } from './SpiffExtensionLaunchButton';
import { SpiffExtensionTextArea } from './SpiffExtensionTextArea';
import { SpiffExtensionTextInput } from './SpiffExtensionTextInput';
import { SpiffExtensionCheckboxEntry } from './SpiffExtensionCheckboxEntry';
import { hasEventDefinition } from 'bpmn-js/lib/util/DiUtil';
import { setExtensionValue } from '../extensionHelpers';
const LOW_PRIORITY = 500;
@ -31,12 +36,14 @@ export default function ExtensionsPropertiesProvider(
return function (groups) {
if (is(element, 'bpmn:ScriptTask')) {
groups.push(
createScriptGroup(element, translate, moddle, commandStack)
createScriptGroup(element, translate, moddle, commandStack),
);
} else if (
isAny(element, ['bpmn:Task', 'bpmn:CallActivity', 'bpmn:SubProcess'])
) {
groups.push(preScriptPostScriptGroup(element, translate, moddle, commandStack));
groups.push(
preScriptPostScriptGroup(element, translate, moddle, commandStack),
);
}
if (is(element, 'bpmn:UserTask')) {
groups.push(createUserGroup(element, translate, moddle, commandStack));
@ -44,7 +51,7 @@ export default function ExtensionsPropertiesProvider(
if (is(element, 'bpmn:BusinessRuleTask')) {
groups.push(
createBusinessRuleGroup(element, translate, moddle, commandStack)
createBusinessRuleGroup(element, translate, moddle, commandStack),
);
}
if (
@ -60,31 +67,29 @@ export default function ExtensionsPropertiesProvider(
])
) {
groups.push(
createUserInstructionsGroup(element, translate, moddle, commandStack)
createUserInstructionsGroup(element, translate, moddle, commandStack),
);
}
if (
isAny(element, [
'bpmn:ManualTask',
'bpmn:UserTask',
])
) {
if (isAny(element, ['bpmn:ManualTask', 'bpmn:UserTask'])) {
groups.push(
createAllowGuestGroup(element, translate, moddle, commandStack)
createAllowGuestGroup(element, translate, moddle, commandStack),
);
}
if (
is(element, 'bpmn:BoundaryEvent') &&
hasEventDefinition(element, 'bpmn:SignalEventDefinition') &&
isAny(element.businessObject.attachedToRef, ['bpmn:ManualTask', 'bpmn:UserTask'])
isAny(element.businessObject.attachedToRef, [
'bpmn:ManualTask',
'bpmn:UserTask',
])
) {
groups.push(
createSignalButtonGroup(element, translate, moddle, commandStack)
createSignalButtonGroup(element, translate, moddle, commandStack),
);
}
if (is(element, 'bpmn:ServiceTask')) {
groups.push(
createServiceGroup(element, translate, moddle, commandStack)
createServiceGroup(element, translate, moddle, commandStack),
);
}
@ -154,7 +159,7 @@ function preScriptPostScriptGroup(element, translate, moddle, commandStack) {
}),
];
const loopCharacteristics = element.businessObject.loopCharacteristics;
if (typeof(loopCharacteristics) !== 'undefined') {
if (typeof loopCharacteristics !== 'undefined') {
entries.push({
id: 'scriptValence',
component: ScriptValenceCheckbox,
@ -170,7 +175,6 @@ function preScriptPostScriptGroup(element, translate, moddle, commandStack) {
}
function ScriptValenceCheckbox(props) {
const { element, commandStack } = props;
const getValue = () => {
@ -204,16 +208,38 @@ function ScriptValenceCheckbox(props) {
* @returns entries
*/
function createUserGroup(element, translate, moddle, commandStack) {
const updateExtensionProperties = (element, name, value, moddle, commandStack) => {
const uiName = value.replace('schema\.json', 'uischema\.json')
setExtensionValue(element, 'formJsonSchemaFilename', value, moddle, commandStack);
setExtensionValue(element, 'formUiSchemaFilename', uiName, moddle, commandStack);
const matches = spiffExtensionOptions[OPTION_TYPE.json_schema_files].filter((opt) => opt.value === value);
const updateExtensionProperties = (
element,
name,
value,
moddle,
commandStack,
) => {
const uiName = value.replace('schema.json', 'uischema.json');
setExtensionValue(
element,
'formJsonSchemaFilename',
value,
moddle,
commandStack,
);
setExtensionValue(
element,
'formUiSchemaFilename',
uiName,
moddle,
commandStack,
);
const matches = spiffExtensionOptions[OPTION_TYPE.json_schema_files].filter(
(opt) => opt.value === value,
);
if (matches.length === 0) {
spiffExtensionOptions[OPTION_TYPE.json_schema_files].push({label: value, value: value});
spiffExtensionOptions[OPTION_TYPE.json_schema_files].push({
label: value,
value: value,
});
}
}
};
return {
id: 'user_task_properties',
@ -239,7 +265,7 @@ function createUserGroup(element, translate, moddle, commandStack) {
event: 'spiff.file.edit',
listenEvent: 'spiff.jsonSchema.update',
listenFunction: updateExtensionProperties,
description: translate('Edit the form schema')
description: translate('Edit the form schema'),
},
],
};
@ -288,12 +314,7 @@ function createBusinessRuleGroup(element, translate, moddle, commandStack) {
* @param moddle
* @returns entries
*/
function createUserInstructionsGroup (
element,
translate,
moddle,
commandStack
) {
function createUserInstructionsGroup(element, translate, moddle, commandStack) {
return {
id: 'instructions',
label: translate('Instructions'),
@ -305,7 +326,8 @@ function createUserInstructionsGroup (
component: SpiffExtensionTextArea,
name: 'spiffworkflow:InstructionsForEndUser',
label: 'Instructions',
description: 'Displayed above user forms or when this task is executing.',
description:
'Displayed above user forms or when this task is executing.',
},
{
element,
@ -317,7 +339,7 @@ function createUserInstructionsGroup (
event: 'spiff.markdown.edit',
listenEvent: 'spiff.markdown.update',
description: translate('Edit the form schema'),
}
},
],
};
}
@ -329,12 +351,7 @@ function createUserInstructionsGroup (
* @param moddle
* @returns entries
*/
function createAllowGuestGroup (
element,
translate,
moddle,
commandStack
) {
function createAllowGuestGroup(element, translate, moddle, commandStack) {
return {
id: 'allow_guest_user',
label: translate('Guest options'),
@ -346,7 +363,8 @@ function createAllowGuestGroup (
component: SpiffExtensionCheckboxEntry,
name: 'spiffworkflow:AllowGuest',
label: 'Guest can complete this task',
description: 'Allow a guest user to complete this task without logging in. They will not be allowed to do anything but submit this task. If another task directly follows it that allows guest access, they could also complete that task.',
description:
'Allow a guest user to complete this task without logging in. They will not be allowed to do anything but submit this task. If another task directly follows it that allows guest access, they could also complete that task.',
},
{
element,
@ -355,7 +373,8 @@ function createAllowGuestGroup (
component: SpiffExtensionTextArea,
name: 'spiffworkflow:GuestConfirmation',
label: 'Guest confirmation',
description: 'This is markdown that is displayed to the user after they complete the task. If this is filled out then the user will not be able to complete additional tasks without a new link to the next task.',
description:
'This is markdown that is displayed to the user after they complete the task. If this is filled out then the user will not be able to complete additional tasks without a new link to the next task.',
},
{
element,
@ -366,7 +385,7 @@ function createAllowGuestGroup (
label: translate('Launch Editor'),
event: 'spiff.markdown.edit',
listenEvent: 'spiff.markdown.update',
}
},
],
};
}
@ -379,15 +398,14 @@ function createAllowGuestGroup (
* @param moddle
* @returns entries
*/
function createSignalButtonGroup (
element,
translate,
moddle,
commandStack
) {
let description =
<p style={{maxWidth : "330px"}}> If attached to a user/manual task, setting this value will display a button which a user can click to immediately fire this signal event.
function createSignalButtonGroup(element, translate, moddle, commandStack) {
let description = (
<p style={{ maxWidth: '330px' }}>
{' '}
If attached to a user/manual task, setting this value will display a
button which a user can click to immediately fire this signal event.
</p>
);
return {
id: 'signal_button',
label: translate('Button'),
@ -399,13 +417,12 @@ function createSignalButtonGroup (
component: SpiffExtensionTextInput,
name: 'spiffworkflow:SignalButtonLabel',
label: 'Button Label',
description: description
description: description,
},
],
};
}
/**
* Create a group on the main panel with a text box (for choosing the dmn to connect)
* @param element
@ -441,7 +458,7 @@ function createServiceGroup(element, translate, moddle, commandStack) {
element,
moddle,
translate,
commandStack
commandStack,
}),
},
],

View File

@ -1,36 +0,0 @@
import {useService } from 'bpmn-js-properties-panel';
import {CheckboxEntry} from '@bpmn-io/properties-panel';
import {
getExtensionValue, setExtensionValue
} from '../extensionHelpers';
/**
* A generic properties' editor for text area.
*/
export function SpiffExtensionCheckboxEntry(props) {
const element = props.element;
const commandStack = props.commandStack, moddle = props.moddle;
const name = props.name, label = props.label, description = props.description;
const debounce = useService('debounceInput');
const getValue = () => {
return getExtensionValue(element.businessObject, name)
}
const setValue = value => {
setExtensionValue(element, name, value, moddle, commandStack)
};
return <CheckboxEntry
id={'extension_' + name}
element={element}
description={description}
label={label}
getValue={getValue}
setValue={setValue}
debounce={debounce}
/>;
}

View File

@ -0,0 +1,38 @@
import React from 'react';
import { CheckboxEntry } from '@bpmn-io/properties-panel';
import { useService } from 'bpmn-js-properties-panel';
import { getExtensionValue, setExtensionValue } from '../extensionHelpers';
/**
* A generic properties' editor for text area.
*/
export function SpiffExtensionCheckboxEntry(props) {
const element = props.element;
const commandStack = props.commandStack,
moddle = props.moddle;
const name = props.name,
label = props.label,
description = props.description;
const debounce = useService('debounceInput');
const getValue = () => {
return getExtensionValue(element.businessObject, name);
};
const setValue = (value) => {
setExtensionValue(element, name, value, moddle, commandStack);
};
return (
<CheckboxEntry
id={'extension_' + name}
element={element}
description={description}
label={label}
getValue={getValue}
setValue={setValue}
debounce={debounce}
/>
);
}

View File

@ -1,35 +0,0 @@
import {useService } from 'bpmn-js-properties-panel';
import {TextAreaEntry, TextFieldEntry} from '@bpmn-io/properties-panel';
import {
getExtensionValue, setExtensionValue
} from '../extensionHelpers';
/**
* A generic properties' editor for text area.
*/
export function SpiffExtensionTextArea(props) {
const element = props.element;
const commandStack = props.commandStack, moddle = props.moddle;
const name = props.name, label = props.label, description = props.description;
const debounce = useService('debounceInput');
const getValue = () => {
return getExtensionValue(element.businessObject, name)
}
const setValue = value => {
setExtensionValue(element, name, value, moddle, commandStack)
};
return <TextAreaEntry
id={'extension_' + name}
element={element}
description={description}
label={label}
getValue={getValue}
setValue={setValue}
debounce={debounce}
/>;
}

View File

@ -0,0 +1,37 @@
import React from 'react';
import { useService } from 'bpmn-js-properties-panel';
import { TextAreaEntry, TextFieldEntry } from '@bpmn-io/properties-panel';
import { getExtensionValue, setExtensionValue } from '../extensionHelpers';
/**
* A generic properties' editor for text area.
*/
export function SpiffExtensionTextArea(props) {
const element = props.element;
const commandStack = props.commandStack,
moddle = props.moddle;
const name = props.name,
label = props.label,
description = props.description;
const debounce = useService('debounceInput');
const getValue = () => {
return getExtensionValue(element.businessObject, name);
};
const setValue = (value) => {
setExtensionValue(element, name, value, moddle, commandStack);
};
return (
<TextAreaEntry
id={'extension_' + name}
element={element}
description={description}
label={label}
getValue={getValue}
setValue={setValue}
debounce={debounce}
/>
);
}

View File

@ -1,9 +1,7 @@
import {useService } from 'bpmn-js-properties-panel';
import React from 'react';
import { useService } from 'bpmn-js-properties-panel';
import { TextFieldEntry } from '@bpmn-io/properties-panel';
import {
getExtensionValue, setExtensionValue
} from '../extensionHelpers';
import { getExtensionValue, setExtensionValue } from '../extensionHelpers';
/**
* A generic properties' editor for text input.
@ -21,25 +19,41 @@ import {
* @returns {string|null|*}
*/
export function SpiffExtensionTextInput(props) {
const { element, commandStack, moddle, name, label, description, businessObject } = props;
const {
element,
commandStack,
moddle,
name,
label,
description,
businessObject,
} = props;
const debounce = useService('debounceInput');
const getValue = () => {
return getExtensionValue(businessObject, name)
}
const setValue = value => {
setExtensionValue(element, name, value, moddle, commandStack, businessObject)
return getExtensionValue(businessObject, name);
};
return <TextFieldEntry
id={'extension_' + name}
element={element}
description={description}
label={label}
getValue={getValue}
setValue={setValue}
debounce={debounce}
/>;
const setValue = (value) => {
setExtensionValue(
element,
name,
value,
moddle,
commandStack,
businessObject,
);
};
return (
<TextFieldEntry
id={'extension_' + name}
element={element}
description={description}
label={label}
getValue={getValue}
setValue={setValue}
debounce={debounce}
/>
);
}

View File

@ -83,7 +83,7 @@ export function findCorrelationKeyForCorrelationProperty(shapeElement, moddle) {
}
export function findCorrelationPropertiesAndRetrievalExpressionsForMessage(
shapeElement
shapeElement,
) {
const formalExpressions = [];
const messageRefElement = getMessageRefElement(shapeElement);
@ -95,7 +95,7 @@ export function findCorrelationPropertiesAndRetrievalExpressionsForMessage(
const retrievalExpression =
getRetrievalExpressionFromCorrelationProperty(
childElement,
messageRefElement
messageRefElement,
);
if (retrievalExpression) {
const formalExpression = {
@ -128,7 +128,7 @@ export function getMessageElementForShapeElement(shapeElement) {
function getRetrievalExpressionFromCorrelationProperty(
correlationProperty,
message
message,
) {
if (correlationProperty.correlationPropertyRetrievalExpression) {
for (const retrievalExpression of correlationProperty.correlationPropertyRetrievalExpression) {
@ -174,7 +174,8 @@ export function findCorrelationKeys(businessObject, moddle) {
if (rootElement.$type === 'bpmn:Collaboration') {
const currentKeys = rootElement.correlationKeys;
for (const correlationKey in currentKeys) {
const currentCorrelation = rootElement.correlationKeys[correlationKey];
const currentCorrelation =
rootElement.correlationKeys[correlationKey];
correlationKeys.push(currentCorrelation);
}
}

View File

@ -1,3 +1,4 @@
import React from 'react';
import { useService } from 'bpmn-js-properties-panel';
import { TextAreaEntry } from '@bpmn-io/properties-panel';
import { getMessageElementForShapeElement } from '../MessageHelpers';
@ -37,11 +38,11 @@ export function MessagePayload(props) {
let messagePayloadObject = getMessagePayloadObject();
if (!messagePayloadObject) {
messagePayloadObject = messageElement.$model.create(
'spiffworkflow:MessagePayload'
'spiffworkflow:MessagePayload',
);
if (!messageElement.extensionElements) {
messageElement.extensionElements = messageElement.$model.create(
'bpmn:ExtensionElements'
'bpmn:ExtensionElements',
);
}
messageElement.extensionElements.get('values').push(messagePayloadObject);

View File

@ -1,3 +1,4 @@
import React from 'react';
import { useService } from 'bpmn-js-properties-panel';
import { SelectEntry } from '@bpmn-io/properties-panel';
import {

View File

@ -1,34 +1,23 @@
'use strict';
const coverage = process.env.COVERAGE;
const path = require('path');
const {
DefinePlugin,
NormalModuleReplacementPlugin
} = require('webpack');
const { DefinePlugin, NormalModuleReplacementPlugin } = require('webpack');
const basePath = '.';
const absoluteBasePath = path.resolve(path.join(__dirname, basePath));
module.exports = function(karma) {
module.exports = function (karma) {
karma.set({
frameworks: ['webpack', 'mocha', 'sinon-chai'],
frameworks: [
'webpack',
'mocha',
'sinon-chai'
],
files: ['test/spec/**/*Spec.js'],
files: [
'test/spec/**/*Spec.js',
],
reporters: [ 'dots' ],
reporters: ['dots'],
preprocessors: {
'test/spec/**/*Spec.js': [ 'webpack', 'env' ]
'test/spec/**/*Spec.js': ['webpack', 'env'],
},
browsers: [ 'ChromeHeadless' ],
browsers: ['ChromeHeadless'],
browserNoActivityTimeout: 30000,
@ -41,86 +30,91 @@ module.exports = function(karma) {
rules: [
{
test: /\.(css|bpmn)$/,
use: 'raw-loader'
use: 'raw-loader',
},
{
test: /\.m?js$/,
test: /\.m?jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
plugins: [
[ '@babel/plugin-transform-react-jsx', {
'importSource': '@bpmn-io/properties-panel/preact',
'runtime': 'automatic'
} ]
]
}
}
[
'@babel/plugin-transform-react-jsx',
{
importSource: '@bpmn-io/properties-panel/preact',
runtime: 'automatic',
},
],
],
},
},
},
{
test: /\.svg$/,
use: [ 'react-svg-loader' ]
}
].concat(coverage ?
{
test: /\.js$/,
use: {
loader: 'istanbul-instrumenter-loader',
options: { esModules: true }
},
enforce: 'post',
include: /src\.*/,
exclude: /node_modules/
} : []
)
use: ['react-svg-loader'],
},
].concat(
coverage
? {
test: /\.js$/,
use: {
loader: 'istanbul-instrumenter-loader',
options: { esModules: true },
},
enforce: 'post',
include: /src\.*/,
exclude: /node_modules/,
}
: []
),
},
plugins: [
new DefinePlugin({
// @barmac: process.env has to be defined to make @testing-library/preact work
'process.env': {}
'process.env': {},
}),
new NormalModuleReplacementPlugin(/^preact(\/[^/]+)?$/, function (
resource
) {
const replMap = {
'preact/hooks': path.resolve(
'node_modules/@bpmn-io/properties-panel/preact/hooks/dist/hooks.module.js'
),
'preact/jsx-runtime': path.resolve(
'node_modules/@bpmn-io/properties-panel/preact/jsx-runtime/dist/jsxRuntime.module.js'
),
preact: path.resolve(
'node_modules/@bpmn-io/properties-panel/preact/dist/preact.module.js'
),
};
const replacement = replMap[resource.request];
if (!replacement) {
return;
}
resource.request = replacement;
}),
new NormalModuleReplacementPlugin(
/^preact(\/[^/]+)?$/,
function(resource) {
const replMap = {
'preact/hooks': path.resolve('node_modules/@bpmn-io/properties-panel/preact/hooks/dist/hooks.module.js'),
'preact/jsx-runtime': path.resolve('node_modules/@bpmn-io/properties-panel/preact/jsx-runtime/dist/jsxRuntime.module.js'),
'preact': path.resolve('node_modules/@bpmn-io/properties-panel/preact/dist/preact.module.js')
};
const replacement = replMap[resource.request];
if (!replacement) {
return;
}
resource.request = replacement;
}
),
new NormalModuleReplacementPlugin(
/^preact\/hooks/,
path.resolve('node_modules/@bpmn-io/properties-panel/preact/hooks/dist/hooks.module.js')
)
path.resolve(
'node_modules/@bpmn-io/properties-panel/preact/hooks/dist/hooks.module.js'
)
),
],
resolve: {
mainFields: [
'browser',
'module',
'main'
],
extensions: ['', '.js', '.jsx', '.tsx'],
mainFields: ['browser', 'module', 'main'],
alias: {
'preact': '@bpmn-io/properties-panel/preact',
'react': '@bpmn-io/properties-panel/preact/compat',
'react-dom': '@bpmn-io/properties-panel/preact/compat'
preact: '@bpmn-io/properties-panel/preact',
react: '@bpmn-io/properties-panel/preact/compat',
'react-dom': '@bpmn-io/properties-panel/preact/compat',
},
modules: [
'node_modules',
absoluteBasePath
]
modules: ['node_modules', absoluteBasePath],
},
devtool: 'eval-source-map'
}
devtool: 'eval-source-map',
},
});
};