Emotion: transpile typescript to babel-plugin-emotion doesn't work

Created on 12 Jan 2018  路  6Comments  路  Source: emotion-js/emotion

I try to get this running properly. How could I set this up correctly?

You can find the sample code here.

  • emotion version: 8.0.12
  • react version: 16.2.0
      "babel-core": "6.26.0",
      "babel-loader": "7.1.2",
      "babel-plugin-emotion": "8.0.12",
      "babel-preset-env": "1.6.1",      
      "babel-preset-react" : "6.24.1",      
       "awesome-typescript-loader": "3.4.1",           
      "typescript": "2.6.2",
      "webpack": "3.10.0",   

Relevant code.

const Child = styled('div')`
    color: red;
`

const Parent = styled('div')`
    ${Child} {
       color: green;
    }
`
class HelloWorld extends React.Component<{}, {}> {

  render(){
   return(
    <div>
      <Parent>
        <Child>green</Child>
      </Parent>
      <Child>red</Child>
    </div>
  )}
}

What you did:

Running webpack with the following settings:

var webpack = require("webpack");
const path = require("path");

module.exports = () => {
    return [{
        entry: [        
            "./src/index.tsx"
        ],
        output: {
            path: path.join(__dirname, 'build'),                        
            filename: "bundle.js"        
        },

        resolve: {           
            extensions: [".webpack.js", ".web.js", ".ts", ".tsx", ".js"],        
        },        

        module: {
            loaders: [                               
                {
                    test: /\.tsx?$/,
                    loaders : ['babel-loader', 'awesome-typescript-loader'],
                    exclude: path.resolve(__dirname, 'node_modules')                
                }            
            ]
        }  
    }];
};

```` 
.bablerc

{
"presets": ["env"],
"env": {
"development": {
"plugins": [["emotion", { "autoLabel" : true }]]
}
}
}

Open up index.html.

What happened:

bundle.js:2185 Uncaught Error: Component selectors can only be used in conjunction with babel-plugin-emotion.
at Styled.handleInterpolation (bundle.js:2185)
at Styled. (bundle.js:2274)
at Array.forEach ()
at Styled.createStyles (bundle.js:2273)
at Styled.css (bundle.js:2302)
at Styled.render (bundle.js:19935)
at finishClassComponent (bundle.js:12093)
at updateClassComponent (bundle.js:12070)
at beginWork (bundle.js:12445)
at performUnitOfWork (bundle.js:14444)
```

Reproduction:

https://github.com/Wezea/ts-with-babel-plugin-emotion

Problem description:

Typescript gets transpiled to es6 which is transpiled to es5 by using babel. But babel-plugin-emotion seems not to be triggered at all.

Most helpful comment

I think this happens because typescripts compiles the imports so babel-plugin-emotion doesn't know which styled calls to transform. I played around the with typescript options a bit and changing it like this fixed it.

diff --git a/tsconfig.json b/tsconfig.json
index 874f32d..00bbfd4 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -2,7 +2,8 @@
     "compilerOptions": {                        
         "noImplicitAny": true,        
         "sourceMap": true,
-        "module": "commonjs",
+        "module": "es2015",
+        "moduleResolution": "node",
         "target": "es6",
         "jsx": "react",        
         "types": [  

I'm gonna close this, if this didn't fix your issue, please reopen the issue.

All 6 comments

I think this happens because typescripts compiles the imports so babel-plugin-emotion doesn't know which styled calls to transform. I played around the with typescript options a bit and changing it like this fixed it.

diff --git a/tsconfig.json b/tsconfig.json
index 874f32d..00bbfd4 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -2,7 +2,8 @@
     "compilerOptions": {                        
         "noImplicitAny": true,        
         "sourceMap": true,
-        "module": "commonjs",
+        "module": "es2015",
+        "moduleResolution": "node",
         "target": "es6",
         "jsx": "react",        
         "types": [  

I'm gonna close this, if this didn't fix your issue, please reopen the issue.

Thank you for the fast response, that did the trick.

Didn't work for me.

.storybook/webpack.config.js

module.exports = async ({
    config
}) => {
    config.module.rules.push({
        test: /\.(ts|tsx)$/,
        use: [{
                loader: require.resolve('awesome-typescript-loader'),
                options: {
                    useBabel: true,
                    babelOptions: {
                        babelrc: false,
                        presets: ["@babel/preset-env", "@emotion/babel-preset-css-prop"],
                        plugins: ["emotion"]
                    },
                    babelCore: "@babel/core",
                },
            },
            {
                loader: require.resolve('react-docgen-typescript-loader'),
            },
        ],
    });
    config.resolve.extensions.push('.ts', '.tsx');
    return config;
};

Didn't work if I use Theme.

Like this:

import emotionStyled, { CreateStyled } from '@emotion/styled'

export interface Theme {
  ...
}

export const styled = emotionStyled as CreateStyled<Theme>

And if use import styled from '@emotion/styled' directly, It worked!

Same here, doesn't work if I use a theme, please reopen !!

This is something which we plan to fix with https://github.com/emotion-js/emotion/pull/1220

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mitchellhamilton picture mitchellhamilton  路  3Comments

kentcdodds picture kentcdodds  路  3Comments

bitttttten picture bitttttten  路  3Comments

tkh44 picture tkh44  路  3Comments

mattfysh picture mattfysh  路  3Comments