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 https://github.com/aws-amplify/amplify-js/issues/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:
[email protected]:imyjimmy/nextjs-aws-amplify.git
Or, if you prefer to recreate from npx
:
npx create-next-app
url-loader
, css-loader
, style-loader
, postcss-loader
, autoprefixer
, aws-amplify
, aws-amplify-react
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',
}
pages/index.js
import { Authenticator } from 'aws-amplify-react'
...
<Nav />
<Authenticator hideDefault={true}>
<div className='hero'>
...
</Authenticator>
yarn build
Expected behavior
I expect the build to complete.
Desktop (please complete the following information):
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, zeit/next-plugins#266, zeit/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.
Have you tried using @zeit/next-css ?
Hmm, 2 days of tweaking the Webpack config, and I'm still stumped. I've tried the following
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
.
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
.
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
.
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.
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.
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.
Have you tried starting from the next.js provided examples?
Go to either
with-aws-amplify
orwith-aws-amplify-typescript
https://github.com/zeit/next.js/tree/canary/examplesNext 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.
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
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.
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?
Any updates on this?
I'm curious about this too. Anyone got this working?
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
@imyjimmy thanks for that. Using it as - hopefully - a temporary solution.
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.
@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
Thanks @imyjimmy
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):
https://github.com/zeit/next-plugins/issues/266
And RFC for css support in next.js here:
https://github.com/zeit/next.js/issues/8626
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
}
});
@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.
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']
})));
OK here is my current next.config.js and everything is working ok
```global.navigator = () => null;
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
},
})
@mlabieniec Thanks for your solution. Unfortunately it doesn't work when using React hooks due to config.externals = []
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.
Bump
@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.
@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.
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';
Please open a new issue if your experience differs!
Most helpful comment
Bump