emotion-js / emotion

👩‍🎤 CSS-in-JS library designed for high performance style composition
https://emotion.sh/
MIT License
17.5k stars 1.11k forks source link

Jest tests with both emotion & styled-components #248

Closed ericclemmons closed 6 years ago

ericclemmons commented 7 years ago

Relevant code.

// .babelrc
plugins: {  "emotion/babel" }

What you did:

What happened:

FAIL src/components/SchoolBanners/SchoolBanners.stories.js ● School Banners › Base Example

Invariant Violation: Component(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

More at invariant (node_modules/fbjs/lib/invariant.js:44:15) at ReactCompositeComponentWrapper.mountComponent (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:195:114) at Object.mountComponent (node_modules/react-test-renderer/lib/ReactReconciler.js:46:35) at ReactTestComponent.mountChildren (node_modules/react-test-renderer/lib/ReactMultiChild.js:238:44) at ReactTestComponent.mountComponent (node_modules/react-test-renderer/lib/ReactTestRenderer.js:62:10) at Object.mountComponent (node_modules/react-test-renderer/lib/ReactReconciler.js:46:35) at ReactCompositeComponentWrapper.performInitialMount (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:371:34) at ReactCompositeComponentWrapper.mountComponent (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:258:21) at Object.mountComponent (node_modules/react-test-renderer/lib/ReactReconciler.js:46:35) at ReactCompositeComponentWrapper._updateRenderedComponent (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:765:40) at ReactCompositeComponentWrapper._performComponentUpdate (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:724:10) at ReactCompositeComponentWrapper.updateComponent (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:645:12) at ReactCompositeComponentWrapper.performUpdateIfNecessary (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:561:12) at Object.performUpdateIfNecessary (node_modules/react-test-renderer/lib/ReactReconciler.js:157:22) at runBatchedUpdates (node_modules/react-test-renderer/lib/ReactUpdates.js:150:21) at ReactTestReconcileTransaction.perform (node_modules/react-test-renderer/lib/Transaction.js:140:20) at ReactUpdatesFlushTransaction.perform (node_modules/react-test-renderer/lib/Transaction.js:140:20) at ReactUpdatesFlushTransaction.perform (node_modules/react-test-renderer/lib/ReactUpdates.js:89:32) at Object.flushBatchedUpdates (node_modules/react-test-renderer/lib/ReactUpdates.js:172:19) at ReactDefaultBatchingStrategyTransaction.closeAll (node_modules/react-test-renderer/lib/Transaction.js:206:25) at ReactDefaultBatchingStrategyTransaction.perform (node_modules/react-test-renderer/lib/Transaction.js:153:16) at Object.batchedUpdates (node_modules/react-test-renderer/lib/ReactDefaultBatchingStrategy.js:62:26) at Object.batchedUpdates (node_modules/react-test-renderer/lib/ReactUpdates.js:97:27) at Object.render (node_modules/react-test-renderer/lib/ReactTestMount.js:125:18) at Object. (src/__mocks__/storybook.js:11:40) at process._tickCallback (internal/process/next_tick.js:103:7)

Reproduction:

Problem description:

Suggested solution:

thangngoc89 commented 7 years ago

This is because babel plugin transpiles emotion/styled-components like template literals so it breaks styled-component. And emotion can't work without the babel plugin.

tkh44 commented 7 years ago

It can work without the plugin but it's really only good for object styles. We might be able to support checking if the emotion import is at the top of a file before transforming it. I'm not absolutely sure. This is more of @mitchellhamilton's area.

emmatown commented 7 years ago

We could do a check for that but I'm not sure if it's a good idea because it would mean that people couldn't use custom runtimes (e.g. emotion-vue).

I think there are two possible solutions to this problem. Firstly, use the babel macro, this would fix the problem but it would mean you can't use extractStatic. Secondly, rename styled-components' styled so emotion's babel plugin doesn't change it. I wrote a little codemod to do this, it's not perfect but it should work in most cases.

ericclemmons commented 7 years ago

I've done babel plugins myself (was adding HMR to functional components) and keying off of emotion's variable assignment of styled would be the most predictable path, as that would solidify emotion/babel's behavior.

stale[bot] commented 6 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.