Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Styling custom components with NextJs #447

Closed
TheJohnPython opened this issue Jul 4, 2019 · 24 comments
Closed

Styling custom components with NextJs #447

TheJohnPython opened this issue Jul 4, 2019 · 24 comments
Labels
bug 🐛 Issue is a confirmed bug needs: investigation 🔎 Issue has to be investigated for reason or solution platform: next.js 🛠️ Issue related to next.js priority: medium 💻 Issue is important but not the most important

Comments

@TheJohnPython
Copy link

I'm using NextJs with linaria and trying to apply styled on custom component:

function CoolComponent({ className, style }) {
  return (
    <div className={className} style={style}>My Component</div>
  );
}

const StyledCoolComponent = styled(CoolComponent)`
  background-color: red;
`;

and get error:

import React from "react";
       ^^^^^

SyntaxError: Unexpected identifier
@TheJohnPython
Copy link
Author

But it works if i pass anonymous function:

const StyledCoolComponent = styled(
  p => (<div className={p.className}>My Component</div>)
)`
  background-color: red;
`

@satya164
Copy link
Member

satya164 commented Jul 5, 2019

Do you have a .babelrc/babel.config.js file? You need it

@TheJohnPython
Copy link
Author

TheJohnPython commented Jul 5, 2019

Do you have a .babelrc/babel.config.js file? You need it

yes

{
  "presets": [
    "next/babel",
    "linaria/babel"
  ]
}

like in this example https://github.com/zeit/next.js/tree/canary/examples/with-linaria

@eviL-ivan
Copy link

eviL-ivan commented Jul 7, 2019

Same issue:#454

Codesandbox example

@mikestopcontinues
Copy link
Contributor

Yeah, this has been a big headache trying to port from styled-components. I believe it might be a result of using the wrong babel bundling strategy (module: true vs module: false).

@talentlessguy
Copy link

Linaria doesn't work in Next.js, it just produces classes not assigned to anything.

import React from 'react'
import { styled } from 'linaria/react'

