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

Unexpected identifier? #19

Closed
deklanw opened this issue Jul 31, 2019 · 21 comments · Fixed by #104
Closed

Unexpected identifier? #19

deklanw opened this issue Jul 31, 2019 · 21 comments · Fixed by #104
Labels
bug Something isn't working help wanted Extra attention is needed
Milestone

Comments

@deklanw
Copy link

deklanw commented Jul 31, 2019

I'm using TypeScript. Linaria is after TypeScript in my config.

./src/components/header.tsx
Module build failed (from ./node_modules/linaria/loader.js):
C:\Users\deklan\Documents\Code\gatsby-testing\gatsby-site\node_modules\@reach\router\es\index.js:12
import React from "react";
       ^^^^^

SyntaxError: Unexpected identifier
    at new Script (vm.js:83:7)
    at Module.evaluate (C:\Users\deklan\Documents\Code\gatsby-testing\gatsby-site\node_modules\linaria\lib\babel\module.js:200:18)
    at Module.<anonymous> (C:\Users\deklan\Documents\Code\gatsby-testing\gatsby-site\node_modules\linaria\lib\babel\module.js:184:13)
    at Module.require (C:\Users\deklan\Documents\Code\gatsby-testing\gatsby-site\node_modules\linaria\lib\babel\module.js:134:23)
    at C:\Users\deklan\Documents\Code\gatsby-testing\gatsby-site\node_modules\gatsby-link\index.js:24:15
    at Script.runInContext (vm.js:133:20)
    at Module.evaluate (C:\Users\deklan\Documents\Code\gatsby-testing\gatsby-site\node_modules\linaria\lib\babel\module.js:203:12)
    at Module.<anonymous> (C:\Users\deklan\Documents\Code\gatsby-testing\gatsby-site\node_modules\linaria\lib\babel\module.js:184:13)
    at Module.require (C:\Users\deklan\Documents\Code\gatsby-testing\gatsby-site\node_modules\linaria\lib\babel\module.js:134:23)
    at C:\Users\deklan\Documents\Code\gatsby-testing\gatsby-site\.cache\gatsby-browser-entry.js:69:43
    at Script.runInContext (vm.js:133:20)
    at Module.evaluate (C:\Users\deklan\Documents\Code\gatsby-testing\gatsby-site\node_modules\linaria\lib\babel\module.js:203:12)
    at Module.<anonymous> (C:\Users\deklan\Documents\Code\gatsby-testing\gatsby-site\node_modules\linaria\lib\babel\module.js:184:13)
    at Module.require (C:\Users\deklan\Documents\Code\gatsby-testing\gatsby-site\node_modules\linaria\lib\babel\module.js:134:23)
    at C:\Users\deklan\Documents\Code\gatsby-testing\gatsby-site\src\components\header.tsx:3:15
    at Script.runInContext (vm.js:133:20)
import React from 'react';
import { Link } from 'gatsby';
import { styled } from 'linaria/react';

type Props = {
   siteTitle: string;
};

const HeaderContainer = styled.div`
   background: rebeccapurple;
   margin-bottom: 1.45rem;
`;

const NameBlock = styled.div`
   margin: 0 auto;
   max-width: 960;
   padding: 1.45rem 1.0875rem;
`;

const StyledLink = styled(Link)`
   color: white;
   text-decoration: none;
`;

const Heading = styled.h1`
   margin: 0;
`;

const Header: React.FC<Props> = ({ siteTitle }) => (
   <HeaderContainer>
      <NameBlock>
         <Heading>
            <StyledLink to="/">{siteTitle}</StyledLink>
         </Heading>
      </NameBlock>
   </HeaderContainer>
);

export default Header;
@silvenon silvenon added the bug Something isn't working label Aug 8, 2019
@silvenon
Copy link
Collaborator

silvenon commented Aug 8, 2019

This error isn't related to TypeScript, it's caused by specifically wrapping Gatsby's Link with styled. I'm not sure why this component in particular is problematic.

@cometkim
Copy link
Owner

cometkim commented Aug 17, 2019

I investigated for hours and found that it was a webpack setup problem with gatsby. The problem will only happen with <Link/> components of gatsby or @reach/router and others will be fine.

in detail:

GatsbyJS provide an alias for @reach/router when stage is about web: https://github.com/gatsbyjs/gatsby/blob/8d66161e4b/packages/gatsby/src/utils/webpack.config.js#L405

So the result of require(@reach/router) is resolved as es module which is linaria evaluator can't understand.

Linaria loader uses it here: https://github.com/callstack/linaria/blob/0ddfc9bb8eba99fe7e0b54790b5cf47493e207ea/src/loader.js#L43

That's why there is import React from "react"; unexpected identifier.

We should find some way to make linaria ignore the alias or to make linaria understand es module syntax.

@silvenon
Copy link
Collaborator

Omg! 😵 Thanks! ❤️

Brainstorming: one way could be to create a Babel plugin that transforms require('@reach/router') into something synonymous that wouldn't be caught by the alias, and pass it to Linaria loader?

@cometkim
Copy link
Owner

Or just do forgery the linaria package on postinstall of gatsby-plugin-linaria? This is the simplest way I have right now Haha...

@cometkim
Copy link
Owner

cometkim commented Aug 17, 2019

