Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Fix/you do not need lodash (#9161)
Browse files Browse the repository at this point in the history
* Remove lodash `without` usage

* isNumber

* Remove lodash `difference`

* Replace lodash isEmpty with type guard

* Replace isObject with type guard

* remove lodash noop

* Replace lodash clamp

* replace lodash uniqueId

* Remove uniqueId import

* Add eslint rule to restrict lodash import

* Replace lodash range

* Replace lodash has() function

Replace lodash has

* replace omitby

* Replace lodash isEqual with fastDeepEqual

* Replace kebabCase with change-case package

* Replace lodash camelCase

Replace lodash mapKeys with function

Move mapkeys to utility

Create camelCaseKeys which replaces usage of mapKeys

* Replace lodash debounce with custom utiity

* replace lodash keyby

* Replace lodash pick with native function

* Replace lodash cloneDeep with klona

* Replace snake case keys package with change case

* Replace sortBy with fast sort package

* replace isEmpty with type guard

* Replace pickBy usage in validation reducer

* Replace groupBy usage in search list control

* Replace flatten, uniqBy usage in getProducts()

* Remove setWith and clone from updateState

* Replace custom useThrottle with useThrottledCallback from use-debounce package

* onSelectRate can use-debounce

* Fix missing flatten

* Update assets/js/data/cart/test/push-changes.ts

Co-authored-by: Paulo Arromba <17236129+wavvves@users.noreply.github.com>

---------

Co-authored-by: Paulo Arromba <17236129+wavvves@users.noreply.github.com>
  • Loading branch information
mikejolley and wavvves authored Apr 28, 2023
1 parent 1a041fd commit 680b21c
Show file tree
Hide file tree
Showing 61 changed files with 942 additions and 1,432 deletions.
124 changes: 124 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,121 @@
const restrictedImports = [
{
name: 'lodash',
importNames: [
'camelCase',
'capitalize',
'castArray',
'chunk',
'clamp',
'clone',
'cloneDeep',
'compact',
'concat',
'countBy',
'debounce',
'deburr',
'defaults',
'defaultTo',
'delay',
'difference',
'differenceWith',
'dropRight',
'each',
'escape',
'escapeRegExp',
'every',
'extend',
'filter',
'find',
'findIndex',
'findKey',
'findLast',
'first',
'flatMap',
'flatten',
'flattenDeep',
'flow',
'flowRight',
'forEach',
'fromPairs',
'has',
'identity',
'includes',
'invoke',
'isArray',
'isBoolean',
'isEqual',
'isFinite',
'isFunction',
'isMatch',
'isNil',
'isNumber',
'isObject',
'isObjectLike',
'isPlainObject',
'isString',
'isUndefined',
'keyBy',
'keys',
'last',
'lowerCase',
'map',
'mapKeys',
'maxBy',
'memoize',
'merge',
'negate',
'noop',
'nth',
'omit',
'omitBy',
'once',
'orderby',
'overEvery',
'partial',
'partialRight',
'pick',
'pickBy',
'random',
'reduce',
'reject',
'repeat',
'reverse',
'setWith',
'size',
'snakeCase',
'some',
'sortBy',
'startCase',
'startsWith',
'stubFalse',
'stubTrue',
'sum',
'sumBy',
'take',
'throttle',
'times',
'toString',
'trim',
'truncate',
'unescape',
'unionBy',
'uniq',
'uniqBy',
'uniqueId',
'uniqWith',
'upperFirst',
'values',
'without',
'words',
'xor',
'zip',
],
message:
'This Lodash method is not recommended. Please use native functionality instead. If using `memoize`, please use `memize` instead.',
},
];

module.exports = {
root: true,
extends: [
Expand Down Expand Up @@ -71,6 +189,12 @@ module.exports = {
allowedTextDomain: [ 'woo-gutenberg-products-block' ],
},
],
'no-restricted-imports': [
'error',
{
paths: restrictedImports,
},
],
'@typescript-eslint/no-restricted-imports': [
'error',
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
useAddToCartFormContext,
} from '@woocommerce/base-context';
import { useProductDataContext } from '@woocommerce/shared-context';
import { isEmpty } from 'lodash';
import { isEmpty } from '@woocommerce/types';
import { withProductDataContext } from '@woocommerce/shared-hocs';

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/**
* External dependencies
*/
import { keyBy } from 'lodash';
import { decodeEntities } from '@wordpress/html-entities';
import {
Dictionary,
Expand All @@ -10,6 +9,7 @@ import {
ProductResponseTermItem,
ProductResponseVariationsItem,
} from '@woocommerce/types';
import { keyBy } from '@woocommerce/base-utils';

/**
* Internal dependencies
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { kebabCase } from 'lodash';
import { paramCase as kebabCase } from 'change-case';
import { decodeEntities } from '@wordpress/html-entities';
import type { ProductResponseItemData } from '@woocommerce/types';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
useStoreEvents,
} from '@woocommerce/base-context/hooks';
import { sanitizeHTML } from '@woocommerce/utils';
import { debounce } from 'lodash';
import { useDebouncedCallback } from 'use-debounce';
import type { ReactElement } from 'react';

/**
Expand Down Expand Up @@ -91,23 +91,22 @@ export const ShippingRatesControlPackage = ( {
) }
</>
);
const onSelectRate = debounce(
useCallback(
( newShippingRateId: string ) => {
selectShippingRate( newShippingRateId, packageId );
dispatchCheckoutEvent( 'set-selected-shipping-rate', {
shippingRateId: newShippingRateId,
} );
},
[ dispatchCheckoutEvent, packageId, selectShippingRate ]
),
1000

const onSelectRate = useCallback(
( newShippingRateId: string ) => {
selectShippingRate( newShippingRateId, packageId );
dispatchCheckoutEvent( 'set-selected-shipping-rate', {
shippingRateId: newShippingRateId,
} );
},
[ dispatchCheckoutEvent, packageId, selectShippingRate ]
);
const debouncedOnSelectRate = useDebouncedCallback( onSelectRate, 1000 );
const packageRatesProps = {
className,
noResultsMessage,
rates: packageData.shipping_rates,
onSelectRate,
onSelectRate: debouncedOnSelectRate,
selectedRate: packageData.shipping_rates.find(
( rate ) => rate.selected
),
Expand Down
10 changes: 6 additions & 4 deletions assets/js/base/components/product-list/product-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* External dependencies
*/
import { __, _n, sprintf } from '@wordpress/i18n';
import { isEqual } from 'lodash';
import fastDeepEqual from 'fast-deep-equal/es6';
import classnames from 'classnames';
import Pagination from '@woocommerce/base-components/pagination';
import { useEffect } from '@wordpress/element';
Expand Down Expand Up @@ -113,7 +113,9 @@ const announceLoadingCompletion = ( totalProducts: number ): void => {
const areQueryTotalsDifferent: AreQueryTotalsDifferent = (
{ totalQuery: nextQuery, totalProducts: nextProducts },
{ totalQuery: currentQuery } = {}
) => ! isEqual( nextQuery, currentQuery ) && Number.isFinite( nextProducts );
) =>
! fastDeepEqual( nextQuery, currentQuery ) &&
Number.isFinite( nextProducts );

const ProductList = ( {
attributes,
Expand Down Expand Up @@ -169,7 +171,7 @@ const ProductList = ( {

// If query state (excluding pagination/sorting attributes) changed, reset pagination to the first page.
useEffect( () => {
if ( isEqual( totalQuery, previousQueryTotals?.totalQuery ) ) {
if ( fastDeepEqual( totalQuery, previousQueryTotals?.totalQuery ) ) {
return;
}
onPageChange( 1 );
Expand Down Expand Up @@ -210,7 +212,7 @@ const ProductList = ( {
const totalPages =
! Number.isFinite( totalProducts ) &&
Number.isFinite( previousQueryTotals?.totalProducts ) &&
isEqual( totalQuery, previousQueryTotals?.totalQuery )
fastDeepEqual( totalQuery, previousQueryTotals?.totalQuery )
? Math.ceil( ( previousQueryTotals?.totalProducts || 0 ) / perPage )
: Math.ceil( totalProducts / perPage );
const listProducts = products.length
Expand Down
11 changes: 5 additions & 6 deletions assets/js/base/context/event-emit/reducer.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* External dependencies
*/
import { uniqueId } from 'lodash';

/**
* Internal dependencies
*/
Expand All @@ -13,14 +8,18 @@ import {
EventObserversType,
} from './types';

export function generateUniqueId() {
return Math.floor( Math.random() * Date.now() ).toString();
}

export const actions = {
addEventCallback: (
eventType: string,
callback: ActionCallbackType,
priority = 10
): ActionType => {
return {
id: uniqueId(),
id: generateUniqueId(),
type: ACTION.ADD_EVENT_CALLBACK,
eventType,
callback,
Expand Down
4 changes: 2 additions & 2 deletions assets/js/base/context/hooks/cart/use-store-cart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/**
* External dependencies
*/
import { isEqual } from 'lodash';
import fastDeepEqual from 'fast-deep-equal/es6';
import { useRef } from '@wordpress/element';
import {
CART_STORE_KEY as storeKey,
Expand Down Expand Up @@ -247,7 +247,7 @@ export const useStoreCart = (

if (
! currentResults.current ||
! isEqual( currentResults.current, results )
! fastDeepEqual( currentResults.current, results )
) {
currentResults.current = results;
}
Expand Down
11 changes: 5 additions & 6 deletions assets/js/base/context/hooks/collections/use-collection-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
*/
import { useState, useEffect, useMemo } from '@wordpress/element';
import { useDebounce } from 'use-debounce';
import { isEmpty, sortBy } from 'lodash';
import { isEmpty, objectHasProp } from '@woocommerce/types';
import { sort } from 'fast-sort';
import { useShallowEqual } from '@woocommerce/base-hooks';
import { objectHasProp } from '@woocommerce/types';

/**
* Internal dependencies
Expand All @@ -22,17 +22,16 @@ const buildCollectionDataQuery = (
if (
Array.isArray( collectionDataQueryState.calculate_attribute_counts )
) {
query.calculate_attribute_counts = sortBy(
query.calculate_attribute_counts = sort(
collectionDataQueryState.calculate_attribute_counts.map(
( { taxonomy, queryType } ) => {
return {
taxonomy,
query_type: queryType,
};
}
),
[ 'taxonomy', 'query_type' ]
);
)
).asc( [ 'taxonomy', 'query_type' ] );
}

return query;
Expand Down
12 changes: 12 additions & 0 deletions assets/js/base/utils/camel-case-keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* External dependencies
*/
import { camelCase } from 'change-case';

/**
* Internal dependencies
*/
import { mapKeys } from './map-keys';

export const camelCaseKeys = ( obj: object ) =>
mapKeys( obj, ( _, key ) => camelCase( key ) );
34 changes: 34 additions & 0 deletions assets/js/base/utils/debounce.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type DebouncedFunction< T extends ( ...args: any[] ) => any > = ( (
...args: Parameters< T >
) => void ) & { flush: () => void };

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const debounce = < T extends ( ...args: any[] ) => any >(
func: T,
wait: number,
immediate?: boolean
): DebouncedFunction< T > => {
let timeout: ReturnType< typeof setTimeout > | null;
let latestArgs: Parameters< T > | null = null;

const debounced = ( ( ...args: Parameters< T > ) => {
latestArgs = args;
if ( timeout ) clearTimeout( timeout );
timeout = setTimeout( () => {
timeout = null;
if ( ! immediate && latestArgs ) func( ...latestArgs );
}, wait );
if ( immediate && ! timeout ) func( ...args );
} ) as DebouncedFunction< T >;

debounced.flush = () => {
if ( timeout && latestArgs ) {
func( ...latestArgs );
clearTimeout( timeout );
timeout = null;
}
};

return debounced;
};
5 changes: 5 additions & 0 deletions assets/js/base/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ export * from './get-icons-from-payment-methods';
export * from './parse-style';
export * from './create-notice';
export * from './get-navigation-type';
export * from './map-keys';
export * from './camel-case-keys';
export * from './snake-case-keys';
export * from './debounce';
export * from './keyby';
7 changes: 7 additions & 0 deletions assets/js/base/utils/keyby.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const keyBy = < T >( array: T[], key: keyof T ) => {
return array.reduce( ( acc, value ) => {
const computedKey = key ? String( value[ key ] ) : String( value );
acc[ computedKey ] = value;
return acc;
}, {} as Record< string, T > );
};
Loading

0 comments on commit 680b21c

Please sign in to comment.