const Center = styled.div`
  display: flex;

image

@mikestopcontinues
Copy link
Contributor

@talentlessguy, check the README again. Linaria definitely does work with Next if you set up everything correctly. If you're sure your config is correct, then you should create a new issue. This thread is for a different problem.

@Tarnadas
Copy link

I also stumbled across this problem and found out that applying styled on an already transpired/bundled Component from a dependency, everything works fine.

import { Headroom } from 'react-headroom'
...
styled(Headroom)...

This doesn't throw an error since it's already transpired. There must be a problem with Next config that breaks Babel transpilation

@Jayphen
Copy link
Contributor

Jayphen commented Jan 30, 2020

It's probably not helpful, but just confirming this still occurs with the latest version of Next + Linaria's latest beta. I'm not smart enough to figure out how to fix this.

@talentlessguy
Copy link

@mikestopcontinues

I have linaria babel plugin installed:

{ 
  "presets": ["next/babel", "linaria/babel"]
}

@mikestopcontinues
Copy link
Contributor

@talentlessguy you've also got to update your next.config.js. Look through all the files here and see if you're missing anything else. https://github.com/zeit/next.js/tree/master/examples/with-linaria

@talentlessguy
Copy link

@mikestopcontinues hm ok it works now but only with withCSS plugin but Next.js already supports CSS modules and global CSS now.

@Pytal
Copy link

Pytal commented Feb 23, 2020

Anyone able to get Linaria working with CSS modules and Next.js?

@mikestopcontinues
Copy link
Contributor

It works perfectly for me just following the readme and example I posted above. @Pytal

@Jayphen
Copy link
Contributor

Jayphen commented Feb 23, 2020

The above comments are a little bit confusing and a diversion from the purpose of this issue.

The Next.js example is still broken when wrapping a React component with styled, as seen at https://codesandbox.io/embed/hello-world-bu9q8

The following pattern does not work

function Component(props) { return <div {…props}>Hello</div> }

const StyledComponent = styled(Component)`color: red`

This fails to compile:

Failed to compile
./pages/index.js
/sandbox/pages/index.js:4
import React from "react";
       ^^^^^

SyntaxError: Unexpected identifier

This is still an issue and seems to be something to do with the way Webpack or Babel are configured in the example.

@fernandojbf
Copy link

fernandojbf commented Feb 28, 2020

I think the problem is between next/babel and linaria.
If you remove next/babel and add a few ones to make the project working (like preset-env and preset-react) the problem is solved.

A workaround is removing your .babelrc from the project and add the configuration to your linaria.config.js like:

{
// ...
babelOptions: {
    presets: ["@babel/preset-env", "@babel/preset-react", "linaria/babel"]
  }
}

This solves the issue.
(I need to check, in terms of build result, if everything looks good, but with a quick look it seems ok.)

@mikestopcontinues
Copy link
Contributor

@fernandojbf, that's a great short-term solution, and I'm grateful for it. Though next may update to include other crucial config in their preset. We shouldn't plan against it. There must be something fixable about next's preset or linaria's preset to ensure the problem doesn't come back.

@fernandojbf
Copy link

@mikestopcontinues yes, this was intended to be short-term solution. I've tested some configurations on the next/babel without success. But i will investigate further this later :)

@jayu
Copy link
Contributor

jayu commented Mar 31, 2020

It would be awesome to support next.js. If there is a real issue with configs we should solve it or write better docs on how to integrate those two projects. I will put it on my list to check what's exactly going on.

@jayu jayu added bug 🐛 Issue is a confirmed bug needs: investigation 🔎 Issue has to be investigated for reason or solution platform: next.js 🛠️ Issue related to next.js priority: medium 💻 Issue is important but not the most important labels Mar 31, 2020
@twolettername
Copy link

twolettername commented Apr 26, 2020

I ran into this one today with the set-up detailed in the next.js example config mentioned above.

Messing around with next.js next/babel preset, modifying these two to be different from one another fixes the build (though changing the pragma option on preset-react breaks when it renders):

https://github.com/zeit/next.js/blob/v9.3.5/packages/next/build/babel/preset.ts#L130
https://github.com/zeit/next.js/blob/v9.3.5/packages/next/build/babel/preset.ts#L115

It starts to break again once they're both set to the same name, though. Note that it doesn't matter what you set the option to, as long as they're both the same (so it isn't any special handling on the name itself but what it's doing - setting both pragma options to "foo" still breaks).

Diving deeper, their jsx-pragma plugin modifies imports to be:

import React from 'react';
var __jsx = React.createElement;

I can't tell anything more, though (would need to dive a lot more into how Babel traverses the AST and where, when, and how Linaria comes into play here), though I do know the issue occurs when the plugin is modifying files via babel's AST parser / traverser / whatever (very unfamiliar with it).

This would explain why #447 (comment) works: you're removing this plugin entirely.

I'm not sure about what jsx-pragma is even for and so I'm not sure what the effects of working around this would be - hopefully this helps anyone else more familiar with linaria, babel, and next.js narrow the issue down.

@jayu
Copy link
Contributor

jayu commented Apr 28, 2020

Thanks @twolettername, your research really helps to understand what causes the issue. During the evaluation, we cannot have any import statements, because node does not understand them, they should be transformed to require statements.

The problem is this jsx-pragma which is adding this import. It is not a responsible behavior since it may break many environments. It was introduced in vercel/next.js#8350 and causes issue like vercel/next.js#9253. Next uses it for some optimizations.

However, the issue will be solved in Linaria 2.0 release, due to too a new evaluation strategy.

For now, to fix it, you should use the lastest Linaria beta for1.4.0 (or stable 1.4.0 in future) or alpha of 2.0.0 (or stable 2.0.0) in the future with the following config in linaria.config.js:
At the moment of writing this, you can yarn add linaria@2.0.0-alpha.1

const shaker = require('linaria/lib/babel/evaluators/shaker').default;

module.exports = {
    displayName: process.env.NODE_ENV !== 'production',
    rules: [
        {
            action: shaker,
        },
        {
            test: /\/node_modules\//,
            action: 'ignore',
        },
    ],
};

It enables mentioned shaker strategy and this troublesome react import is no longer contained in file for evaluation.

@marbiano
Copy link

Next.js example fixed: vercel/next.js#13568 :)

@Mizumaki
Copy link

For me, this library works well

https://github.com/Mistereo/next-linaria

@Grong1515
Copy link

Grong1515 commented Feb 11, 2021

The issue is still present. Just as it described in the first message. I found a solution in this emotion.js issue they had the same problem.
So could solve this by setting my babelrc like this:

{
  "presets": [
    [
      "next/babel",
      {
        "preset-react": {
          "runtime": "automatic"
        }
      }
    ],
    "linaria/babel"
  ]
}

and installing @babel/preset-env as it asked:

info  - Creating an optimized production build  
Failed to compile.

./pages/index.js
Error: path_to/with-linaria-app/pages/index.js: An unexpected runtime error ocurred during dependencies evaluation: 
Error: Cannot find module '@babel/preset-env'

Hope it'll help someone :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Issue is a confirmed bug needs: investigation 🔎 Issue has to be investigated for reason or solution platform: next.js 🛠️ Issue related to next.js priority: medium 💻 Issue is important but not the most important
Projects
None yet
Development

No branches or pull requests