Brainstorming: one way could be to create a Babel plugin that transforms require('@reach/router') into something synonymous that wouldn't be caught by the alias, and pass it to Linaria loader?

@silvenon I just have done PoC of your idea. It would require two fixes:

  1. replace @reach/router into @reach/router$ (exact match alias) in the webpack config.
  2. Make plugin transforms require('@reach/router') into require('@reach/router/index.js') and give it babelOptions of linaria loader.
const config = getConfig();
const routerAlias = config.resolve.alias['@reach/router'];
if (routerAlias) {
  delete config.resolve.alias['@reach/router'];
  config.resolve.alias['@reach/router$'] = routerAlias;
}
replaceWebpackConfig(config);

Little hacky, but It would work without touching gatsby and linaria.

Since the @reach/router's es package is completely separate, we can be sure that direct references to index.js always want the commonjs module.

@cometkim cometkim added the help wanted Extra attention is needed label Aug 17, 2019
@silvenon
Copy link
Collaborator

Or just do forgery the linaria package on postinstall of gatsby-plugin-linaria?

What do you mean by this?

@cometkim
Copy link
Owner

cometkim commented Aug 17, 2019

Ok, I wrote almost all of the code, but I later realized that transformation only happens once and babel plugin cannot be affected during evaluating.

require('@reach/router') is indirectly called by gatsby or gatsby-link, so it's cannot be changed with the custom babel plugin.

Another similar version is:

  1. Replace @reach/router into @reach/router$ (exact match alias) in the webpack config.
  2. Make custom gatsby-link that directly use @reach/router/index.js
  3. Make babel plugin to transform Link from gatsby or gatsby-link to our custom link

probably this version would work...

@cometkim
Copy link
Owner

Or just do forgery the linaria package on postinstall of gatsby-plugin-linaria?

What do you mean by this?

Just like callstack/linaria#392 (comment), we can use plugin's postinstall script to change linaria's behavior.

@silvenon
Copy link
Collaborator

The idea with the custom gatsby-link sounds like a more stable hack. Changing Linaria's behavior would break as soon as that code changes, if I understood correctly.

@sslotsky
Copy link

Running into this issue as well. I see it's been a while since last activity here. Any chance of some progress on this? 🙏

@jazeved0
Copy link

Are there any working fixes/workarounds for this issue?

@silvenon
Copy link
Collaborator

Heyo! I'll check this out tomorrow, thanks for pinging 😉

@silvenon silvenon changed the title Unexpected identifier? "Unexpected identifier" with TypeScript? Jun 27, 2020
@silvenon silvenon changed the title "Unexpected identifier" with TypeScript? Unexpected identifier? Jun 27, 2020
@silvenon
Copy link
Collaborator

silvenon commented Jun 28, 2020

Just letting everyone here know that this plugin is now under new ownership 🎉 @cometkim always had a better grip of the issues than me 😃

@cometkim considering that you have a better insight into what's going on here, could you take over?

@silvenon
Copy link
Collaborator

Until I figure out a fix, a workaround is to simply wrap Link before styling it:

import { Link as GatsbyLink } from 'gatsby'
import { styled } from 'linaria/react'

const WrappedLink = (props) => <GatsbyLink {...props} />

const Link = styled(WrappedLink)`
  /* your styles */
`

I'll add this to the docs.

@silvenon
Copy link
Collaborator

silvenon commented Jun 30, 2020

Ok, workaround documented under "Known issues".

Now the error says SyntaxError: Cannot use import statement outside a module so that's how I wrote it down.

@jazeved0
Copy link

jazeved0 commented Jul 6, 2020

This workaround doesn't seem to work for me; if I have any component inside of styled(...) that includes an import to { Link } from "gatsby" or anything from "@reach/router" at any point in its downstream import graph (regardless of whether the Link is wrapped with a passthrough component or not), the build will fail with the syntax error.

So far, the only working temporary fix I have found is to be cognizant of which paths of my file tree end up referencing Link or some other Router API (such as useLocation) at some point and never use them in a styled(...) clause. Instead, I can use the traditional const c = css... and set the className explicitly.

@cometkim
Copy link
Owner

cometkim commented Jul 6, 2020

This happened because of the linaria's extractor doesn't understand the esmodule syntax.

Removing the forced alias for @reach/router from the Gatsby's Webpack settings will make this work and Webpack still resolves esmodule anyway.

I'm curious why that alias was needed in the first place.

@cometkim
Copy link
Owner

cometkim commented Jul 6, 2020

related with gatsbyjs/gatsby#13197

@cometkim
Copy link
Owner

cometkim commented Jul 6, 2020

@jazevedo620 @deklanw @silvenon @sslotsky

This has been fixed in v2.1.0. Please reopen the If it doesn't work for you

@cometkim cometkim added this to the v3 milestone Jul 6, 2020
@amankkg
Copy link

amankkg commented Jul 7, 2020

Thanks for the fix!

There is yet another error with the latest alpha linaria@2.0.0-alpha.5, but with 2.0.0-alpha.4 everything is OK.

Update: the error is related to styled(Link) usage only

@fshowalter
Copy link

Hey folks, looks like this is breaking Gatsby v3, as they've vendored @reach/router and rely on that alias to resolve exisitng imports (even internal).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants