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

Next.js project fails to build, Unexpected token : at dist/style.css #3854

Closed
imyjimmy opened this issue Aug 15, 2019 · 27 comments · Fixed by #5138
Closed

Next.js project fails to build, Unexpected token : at dist/style.css #3854

imyjimmy opened this issue Aug 15, 2019 · 27 comments · Fixed by #5138
Assignees
Labels
feature-request Request a new feature React React related issues SSR Issues related to Server Side Rendering

Comments

@imyjimmy
Copy link

imyjimmy commented Aug 15, 2019

Description
I have Next.js project and have added aws-amplify. During the build, I get the following error:

> Build error occurred
{ /Users/imyjimmy/_tea/react-frontend/node_modules/@aws-amplify/ui/dist/style.css:13
:root {
^

SyntaxError: Unexpected token :
    at new Script (vm.js:79:7)
    at createScript (vm.js:251:10)
    at Object.runInThisContext (vm.js:303:10)
    at Module._compile (internal/modules/cjs/loader.js:656:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
    at Module.load (internal/modules/cjs/loader.js:598:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
    at Function.Module._load (internal/modules/cjs/loader.js:529:3)
    at Module.require (internal/modules/cjs/loader.js:636:17)
    at require (internal/modules/cjs/helpers.js:20:18) type: 'SyntaxError', '$error': '$error' }
error Command failed with exit code 1.

I have looked at the solution described in #1934 and my next.config.js has been set up accordingly:

if (typeof require !== 'undefined') {
  require.extensions['.less'] = () => {}
  require.extensions['.css'] = file => {}
}

module.exports = {
  webpack: (config, options) => {
    config.module.rules.push({
      test: /\.png$/,
      loader: require.resolve('url-loader'),
    })
    config.module.rules.push({
      test: /\.css$/,
      loader: [
        require.resolve('style-loader'),
        require.resolve('css-loader'),
        require.resolve('postcss-loader'),
      ],
    })
    return config
  },
  distDir: 'build',
}

However, the build still fails.

To Reproduce
I will create a minimum github project that shows this issue. For now, clone my repo:
I've created a minimum repo that shows this issue:

  1. [email protected]:imyjimmy/nextjs-aws-amplify.git
  2. yarn
  3. yarn build

Or, if you prefer to recreate from npx:

  1. npx create-next-app
  2. add the following: url-loader, css-loader, style-loader, postcss-loader, autoprefixer, aws-amplify, aws-amplify-react
  3. next.config.js
if (typeof require !== 'undefined') {
  require.extensions['.less'] = () => {}
  require.extensions['.css'] = file => {}
}

module.exports = {
  webpack: (config, options) => {
    config.module.rules.push({
      test: /\.png$/,
      loader: require.resolve('url-loader'),
    })
    config.module.rules.push({
      test: /\.css$/,
      loader: [
        require.resolve('style-loader'),
        require.resolve('css-loader'),
        require.resolve('postcss-loader'),
      ],
    })
    return config
  },
  distDir: 'build',
}
  1. pages/index.js
import { Authenticator } from 'aws-amplify-react'
...
<Nav />
<Authenticator hideDefault={true}>
  <div className='hero'>
  ...
</Authenticator>
  1. yarn build

Expected behavior
I expect the build to complete.

Desktop (please complete the following information):

  • OS: macOS 10.14.5
  • node v10.12.0
  • aws-amplify ^1.1.36
  • aws-amplify-react ^2.3.12
@jordanranz jordanranz added SSR Issues related to Server Side Rendering React React related issues labels Aug 15, 2019
@vivshaw
Copy link

vivshaw commented Aug 20, 2019

Can confirm I experience this as well. App builds fine with npm run dev, but crashes with the unexpected token error on npm run build. I know that #3279 is planned to fix this problem, but in the interest of finding a temporary workaround in the meanwhile, here's some more info.

Not sure if this is useful info, but: the solution from #1934 is helping, but in npm run dev only. If you remove this fix:

if (typeof require !== 'undefined') {
  require.extensions['.less'] = () => {}
  require.extensions['.css'] = file => {}
}

...you will then find that npm run dev and npm run build now both fail with the same error.

Been surveying related issues, and what's interesting is that it appears this fix used to work in both dev and build, prior to around July 2019! But since July it has failed to work on build. This coincides with some other, similar issues popping up with unexpected token errors in css imports from node_modules with next (see, for example, vercel/next-plugins#266, vercel/next-plugins#498). This coincides with the release of Next 9. and in fact, according to JJ Kasper's reply this is because of a change in build in Next 9!

Now that we know exactly what's causing it, I think all we need for a hacky workaround is to do some Webpack magic to exclude those imports. I expect to have this working within a day or two and will post my fix when I do.

@rakannimer
Copy link

rakannimer commented Aug 20, 2019

Have you tried using @zeit/next-css ?

@vivshaw
Copy link

vivshaw commented Aug 22, 2019

Hmm, 2 days of tweaking the Webpack config, and I'm still stumped. I've tried the following

  1. Tried the approach from the Next with-ant-design example, which is to regex match the specific problem files (in our case, @aws-amplify/ui/dist/style.css), and then both externalize them and add a rule to use null-loader for them. No effect, Same error message as before, on both dev and build.

  2. Tried a scorched-earth approach of excluding every single CSS file with the above method. No effect. Same error message as before, on both dev and build.

  3. Tried approach 1, but removing the isServer check, so that @aws-amplify/ui/dist/style.css gets excluded from both the server it client bundles. No effect. Same error message as before, on both dev and build.

  4. Tried approach 2, but removing the isServer check, so that all CSS gets excluded from both the server and client bundles. No effect. Same error message as before, on both dev and build.

5-8. Tried each of the above, but now with next-css. Identical results in each case.

As best I can tell, regardless of what we do in the Webpack config is next.config.js, something is still pulling in @aws-amplify/ui/dist/style.css. I can't seem to get verbose enough output from next or webpack to figure out why this occurs.

  1. Skipped all this Webpack sorcery, and simply did the old require.extensions hack from above:
if (typeof require !== 'undefined') {
  require.extensions['.less'] = () => {}
  require.extensions['.css'] = file => {}
}

This one is the only one that's made a difference. When I do this, I can at least get dev working. But build fails, same error message as before. Curiously, it fails after it reaches Compiled successfully. I've poked around in the next source, and it looks like the automatic prerendering (that ijjk said causes this issue) occurs after this message prints. This is as far as I've gotten.

Only thing I've found that gets build working is the horrible, horrible hack of going into @aws-amplify/ui/dist/style.css in a text editor and deleting its contents. That makes everything load just fine, as long as you don't actually want that CSS, and also don't care about breaking npm forever!

Have you tried using @zeit/next-css ?

@rakannimer Ah, just saw that @imyjimmy 's example wasn't using next-css. I was using next-css, but have tried it without also.

@ajhool
Copy link

ajhool commented Aug 22, 2019

Have you tried starting from the next.js provided examples?

Go to either with-aws-amplify or with-aws-amplify-typescript
https://github.com/zeit/next.js/tree/canary/examples

Next and amplify can be made to behave with each other but it can be quite painful, mostly from Amplify's end.

@vivshaw
Copy link

vivshaw commented Aug 23, 2019

Have you tried starting from the next.js provided examples?

Go to either with-aws-amplify or with-aws-amplify-typescript
https://github.com/zeit/next.js/tree/canary/examples

Next and amplify can be made to behave with each other but it can be quite painful, mostly from Amplify's end.

Yup, those examples which use only the aws-amplify package work perfectly. It's the React bindings (aws-amplify-react package) that make everything fall apart. Unfortunately this ties into #3365. Due to non-modularized code, it's tough to import anything from aws-amplify-react without pulling every bit of aws-related code into our app along with it. We're not actually using any of the presentational components, but we still get the CSS for them.

Going forward we'll probably go ahead with Next 9, and just remove aws-amplify-react and write our own bindings for aws-amplify. It'll be a bit of a pain, but will neatly solve this CSS issue and probably slim our bundle size too.

@ajhool
Copy link

ajhool commented Aug 23, 2019

Okay, yeah, that's the same experience that I had. Sorry I didn't realize that those examples didn't use the react bindings. I ejected from aws-amplify-react, too, and it has been nice to get away from.

There are still various issues but they can usually be resolved by making sure that everything runs on the client with componentDidMount or useEffect. Sometimes I would use dynamic imports to make sure the package wasn't imported on the server

@dosentmatter
Copy link

dosentmatter commented Aug 26, 2019

I have the same issue.
I have a package that builds react components using rollup. Let's call it components package. Components depends on another package called assets that has a bunch of svgs.

In my components rollup config, I marked assets as external so that the require/import are left in the bundle. This allows nextjs webpack to bundle the svg and choose the static path, instead of using data urls or embedding the path in the rollup bundle.

Components outputs two bundles, main (using require) and module (using es6 modules) in package.json.

So if I inspect the components bundle, I see require('assets/image.svg') in index.js and import ... from 'assets/image.svg' in index.es.js.

Similar to above, I only get the error for next build and not dev mode. It seems to be breaking on the require() in index.js and not the import in index.es.js. Deleting the require() allows it to build. I think this is because it is breaking on the server build but now the browser build. I tried adding require.extensions['.svg'] = () => {} in next.config.js but it doesn't help.

@imyjimmy
Copy link
Author

imyjimmy commented Sep 9, 2019

Going forward we'll probably go ahead with Next 9, and just remove aws-amplify-react and write our own bindings for aws-amplify

@vivshaw will this effort be open sourced anywhere?

@jskrt
Copy link

jskrt commented Oct 1, 2019

Any updates on this?

@jukkamarttinen
Copy link

I'm curious about this too. Anyone got this working?

@imyjimmy
Copy link
Author

imyjimmy commented Oct 1, 2019

As a temporary stopgap I published my own package, https://www.npmjs.com/package/aws-amplify-react-jz, which is a fork of aws-amplify-react minus the offending line, and it seems to work. It reflects their version 2.3.12

@jskrt
Copy link

jskrt commented Oct 9, 2019

@imyjimmy thanks for that. Using it as - hopefully - a temporary solution.

@sachinrajgire
Copy link

Any update on this , Already spend couple of hours on this ,
I wondering why
:root <---- is not picked up ..its just normal css file . I looked at all the css selectors here ,
According to Mozilla https://developer.mozilla.org/en-US/docs/Web/CSS/:root

The :root CSS pseudo-class matches the root element of a tree representing the document. In HTML, :root represents the element and is identical to the selector html, except that its specificity is higher.

@imyjimmy
Copy link
Author

imyjimmy commented Oct 16, 2019

@sachinrajgire you have a couple options:

either delete everything in @aws-amplify/ui/dist/style.css or delete the import statement in the corresponding file (can't remember which file off the top of my head but you can search for it in your favorite code editor) or use my own custom package: https://www.npmjs.com/package/aws-amplify-react-jz

edit: get rid of the line import "@aws-amplify/ui/dist/style.css"; at packages/aws-amplify-react/src/Amplify-UI/Amplify-UI-Components-React.jsx

@sachinrajgire
Copy link

Thanks @imyjimmy

@mlabieniec
Copy link
Contributor

mlabieniec commented Nov 15, 2019

To get past the > :root { issue and render the Authenticator in Next.js you need to include @zeit/next-css package npm i --save @zeit/next-css. So your root ./next.config.js file should look like this:

const withCSS = require('@zeit/next-css')
global.navigator = () => null
if (typeof require !== 'undefined') {
    require.extensions['.less'] = () => {}
    require.extensions['.css'] = file => {}
}
module.exports = withCSS({
});

This will render the full withAuthenticator with styles and also polyfill the navigator for analytics so everything works for dev. Seems like some of this can be solved with a postcss config file as outlined in the next docs, example here: https://stackoverflow.com/questions/46592310/postcss-modules-and-next-js

Seems like in general there is an issue loading css from node_modules discussed here (this still fails on production build):
vercel/next-plugins#266

And RFC for css support in next.js here:
vercel/next.js#8626

@mlabieniec
Copy link
Contributor

mlabieniec commented Nov 17, 2019

Updated next.config.js that works for both dev and build (be sure to install amplify with npm i --save aws-amplify@next)

const withCSS = require('@zeit/next-css')
const resolve = require('resolve')
global.navigator = () => null
module.exports = withCSS({
    webpack (config, options) {
        const { dir, isServer } = options
        config.externals = []
        if (isServer) {
          config.externals.push((context, request, callback) => {
            resolve(request, { basedir: dir, preserveSymlinks: true }, (err, res) => {
              if (err) {
                return callback()
              }
              if (
                res.match(/node_modules[/\\].*\.css/)
                && !res.match(/node_modules[/\\]webpack/)
                && !res.match(/node_modules[/\\]@aws-amplify/)
              ) {
                return callback(null, `commonjs ${request}`)
              }
              callback()
            })
          })
        }
        return config
      }
});

@gtinkham
Copy link

@mlabieniec This works super well allowing me to remove all of the resolutions from my previous comment. Thanks a ton!!!! I am still experiencing build errors. However it is not related to navigator now.
This is the error
Error occurred prerendering page "/shop/[slugId]": Error: Minified React error #321;

I don't believe this pertains to this issue though, I think this is a separate config issue that I am having with my project.

@axeen
Copy link

axeen commented Nov 21, 2019

I had the same issue using react-flexbox-grid. Managed to solve it using the module next-transpile-modules, like so:

const withSass = require('@zeit/next-sass');
const withCSS = require('@zeit/next-css');
const withTM = require('next-transpile-modules');

module.exports = withCSS(withSass(withTM({
  transpileModules: ['react-flexbox-grid']
})));

@eastuto
Copy link

eastuto commented Nov 23, 2019

OK here is my current next.config.js and everything is working ok


if (typeof require !== 'undefined') {
  require.extensions['.less'] = () => {}
  require.extensions['.css'] = file => {}
}

module.exports = withPlugins([withCSS, withSass, withTM], {
  transpileModules: ['bs-platform', 'bs-css', 'reason-apollo-hooks', 're-formality'],
  pageExtensions: ['jsx', 'js', 'bs.js'],
  resolve: {
    modules: ['sass_loader'],
    cssModules: true,
  },
  webpack (config, options) {
    config.module.rules.push({
      test: /\.css$/,
      loader: [
        require.resolve('postcss-loader'),
      ],
    });

    // Fixes npm packages that depend on `fs` module
    config.node = {
      fs: 'empty'
    };
    return config
  },
})

@daniel-trevino
Copy link

@mlabieniec Thanks for your solution. Unfortunately it doesn't work when using React hooks due to config.externals = []

@stale
Copy link

stale bot commented Dec 29, 2019

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

@mlabieniec mlabieniec added the feature-request Request a new feature label Dec 29, 2019
@jskrt
Copy link

jskrt commented Dec 29, 2019

Bump

@imyjimmy
Copy link
Author

@jskrt can you describe what's still broken for you? I've transitioned away from using AWS Amplify and haven't had time to look at this thread, but I think it's still relevant to lots of people.

@sushi30
Copy link

sushi30 commented Feb 4, 2020

@mlabieniec Thanks for your solution. Unfortunately it doesn't work when using React hooks due to config.externals = []

As quoted, hooks don't work with this solution. Has anybody found a solution that doesn't break hooks?

Edit: the solution by @eastuto appears to be working.

Edit2: wrote a gist that implements this solution more granularly and without using deprecated features of node.js.

@ericclemmons
Copy link
Contributor

With the latest release of aws-amplify-react, #5138 resolves this by moving the CSS to a separate import:

import '@aws-amplify/ui/dist/style.css';

https://aws-amplify.github.io/docs/js/react

Please open a new issue if your experience differs!

@github-actions
Copy link

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels or Discussions for those types of questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature-request Request a new feature React React related issues SSR Issues related to Server Side Rendering
Projects
None yet