Skip to content

Commit

Permalink
feat: strip off logs & errors in production builds (#1461)
Browse files Browse the repository at this point in the history
  • Loading branch information
snitin315 authored Jul 31, 2023
1 parent 2be798d commit cbed430
Show file tree
Hide file tree
Showing 44 changed files with 441 additions and 279 deletions.
5 changes: 5 additions & 0 deletions .changeset/eight-wasps-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@razorpay/blade": minor
---

feat: strip off logs & errors in production builds
8 changes: 8 additions & 0 deletions packages/blade/.storybook/react/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const { DefinePlugin } = require('webpack');
const path = require('path');

module.exports = {
Expand Down Expand Up @@ -56,6 +57,13 @@ module.exports = {
}),
];

config.plugins = [
...(config.plugins || []),
new DefinePlugin({
__DEV__: true,
}),
];

// Return the altered config
return {
...config,
Expand Down
3 changes: 3 additions & 0 deletions packages/blade/jest.web.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ const baseConfig = {
'^\\~utils/(.*)': '<rootDir>/src/utils/$1',
'^\\~tokens/(.*)': '<rootDir>/src/tokens/$1',
},
globals: {
__DEV__: true,
},
};

module.exports = {
Expand Down
28 changes: 18 additions & 10 deletions packages/blade/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
},
"default": {
"types": "./build/components/index.d.ts",
"default": "./build/components/index.web.js"
"development": "./build/components/index.development.web.js",
"production": "./build/components/index.production.web.js",
"default": "./build/components/index.development.web.js"
}
},
"./tokens": {
Expand All @@ -49,7 +51,9 @@
},
"default": {
"types": "./build/tokens/index.d.ts",
"default": "./build/tokens/index.web.js"
"development": "./build/tokens/index.development.web.js",
"production": "./build/tokens/index.production.web.js",
"default": "./build/tokens/index.development.web.js"
}
},
"./utils": {
Expand All @@ -59,7 +63,9 @@
},
"default": {
"types": "./build/utils/index.d.ts",
"default": "./build/utils/index.web.js"
"development": "./build/utils/index.development.web.js",
"production": "./build/utils/index.production.web.js",
"default": "./build/utils/index.development.web.js"
}
}
},
Expand All @@ -80,8 +86,9 @@
"types:copy-declarations:native": "copyfiles -u 1 \"src/**/*.d.ts\" build/types/native",
"build:generate-root-imports": "rollup -c && node ./scripts/generateRootImports.js",
"build:clean-declarations": "rm -rf build/types",
"build:react": "FRAMEWORK=REACT rollup -c && node ./scripts/generateRootImports.js",
"build:react-native": "FRAMEWORK=REACT_NATIVE rollup -c && node ./scripts/generateRootImports.js",
"build:react-dev": "FRAMEWORK=REACT NODE_ENV=development rollup -c",
"build:react-prod": "FRAMEWORK=REACT NODE_ENV=production rollup -c",
"build:react-native": "FRAMEWORK=REACT_NATIVE rollup -c",
"build:generate-css-variables": "GENERATE_CSS_VARIABLES=true FRAMEWORK=REACT rollup -c && node ./scripts/generateCssThemeVariables.js",
"build:clean-theme-bundle": "rm -rf build/js-bundle-for-css",
"react-native:get-stories": "sb-rn-get-stories --config-path=./.storybook/react-native && yarn prettier --write ./.storybook/react-native/storybook.requires.js",
Expand Down Expand Up @@ -133,6 +140,7 @@
"@rollup/plugin-babel": "5.3.1",
"@rollup/plugin-commonjs": "21.1.0",
"@rollup/plugin-node-resolve": "13.1.1",
"@rollup/plugin-replace": "5.0.2",
"@size-limit/preset-big-lib": "8.2.4",
"@storybook/addon-a11y": "6.3.0",
"@storybook/addon-actions": "6.3.0",
Expand Down Expand Up @@ -247,15 +255,15 @@
"files": [
{
"friendlyName": "Web Components",
"path": "./build/components/index.web.js"
"path": "./build/components/index.production.web.js"
},
{
"friendlyName": "React Native Components",
"path": "./build/components/index.native.js"
},
{
"friendlyName": "Web Tokens",
"path": "./build/tokens/index.web.js"
"path": "./build/tokens/index.production.web.js"
},
{
"friendlyName": "React Native Tokens",
Expand All @@ -267,7 +275,7 @@
},
{
"friendlyName": "Web Utils",
"path": "./build/utils/index.web.js"
"path": "./build/utils/index.production.web.js"
},
{
"friendlyName": "React Native Utils",
Expand All @@ -281,14 +289,14 @@
"size-limit": [
{
"name": "Import Button only",
"path": "./build/components/index.web.js",
"path": "./build/components/index.production.web.js",
"import": "{ Button }",
"limit": "20 kb",
"running": false
},
{
"name": "Import Text only",
"path": "./build/components/index.web.js",
"path": "./build/components/index.production.web.js",
"import": "{ Text }",
"limit": "15 kb",
"running": false
Expand Down
9 changes: 8 additions & 1 deletion packages/blade/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import pluginResolve from '@rollup/plugin-node-resolve';
import pluginCommonjs from '@rollup/plugin-commonjs';
import pluginDeclarations from 'rollup-plugin-dts';
import pluginAlias from '@rollup/plugin-alias';
import pluginReplace from '@rollup/plugin-replace';
// eslint-disable-next-line import/no-extraneous-dependencies
import ts from 'typescript';

Expand Down Expand Up @@ -61,13 +62,19 @@ const getWebConfig = ({ exportCategory }) => ({
input: `${inputRootDirectory}/${exportCategory}/index.ts`,
output: [
{
file: `${outputRootDirectory}/${exportCategory}/index.web.js`,
file: `${outputRootDirectory}/${exportCategory}/index.${
process.env.NODE_ENV || 'development'
}.web.js`,
format: 'esm',
sourcemap: true,
},
],
external: (id) => id.includes('@babel/runtime'),
plugins: [
pluginReplace({
__DEV__: process.env.NODE_ENV !== 'production',
preventAssignment: true,
}),
pluginPeerDepsExternal(),
pluginResolve({ extensions: webExtensions }),
pluginCommonjs(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,10 @@ const _AccordionButton = ({ index, icon: Icon, children }: AccordionButtonProps)
<Icon size="medium" color={iconColor} marginRight="spacing.3" marginY="spacing.2" />
);

if (_index && _icon) {
throw new Error(`[Blade: Accordion]: showNumberPrefix and icon shouldn't be used together`);
if (__DEV__) {
if (_index && _icon) {
throw new Error(`[Blade: Accordion]: showNumberPrefix and icon shouldn't be used together`);
}
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ const _AccordionButton = ({ index, icon: Icon, children }: AccordionButtonProps)
<Icon size="medium" color="currentColor" marginRight="spacing.3" marginY="spacing.2" />
);

if (_index && _icon) {
throw new Error(`[Blade: Accordion]: showNumberPrefix and icon shouldn't be used together`);
if (__DEV__) {
if (_index && _icon) {
throw new Error(`[Blade: Accordion]: showNumberPrefix and icon shouldn't be used together`);
}
}

const isItemExpanded = expandedIndex === index;
Expand Down
12 changes: 7 additions & 5 deletions packages/blade/src/components/Accordion/AccordionContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ const AccordionContext = createContext<AccordionContextState | null>(null);

const useAccordion = (): AccordionContextState => {
const accordionContext = useContext(AccordionContext);
if (!accordionContext) {
throw new Error(
`[Blade: AccordionContext]: useAccordion should be only used within AccordionContext`,
);
if (__DEV__) {
if (!accordionContext) {
throw new Error(
`[Blade: AccordionContext]: useAccordion should be only used within AccordionContext`,
);
}
}
return accordionContext;
return accordionContext!;
};

export { AccordionContext, useAccordion, AccordionContextState };
10 changes: 6 additions & 4 deletions packages/blade/src/components/ActionList/ActionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ const ActionListContext = React.createContext<ActionListContextProp>({ surfaceLe
const useActionListContext = (): ActionListContextProp => {
const context = React.useContext(ActionListContext);

if (!context) {
throw new Error(
'[Blade ActionList]: useActionListContext has to be called inside ActionListContext.Provider',
);
if (__DEV__) {
if (!context) {
throw new Error(
'[Blade ActionList]: useActionListContext has to be called inside ActionListContext.Provider',
);
}
}
return context;
};
Expand Down
10 changes: 6 additions & 4 deletions packages/blade/src/components/ActionList/ActionListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,12 @@ const _ActionListItem = (props: ActionListItemProps): JSX.Element => {
}, [props.leading, props.trailing]);

React.useEffect(() => {
if (dropdownTriggerer === 'SelectInput' && props.intent === 'negative') {
throw new Error(
'[ActionListItem]: negative intent ActionListItem cannot be used inside Dropdown with SelectInput trigger',
);
if (__DEV__) {
if (dropdownTriggerer === 'SelectInput' && props.intent === 'negative') {
throw new Error(
'[ActionListItem]: negative intent ActionListItem cannot be used inside Dropdown with SelectInput trigger',
);
}
}
}, [props.intent, dropdownTriggerer]);

Expand Down
54 changes: 29 additions & 25 deletions packages/blade/src/components/ActionList/actionListUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,11 @@ const getActionListProperties = (
return getActionListItemWithId(child, true);
}

throw new Error(
`[ActionList]: Only ${actionListAllowedChildren.join(', ')} supported inside ActionList`,
);
if (__DEV__) {
throw new Error(
`[ActionList]: Only ${actionListAllowedChildren.join(', ')} supported inside ActionList`,
);
}
}
return child;
});
Expand All @@ -179,28 +181,30 @@ const validateActionListItemProps = ({
leading: ActionListItemProps['leading'];
trailing: ActionListItemProps['trailing'];
}): void => {
React.Children.map(trailing, (child) => {
if (
!isValidAllowedChildren(child, componentIds.ActionListItemIcon) &&
!isValidAllowedChildren(child, componentIds.ActionListItemText)
) {
throw new Error(
`[ActionListItem]: Only ${componentIds.ActionListItemIcon} and ${componentIds.ActionListItemText} are allowed in trailing prop`,
);
}
});

React.Children.map(leading, (child) => {
if (
!isValidAllowedChildren(child, componentIds.ActionListItemIcon) &&
!isValidAllowedChildren(child, componentIds.ActionListItemText) &&
!isValidAllowedChildren(child, componentIds.ActionListItemAsset)
) {
throw new Error(
`[ActionListItem]: Only ${componentIds.ActionListItemIcon}, ${componentIds.ActionListItemAsset}, and ${componentIds.ActionListItemText} are allowed in leading prop`,
);
}
});
if (__DEV__) {
React.Children.map(trailing, (child) => {
if (
!isValidAllowedChildren(child, componentIds.ActionListItemIcon) &&
!isValidAllowedChildren(child, componentIds.ActionListItemText)
) {
throw new Error(
`[ActionListItem]: Only ${componentIds.ActionListItemIcon} and ${componentIds.ActionListItemText} are allowed in trailing prop`,
);
}
});

React.Children.map(leading, (child) => {
if (
!isValidAllowedChildren(child, componentIds.ActionListItemIcon) &&
!isValidAllowedChildren(child, componentIds.ActionListItemText) &&
!isValidAllowedChildren(child, componentIds.ActionListItemAsset)
) {
throw new Error(
`[ActionListItem]: Only ${componentIds.ActionListItemIcon}, ${componentIds.ActionListItemAsset}, and ${componentIds.ActionListItemText} are allowed in leading prop`,
);
}
});
}
};

const getNormalTextColor = (
Expand Down
10 changes: 6 additions & 4 deletions packages/blade/src/components/Alert/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,12 @@ const Alert = ({
testID,
...styledProps
}: AlertProps): ReactElement | null => {
if (!actions?.primary && actions?.secondary) {
throw new Error(
'[Blade: Alert]: SecondaryAction is allowed only when PrimaryAction is defined.',
);
if (__DEV__) {
if (!actions?.primary && actions?.secondary) {
throw new Error(
'[Blade: Alert]: SecondaryAction is allowed only when PrimaryAction is defined.',
);
}
}
const { theme } = useTheme();
const { matchedDeviceType } = useBreakpoint({ breakpoints: theme.breakpoints });
Expand Down
14 changes: 8 additions & 6 deletions packages/blade/src/components/Amount/Amount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -230,12 +230,14 @@ const _Amount = ({
currency = 'INR',
...styledProps
}: AmountProps): ReactElement => {
if (typeof value !== 'number') {
throw new Error('[Blade: Amount]: `value` prop must be of type `number` for Amount.');
}
// @ts-expect-error neutral intent should throw error
if (intent === 'neutral') {
throw new Error('[Blade Amount]: `neutral` intent is not supported.');
if (__DEV__) {
if (typeof value !== 'number') {
throw new Error('[Blade: Amount]: `value` prop must be of type `number` for Amount.');
}
// @ts-expect-error neutral intent should throw error
if (intent === 'neutral') {
throw new Error('[Blade Amount]: `neutral` intent is not supported.');
}
}

const currencyPrefix = currencyPrefixMapping[currency][prefix];
Expand Down
6 changes: 4 additions & 2 deletions packages/blade/src/components/Badge/Badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,10 @@ const _Badge = ({
...styledProps
}: BadgeProps): ReactElement => {
const childrenString = getStringFromReactText(children);
if (!childrenString?.trim()) {
throw new Error('[Blade: Badge]: Text as children is required for Badge.');
if (__DEV__) {
if (!childrenString?.trim()) {
throw new Error('[Blade: Badge]: Text as children is required for Badge.');
}
}
const { backgroundColor, iconColor, textColor } = getColorProps({
variant,
Expand Down
14 changes: 8 additions & 6 deletions packages/blade/src/components/BaseHeaderFooter/BaseHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,14 @@ const useTrailingRestriction = (trailing: React.ReactNode): React.ReactNode => {
const trailingComponentType = getComponentId(trailing) as TrailingComponents;
const restrictedProps = propRestrictionMap[trailingComponentType];
const allowedComponents = Object.keys(propRestrictionMap);
if (!restrictedProps) {
throw new Error(
`[Blade Header]: Only one of \`${allowedComponents.join(
', ',
)}\` component is accepted as trailing`,
);
if (__DEV__) {
if (!restrictedProps) {
throw new Error(
`[Blade Header]: Only one of \`${allowedComponents.join(
', ',
)}\` component is accepted as trailing`,
);
}
}

const restrictedPropKeys = Object.keys(propRestrictionMap[trailingComponentType]);
Expand Down
Loading

0 comments on commit cbed430

Please sign in to comment.