diff --git a/package.json b/package.json index 37d1997..b934997 100644 --- a/package.json +++ b/package.json @@ -14,9 +14,10 @@ "lint:prettier": "prettier './**/*.js' './**/*.css' './**/*.md' --list-different", "typecheck": "tsc", "build": "yarn run clean && yarn run rollup -c", + "checkimport": "scripts/check-imports", "clean": "rimraf dist", "prettier:fix": "prettier './**/*.js' './**/*.css' './**/*.md' --write", - "ci": "yarn run lint && yarn run lint:prettier && yarn run test && yarn run typecheck && yarn run build", + "ci": "yarn run lint && yarn run lint:prettier && yarn run test && yarn run typecheck && yarn run build && yarn run checkimport", "prepublish": "yarn run ci", "doctoc": "doctoc README.md", "storybook": "start-storybook -p 6006 " @@ -108,4 +109,4 @@ "react": "^16.8.0", "react-dom": "^16.8.0" } -} +} \ No newline at end of file diff --git a/rollup.config.js b/rollup.config.js index 5cec006..c86b6b9 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -30,14 +30,7 @@ export default [ }, }, ], - plugins: [ - ts(), - resolve(), - babel(), - commonjs({ - namedExports: {'prop-types': ['func', 'object', 'any', 'string']}, - }), - ], + plugins: [ts(), resolve(), babel(), commonjs()], }, // Minified UMD Build without PropTypes { @@ -58,9 +51,7 @@ export default [ resolve(), babel(), replace({'process.env.NODE_ENV': JSON.stringify('production')}), - commonjs({ - namedExports: {'prop-types': ['func', 'object', 'any', 'string']}, - }), + commonjs(), terser(), ], }, diff --git a/scripts/check-imports b/scripts/check-imports new file mode 100755 index 0000000..dc3c536 --- /dev/null +++ b/scripts/check-imports @@ -0,0 +1,22 @@ +#!/bin/sh + +# Generated type definitions should not include default imports. + +BASE_DIR="$(dirname "$0")/.."; + +OUTPUT_FILE="/dist/react-stripe.d.ts" + +grep 'import [^*{]' "${BASE_DIR}${OUTPUT_FILE}" + +case $? in + 1) true + ;; + 0) + echo "Found disallowed default import in ${OUTPUT_FILE}" + echo 'Please only use * or named imports for types' + false + ;; + *) + false + ;; +esac \ No newline at end of file diff --git a/src/components/Elements.test.js b/src/components/Elements.test.js index 89ed1f7..e2b6037 100644 --- a/src/components/Elements.test.js +++ b/src/components/Elements.test.js @@ -1,4 +1,4 @@ -import * as React from 'react'; +import React from 'react'; import {act} from 'react-dom/test-utils'; import {mount} from 'enzyme'; import {Elements, useElements, useStripe, ElementsConsumer} from './Elements'; diff --git a/src/components/Elements.tsx b/src/components/Elements.tsx index 53e8340..e4e0734 100644 --- a/src/components/Elements.tsx +++ b/src/components/Elements.tsx @@ -1,4 +1,7 @@ +// Must use `import *` or named imports for React's types import * as React from 'react'; +import * as stripeJs from '@stripe/stripe-js'; + import { createContext, useContext, @@ -6,11 +9,8 @@ import { useState, useEffect, useRef, - ReactNode, - ReactElement, } from 'react'; -import * as PropTypes from 'prop-types'; -import * as stripeJs from '@stripe/stripe-js'; +import PropTypes from 'prop-types'; import {isEqual} from '../utils/isEqual'; import {usePrevious} from '../utils/usePrevious'; @@ -93,7 +93,7 @@ interface ElementsProps { interface PrivateElementsProps { stripe: unknown; options?: stripeJs.StripeElementsOptions; - children?: ReactNode; + children?: React.ReactNode; } /** @@ -199,7 +199,7 @@ export const useStripe = (): stripeJs.Stripe | null => { }; interface ElementsConsumerProps { - children: (props: ElementsContextValue) => ReactNode; + children: (props: ElementsContextValue) => React.ReactNode; } /** @@ -211,7 +211,7 @@ export const ElementsConsumer: React.FC = ({ const ctx = useElementsContextWithUseCase('mounts '); // Assert to satsify the busted React.FC return type (it should be ReactNode) - return children(ctx) as ReactElement | null; + return children(ctx) as React.ReactElement | null; }; ElementsConsumer.propTypes = { diff --git a/src/components/createElementComponent.test.js b/src/components/createElementComponent.test.js index 84eca5d..223d260 100644 --- a/src/components/createElementComponent.test.js +++ b/src/components/createElementComponent.test.js @@ -1,10 +1,15 @@ -import * as React from 'react'; -import {useLayoutEffect} from 'react'; +import React, {useLayoutEffect} from 'react'; import {mount} from 'enzyme'; import {Elements} from './Elements'; import createElementComponent from './createElementComponent'; import {mockElements, mockElement, mockStripe} from '../../test/mocks'; +jest.mock('react', () => { + const actual = jest.requireActual('react'); + jest.spyOn(actual, 'useLayoutEffect'); + return actual; +}); + describe('createElementComponent', () => { let stripe; let elements; @@ -22,7 +27,7 @@ describe('createElementComponent', () => { element = mockElement(); stripe.elements.mockReturnValue(elements); elements.create.mockReturnValue(element); - jest.spyOn(React, 'useLayoutEffect'); + useLayoutEffect.mockClear(); element.on = jest.fn((event, fn) => { switch (event) { case 'change': diff --git a/src/components/createElementComponent.tsx b/src/components/createElementComponent.tsx index b313d41..8df1723 100644 --- a/src/components/createElementComponent.tsx +++ b/src/components/createElementComponent.tsx @@ -1,8 +1,10 @@ +// Must use `import *` or named imports for React's types import * as React from 'react'; -import {useRef, useEffect, useLayoutEffect} from 'react'; -import * as PropTypes from 'prop-types'; import * as stripeJs from '@stripe/stripe-js'; +import {useRef, useEffect, useLayoutEffect} from 'react'; +import PropTypes from 'prop-types'; + import {useElementsContextWithUseCase} from './Elements'; import {useCallbackReference} from '../utils/useCallbackReference'; import {isEqual} from '../utils/isEqual'; diff --git a/test/setupJest.js b/test/setupJest.js index 05e8e81..96bab7d 100644 --- a/test/setupJest.js +++ b/test/setupJest.js @@ -1,4 +1,4 @@ import {configure} from 'enzyme'; -import * as Adapter from 'enzyme-adapter-react-16'; +import Adapter from 'enzyme-adapter-react-16'; configure({adapter: new Adapter()}); diff --git a/tsconfig.json b/tsconfig.json index 1247ede..5c01be9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,8 +10,7 @@ "removeComments": false, "strict": true, "forceConsistentCasingInFileNames": true, - "esModuleInterop": false // Must remain `false` to emit types compatible with other projects not using `esModuleInterop` + "esModuleInterop": true }, "include": ["./src"] } -