aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.44k stars 2.13k forks source link

Adding Amplify Auth to a Next.js project has a huge impact of the chunk size #7570

Closed Riley0111 closed 12 months ago

Riley0111 commented 3 years ago

Describe the bug I want to use Amplify Auth with my Next.js project. After I added aws-amplify to my project and imported 'Auth' to my index page the First load size increased from 64.1 kB to 308 kB without adding anything else. I also tried to analyze the problem with the webpack-bundle-analyzer and noticed that a lot of crypto libraries got loaded and some of them like bn.js multiple times (see screenshot below).

To Reproduce

  1. Create a new Next.js project
  2. Add aws-amplify to your package.json
  3. import {Auth} from 'aws-amplify'; in your index.js page

Expected behavior That the use of the aws-amplify Auth module will add way less than 240 kB to the first load size. Or is this an expected increase of size?

Code Snippet

package.json:

"dependencies": {
    "next": "^10.0.5",
    "react": "16.14.0",
    "react-dom": "16.14.0",
    "aws-amplify": "3.3.14"
  },

index.js

import Head from 'next/head'
import {Auth} from 'aws-amplify';

export default function Home() {
    Auth.currentAuthenticatedUser()

    return (
        <div className="container">
            <Head>
                <title>Create Next App</title>
                <link rel="icon" href="/favicon.ico"/>
            </Head>

            <main>
                <h1 className="title">
                    Welcome to <a href="https://nextjs.org">Next.js!</a>
                </h1>
            </main>
        </div>
    )
}

Screenshots Screenshot from the webpack bundle analyzer:

Bildschirmfoto 2021-01-18 um 10 33 16

Page size without amplify:

Bildschirmfoto 2021-01-18 um 10 44 11

Page size with amplify:

Bildschirmfoto 2021-01-18 um 10 43 57

What is Configured? Amplify version: 3.3.14 Next.js version: 10.0.5

jamessouth commented 3 years ago

Dumping the amplify package might help, see https://github.com/aws-amplify/amplify-js/issues/7313#issuecomment-757424281

amhinson commented 3 years ago

This looks to be related to https://github.com/aws-amplify/amplify-js/pull/7521, which has been merged but not released yet. We will likely be doing a release this week. However, you can test out the changes currently in main by using aws-amplify@unstable.

Riley0111 commented 3 years ago

I just tested using @aws-amplify/auth instead of importing from aws-amplify but it only reduced the first load size from 308kB to 306 kB.

I also tried with "aws-amplify": "3.3.15-unstable.3" but it doesn't have any effect at the first load size or the webpack bundle analyzer.

amhinson commented 3 years ago

Ah yes, sorry, I forgot that the PR only addressed a usage with Create React App. I'll do a bit more digging and testing and get back to you πŸ‘

ericclemmons commented 3 years ago

We definitely need to investigate this more, particularly for Next.js.

Next.js is moving to support Webpack 5, but explicitly adds a polyfill for crypto (that webpack4 does automatically):

https://github.com/vercel/next.js/blob/0d0db45c7201acf850b01343a846e0a74db86d77/packages/next/build/webpack-config.ts#L377

Next.js' "base bundle" size is around 65kB, and using import { Amplify, Auth } from "aws-amplify" brought it up to ~205kB.

We'd like to get this lower, of course, knowing that we don't want crypto polyfilled on the client, but this needs work on top of #7521 to accomplish.

ianpogi5 commented 3 years ago

This looks to be related to #7521, which has been merged but not released yet. We will likely be doing a release this week. However, you can test out the changes currently in main by using aws-amplify@unstable.

I just tried "aws-amplify": "^3.3.15-unstable.3" on my react app and can confirm that the size has been drastically reduced.

ericclemmons commented 3 years ago

@ianpogi5 That's great news! I'll share it with @amhinson πŸ’ͺ

Is it a Next.js app or Create React App?

ianpogi5 commented 3 years ago

@ianpogi5 That's great news! I'll share it with @amhinson πŸ’ͺ

Is it a Next.js app or Create React App?

It's CRA

bezreyhan commented 3 years ago

This is also a big issue for us as our bundle size has increased dramatically.

hwangar commented 3 years ago

Same issue here, even with 3.3.15-unstable.8: image

Multiple duplications in the bundle (7x bn.js 85Kb... unnecessary ~510Kb for a "hello world app")

In case it helps, not my first time with this issue: in another project I decided to downgrade "crypto-js@4"... for me the root of all evil, to "^3.1.9-1" and all bundle issues vanished

VicFrolov commented 3 years ago

Confirming this is also an issue with latest "@aws-amplify/auth": "3.4.17" for us

bezreyhan commented 3 years ago

Has there been any progress or update on this issue? This issue is really slowing down our site.

Alternatively, is there documentation on how to use Cognito without Amplify?

VicFrolov commented 3 years ago

Any updates?

fomalhaut79 commented 3 years ago

Same issue here with the new Vue project after import Auth from "@aws-amplify/auth"

Screen Shot 2021-02-24 at 9 01 49 AM
bobbyhadz commented 3 years ago

Same issue, amplify is absolutely unusable with next.js with first load of 300 kB for just including an @aws-amplify/auth import.

The same module gets loaded like 8 times.

Can we get an update from the amplify team, I mean this is not really a corner case issue, Next.js is one of the most popular react frameworks. Is this being worked on?

The amplify team say they're working on deploying next.js applications using amplify, I mean that's great and very exciting, but maybe a priority should be to not load over 300kb of gzipped code for the auth module.

Also didn't realize about this until I finished building the site, that's not very fun.

o-gi commented 3 years ago

I'm curious if there are any updates to this.I think it's safe to say that using Nextjs to create Jamstack is now the standard.This is a pretty important issue.

VicFrolov commented 3 years ago

Words cannot explain how continuously disappointed I am with the Amplify team's lack of responses on a wide net of outstanding issues such as this one.

ericclemmons commented 3 years ago

Hey everyone, I'm personally sorry for the late resolution here.

With bundle sizes improved via https://github.com/aws-amplify/amplify-js/pull/7521, I missed that Next.js doesn't resolve .web.js files (https://github.com/vercel/next.js/issues/1854).

I opened a PR with my research, tests to alert us on bundle-size increases (so bloat doesn't happen accidentally), and possible solutions. I'd really appreciate your input here:

https://github.com/aws-amplify/amplify-js/pull/7842

For an immediate workaround, you can opt-in to the .web.js files from #7521, which will prevent crypto polyfills from being included in your browser bundle:

--- a/samples/next/auth/ssr-auth/next.config.js
+++ b/samples/next/auth/ssr-auth/next.config.js
@@ -1,3 +1,8 @@
 module.exports = {
   target: 'serverless',
+  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
+    config.resolve.extensions = ['.web.js', ...config.resolve.extensions]
+
+    return config
+  },
 }

The results are:

Page                                                           Size     First Load JS
β”Œ β—‹ /                                                          3.47 kB        66.2 kB
β”œ   /_app                                                      0 B            62.7 kB
β”œ β—‹ /404                                                       3.46 kB        66.2 kB
β”œ β—‹ /Amplify                                                   875 B          67.4 kB
β”œ β—‹ /Amplify+Auth                                              37.9 kB         142 kB
β”œ β—‹ /Amplify+Storage                                           42.6 kB         146 kB
β”” Ξ» /api/hello                                                 0 B            62.7 kB
+ First Load JS shared by all                                  62.7 kB
  β”œ chunks/f6078781a05fe1bcb0902d23dbbb2662c8d200b3.015d8f.js  13.1 kB
  β”œ chunks/framework.e2fe4a.js                                 41.8 kB
  β”œ chunks/main.a1fab4.js                                      6.62 kB
  β”œ chunks/pages/_app.3da7c8.js                                530 B
  β”œ chunks/webpack.50bee0.js                                   751 B
  β”” css/2f26bb9842d84a608fa3.css                               202 B

Down to 142kB from 281kB (-138kB). For comparison, Next.js has a ~65kB "tax" just to run "Hello World". This puts the Amplify+Auth.js page at ~77kB additional, which is comparable to Create React App's ~75kB. (See https://github.com/aws-amplify/amplify-js/pull/7842 for more numbers)

I also created a Bundle Size Optimizations milestone to track these issues & get them released once we validate Next.js + Amplify continues working as intended πŸ™

o-gi commented 3 years ago

@ericclemmons I’m grateful for all your help

izzy-h commented 3 years ago

Hi @ericclemmons, thanks for sharing this. Do you have any ideas as to why this solution wouldn’t work with other react frameworks? I created a brand new Gatsby project and added Auth as a dependency, and also configured webpack to resolveΒ .web.jsΒ files, but am still seeing the crypto polyfills included in the bundle.

Dependency in package.json:

"@aws-amplify/auth": "^3.4.24"

Importing Auth in gatsby-browser.js:

import { Auth } from "@aws-amplify/auth";

Configuring webpack in gatsby-node.js:

exports.onCreateWebpackConfig = ({ actions }) => {
    actions.setWebpackConfig({
        resolve: {
            extensions: ['.web.js']
        },
    })
}

However, as you can see from the bundle analyser output, all those crypto modules are still being included:

image

Any ideas as to how to exclude them? Thanks

ericclemmons commented 3 years ago

@izzy-h I'm looking into "browser": { "crypto": false } behavior for Gatsby right now in #7842.

By default, I get:

warn Module not found: Error: Can't resolve 'crypto' in '/Users/ecclemm/Projects/ericclemmons/amplify-js/.github/actions/bundle-size-action/gatsby/node_modules/amazon-cognito-identity-js/es/utils'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
    - install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "crypto": false }

If you could provide a working Gatsby repo with Amplify & Auth to model after, I'd appreciate it! We may have to solve that separately if #7842 doesn't fix Gatsby as well...

izzy-h commented 3 years ago

@ericclemmons I just created a skeleton project with Gatsby's default starter and added the Auth module to it. Here's the repo. It doesn't do anything other than call Auth.configure() in gatsby-browser.js, but it builds with no issues.

ericclemmons commented 3 years ago

@izzy-h Perfect! I'll give this a shot. πŸ™

ericclemmons commented 3 years ago

@izzy-h Ok, so Gatsby doesn't make it easy to track my bundle sizes, but I have a before/after comparison against #7842 with gatsby build:

npx init gatsby


      96 Mar  3 14:21 404
    2271 Mar  3 14:21 404.html
   56017 Mar  3 14:21 app-b8b4f55540b4d703a0da.js
      94 Mar  3 14:21 app-b8b4f55540b4d703a0da.js.LICENSE.txt
  236040 Mar  3 14:21 app-b8b4f55540b4d703a0da.js.map

     271 Mar  3 14:21 chunk-map.json
     794 Mar  3 14:21 component---src-pages-404-js-dd32d1c6f01bb8326b7f.js
    1878 Mar  3 14:21 component---src-pages-404-js-dd32d1c6f01bb8326b7f.js.map
    3951 Mar  3 14:21 component---src-pages-index-js-4588164e2ba842d0bbac.js
    7608 Mar  3 14:21 component---src-pages-index-js-4588164e2ba842d0bbac.js.map
  128864 Mar  3 14:21 framework-fade9fdc1e19a4019429.js
     736 Mar  3 14:21 framework-fade9fdc1e19a4019429.js.LICENSE.txt
  318929 Mar  3 14:21 framework-fade9fdc1e19a4019429.js.map
    6901 Mar  3 14:21 index.html
     192 Mar  3 14:21 page-data
   82572 Mar  3 14:21 polyfill-825bfe67c5a0b4fd2ef8.js
  198893 Mar  3 14:21 polyfill-825bfe67c5a0b4fd2ef8.js.map
      64 Mar  3 14:16 static
    3032 Mar  3 14:21 webpack-runtime-c5b81771f0a86fdc8e8e.js
   15697 Mar  3 14:21 webpack-runtime-c5b81771f0a86fdc8e8e.js.map
    1521 Mar  3 14:21 webpack.stats.json

Adding Amplify and Auth to gatsby-browser.js

import { Amplify, Auth } from 'aws-amplify';

export const onClientEntry = () => {
    Amplify.configure();

    Auth.currentAuthenticatedUser()
        .then(console.info)
        .catch(console.warn);
};
    11906 Mar  3 14:49 0eceb729-cc1669f4895a20592e47.js
   222357 Mar  3 14:49 0eceb729-cc1669f4895a20592e47.js.map
       96 Mar  3 14:21 404
     2411 Mar  3 14:49 404.html
    56017 Mar  3 14:21 app-b8b4f55540b4d703a0da.js
       94 Mar  3 14:21 app-b8b4f55540b4d703a0da.js.LICENSE.txt
   236040 Mar  3 14:21 app-b8b4f55540b4d703a0da.js.map
   323721 Mar  3 14:49 app-edfc7688ed2478a2b001.js
     2046 Mar  3 14:49 app-edfc7688ed2478a2b001.js.LICENSE.txt
  1332807 Mar  3 14:49 app-edfc7688ed2478a2b001.js.map
      271 Mar  3 14:49 chunk-map.json
      794 Mar  3 14:21 component---src-pages-404-js-dd32d1c6f01bb8326b7f.js
     1878 Mar  3 14:21 component---src-pages-404-js-dd32d1c6f01bb8326b7f.js.map
     3951 Mar  3 14:21 component---src-pages-index-js-4588164e2ba842d0bbac.js
     7608 Mar  3 14:21 component---src-pages-index-js-4588164e2ba842d0bbac.js.map
   128864 Mar  3 14:21 framework-fade9fdc1e19a4019429.js
      736 Mar  3 14:21 framework-fade9fdc1e19a4019429.js.LICENSE.txt
   318929 Mar  3 14:21 framework-fade9fdc1e19a4019429.js.map
     7041 Mar  3 14:49 index.html
      192 Mar  3 14:49 page-data
    82572 Mar  3 14:21 polyfill-825bfe67c5a0b4fd2ef8.js
   198893 Mar  3 14:21 polyfill-825bfe67c5a0b4fd2ef8.js.map
       64 Mar  3 14:16 static
     3141 Mar  3 14:49 webpack-runtime-42b9d014f495f84d30fc.js
    16154 Mar  3 14:49 webpack-runtime-42b9d014f495f84d30fc.js.map
     3032 Mar  3 14:21 webpack-runtime-c5b81771f0a86fdc8e8e.js
    15697 Mar  3 14:21 webpack-runtime-c5b81771f0a86fdc8e8e.js.map
     1615 Mar  3 14:49 webpack.stats.json

This adds a couple extra files that should gzip pretty well. The network tab looks pretty good IMO:

Screen Shot 2021-03-03 at 2 57 37 PM
izzy-h commented 3 years ago

@ericclemmons Oh great, thank you! Hoping your PR gets merged soon πŸ™Œ

bobbyhadz commented 3 years ago

@ericclemmons this bug persists even when using @aws-amplify/auth version ^4.0.0. Here's my bundle for a next.js application: amplify-auth-bundle

The only amplify package I'm using is @aws-amplify/auth at version ^4.0.0.

ericclemmons commented 3 years ago

Hmmm, I went to check out https://github.com/aws-amplify/amplify-js/tree/main/.github/actions/bundle-size-action/next and I'm seeing a regression in bundle-size:

❯ yarn build
yarn run v1.22.10
$ rimraf .next
$ next build
Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
info  - Creating an optimized production build
info  - Compiled successfully
info  - Collecting page data
info  - Generating static pages (5/5)
info  - Finalizing page optimization

Page                                                           Size     First Load JS
β”Œ β—‹ /                                                          3.47 kB        66.2 kB
β”œ   /_app                                                      0 B            62.7 kB
β”œ β—‹ /404                                                       3.46 kB        66.2 kB
β”œ β—‹ /Amplify                                                   875 B          67.4 kB
β”œ β—‹ /Amplify+Auth                                              176 kB          281 kB
β”œ β—‹ /Amplify+Storage                                           41.1 kB         147 kB
β”” Ξ» /api/hello                                                 0 B            62.7 kB
+ First Load JS shared by all                                  62.7 kB
  β”œ chunks/f6078781a05fe1bcb0902d23dbbb2662c8d200b3.015d8f.js  13.1 kB
  β”œ chunks/framework.d886aa.js                                 41.8 kB
  β”œ chunks/main.a1fab4.js                                      6.62 kB
  β”œ chunks/pages/_app.c36bd6.js                                531 B
  β”œ chunks/webpack.50bee0.js                                   751 B
  β”” css/d7103672eb18c283a687.css                               209 B

Ξ»  (Server)  server-side renders at runtime (uses getInitialProps or getServerSideProps)
β—‹  (Static)  automatically rendered as static HTML (uses no initial props)
●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)
   (ISR)     incremental static regeneration (uses revalidate in getStaticProps)

✨  Done in 18.81s.

actions/bundle-size-action/next on ξ‚  main [$?] via β¬’ v14.16.1 on ☁️  us-east-1 took 19s
❯ yarn calculate
yarn run v1.22.10
$ $_ run build
$ rimraf .next
$ next build
Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
info  - Creating an optimized production build
info  - Compiled successfully
info  - Collecting page data
info  - Generating static pages (5/5)
info  - Finalizing page optimization

Page                                                           Size     First Load JS
β”Œ β—‹ /                                                          3.47 kB        66.2 kB
β”œ   /_app                                                      0 B            62.7 kB
β”œ β—‹ /404                                                       3.46 kB        66.2 kB
β”œ β—‹ /Amplify                                                   875 B          67.4 kB
β”œ β—‹ /Amplify+Auth                                              176 kB          281 kB
β”œ β—‹ /Amplify+Storage                                           41.1 kB         147 kB
β”” Ξ» /api/hello                                                 0 B            62.7 kB
+ First Load JS shared by all                                  62.7 kB
  β”œ chunks/f6078781a05fe1bcb0902d23dbbb2662c8d200b3.015d8f.js  13.1 kB
  β”œ chunks/framework.d886aa.js                                 41.8 kB
  β”œ chunks/main.a1fab4.js                                      6.62 kB
  β”œ chunks/pages/_app.c36bd6.js                                531 B
  β”œ chunks/webpack.50bee0.js                                   751 B
  β”” css/d7103672eb18c283a687.css                               209 B

Ξ»  (Server)  server-side renders at runtime (uses getInitialProps or getServerSideProps)
β—‹  (Static)  automatically rendered as static HTML (uses no initial props)
●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)
   (ISR)     incremental static regeneration (uses revalidate in getStaticProps)

$ bundlewatch
[WARNING] Some CI configuration options were not found (githubAccessToken, repoOwner, repoName, commitSha):
    bundlewatch will be unable to report build status, or save comparison data
    Learn more at: https://bundlewatch.io/

Result breakdown at: https://ja2r7.app.goo.gl/DZPfzHNtiSvnmJKG8

PASS .next/static/chunks/pages/Amplify-1e0c44f6ee988d6e1533.js: 875B < 1KB (gzip)
FAIL .next/static/chunks/pages/Amplify+Auth-00c89a7c73f20200248d.js: 171.55KB > 40KB (gzip)
PASS .next/static/chunks/pages/Amplify+Storage-ba35e8048a87a04008a4.js: 35.09KB < 40KB (gzip)
PASS .next/static/chunks/pages/index-ddf337df94f27dbf037f.js: 3.39KB < 5KB (gzip)

bundlewatch FAIL
maxSize check failed

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Last passing check

https://github.com/aws-amplify/amplify-js/actions/runs/838805594

First failing check since then

https://github.com/aws-amplify/amplify-js/actions/runs/840277847

Pinpointing the regression

Re-running the following command:

yarn add aws-amplify@3.3.x && yarn build && yarn calculate

Based on the differences:

https://github.com/aws-amplify/amplify-js/compare/aws-amplify@3.4.0...aws-amplify@3.4.3#diff-79fbe1d958aec3ec2b3d46cdc5b9b34cd834f48550895ce9484f10c0f77a4a8fR47

It looks like the main suspect is crypto-js moving to 4.0.0:

❯ yarn why bn.js
yarn why v1.22.10
[1/4] πŸ€”  Why do we have the module "bn.js"...?
[2/4] 🚚  Initialising dependency graph...
[3/4] πŸ”  Finding dependency...
[4/4] 🚑  Calculating file sizes...
=> Found "bn.js@4.12.0"
info Has been hoisted to "bn.js"
info Reasons this module exists
   - Hoisted from "next#crypto-browserify#create-ecdh#bn.js"
   - Hoisted from "next#crypto-browserify#diffie-hellman#bn.js"
   - Hoisted from "next#crypto-browserify#public-encrypt#bn.js"
   - Hoisted from "next#crypto-browserify#diffie-hellman#miller-rabin#bn.js"
   - Hoisted from "next#crypto-browserify#browserify-sign#elliptic#bn.js"
   - Hoisted from "next#crypto-browserify#public-encrypt#parse-asn1#asn1.js#bn.js"
info Disk size without dependencies: "108KB"
info Disk size with unique dependencies: "108KB"
info Disk size with transitive dependencies: "108KB"
info Number of shared dependencies: 0
=> Found "browserify-sign#bn.js@5.2.0"
info This module exists because "next#crypto-browserify#browserify-sign" depends on it.
info Disk size without dependencies: "116KB"
info Disk size with unique dependencies: "116KB"
info Disk size with transitive dependencies: "116KB"
info Number of shared dependencies: 0
=> Found "browserify-rsa#bn.js@5.2.0"
info This module exists because "next#crypto-browserify#public-encrypt#browserify-rsa" depends on it.
info Disk size without dependencies: "116KB"
info Disk size with unique dependencies: "116KB"
info Disk size with transitive dependencies: "116KB"
info Number of shared dependencies: 0
✨  Done in 0.41s.

Going to investigate with the team on how to best resolve this.

ericclemmons commented 3 years ago

I'm also having the same issue with https://github.com/aws-amplify/amplify-js/tree/main/.github/actions/bundle-size-action/cra:

❯ yarn calculate
yarn run v1.22.10
$ $_ run build
$ SKIP_PREFLIGHT_CHECK=true react-scripts build
Creating an optimized production build...
Compiled successfully.

File sizes after gzip:

  242.81 KB (+157.84 KB)  build/static/js/2.681ffe20.chunk.js
  1.62 KB (+2 B)          build/static/js/3.76b29e96.chunk.js
  1.16 KB                 build/static/js/runtime-main.0b008cca.js
  704 B (-30.45 KB)       build/static/js/main.cce0dad8.chunk.js
  574 B                   build/static/css/main.9d5b29c0.chunk.css

The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.

The build folder is ready to be deployed.
You may serve it with a static server:

  yarn global add serve
  serve -s build

Find out more about deployment here:

  https://cra.link/deployment

$ bundlewatch
[WARNING] Some CI configuration options were not found (githubAccessToken, repoOwner, repoName, commitSha):
    bundlewatch will be unable to report build status, or save comparison data
    Learn more at: https://bundlewatch.io/

Result breakdown at: https://ja2r7.app.goo.gl/taA5mr2uY4j4L37V6

PASS build/static/js/main.cce0dad8.chunk.js: 704B < 35KB (gzip)
FAIL build/static/js/2.681ffe20.chunk.js: 242.81KB > 90KB (gzip)

bundlewatch FAIL
maxSize check failed

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Screen Shot 2021-05-18 at 12 26 34 PM
iartemiev commented 3 years ago

@bobbyhadz this change in bundle size is due to our upgrading Amplify’s CryptoJS dependency from ^3.3.0 to 4.0.0 in order to remediate a security vulnerability. Please see https://github.com/aws-amplify/amplify-js/issues/8256 for additional context.

hziburski commented 3 years ago

Is there any progress with this issue or maybe a workaround? This issue makes amplify basically unusable again.

I tried the workaround from @ericclemmons https://github.com/aws-amplify/amplify-js/issues/7570#issuecomment-788405226 to add config.resolve.extensions = ['.web.js', ...config.resolve.extensions] to my next.config.js but it seems to not work anymore with version "aws-amplify": "^3.4.3".

ChrisSargent commented 3 years ago

Also seeing this issue in a CRA app right now with "@aws-amplify/auth": "^4.0.1"

ackl commented 3 years ago

A workaround I've found is to tell webpack not to polyfill the crypto module for the browser.

e.g. for webpack4 nextjs setup currently running npm run calculate gives me:

Page                                                           Size     First Load JS
β”Œ β—‹ /                                                          3.47 kB        66.2 kB
β”œ   /_app                                                      0 B            62.7 kB
β”œ β—‹ /404                                                       3.46 kB        66.2 kB
β”œ β—‹ /Amplify                                                   875 B          67.4 kB
β”œ β—‹ /Amplify+Auth                                              211 kB          317 kB
β”œ β—‹ /Amplify+Storage                                           41.2 kB         147 kB
β”” Ξ» /api/hello                                                 0 B            62.7 kB
+ First Load JS shared by all                                  62.7 kB
  β”œ chunks/f6078781a05fe1bcb0902d23dbbb2662c8d200b3.015d8f.js  13.1 kB
  β”œ chunks/framework.d886aa.js                                 41.8 kB
  β”œ chunks/main.a1fab4.js                                      6.62 kB
  β”œ chunks/pages/_app.8bf8d7.js                                533 B
  β”œ chunks/webpack.50bee0.js                                   751 B
  β”” css/d7103672eb18c283a687.css                               209 B

updating next.config.js with

module.exports = withBundleAnalyzer({
    webpack: (config, options) => {
        if (!options.isServer) {
            config.node = {
                crypto: 'empty',
            };
        }

        return config;
    },
});

gives me:

Page                                                           Size     First Load JS
β”Œ β—‹ /                                                          3.47 kB        66.2 kB
β”œ   /_app                                                      0 B            62.7 kB
β”œ β—‹ /404                                                       3.46 kB        66.2 kB
β”œ β—‹ /Amplify                                                   875 B          67.4 kB
β”œ β—‹ /Amplify+Auth                                              38.9 kB         143 kB
β”œ β—‹ /Amplify+Storage                                           42.9 kB         147 kB
β”” Ξ» /api/hello                                                 0 B            62.7 kB
+ First Load JS shared by all                                  62.7 kB
  β”œ chunks/f6078781a05fe1bcb0902d23dbbb2662c8d200b3.015d8f.js  13.1 kB
  β”œ chunks/framework.d886aa.js                                 41.8 kB
  β”œ chunks/main.a1fab4.js                                      6.62 kB
  β”œ chunks/pages/_app.865f03.js                                530 B
  β”œ chunks/webpack.50bee0.js                                   751 B
  β”” css/d7103672eb18c283a687.css                               209 B

I haven't tested it thoroughly but basic sign in and signout functionality works fine.

ChrisSargent commented 3 years ago

Also seeing this issue in a CRA app right now with "@aws-amplify/auth": "^4.0.1"

Ahhh sorry. I meant to already write a reply here that my issue was being caused by different package. When I stopped importing the offending package my bundle size was normal and crypto was no longer being poly filled. i.e. Amplify Auth was not causing my problem (and I got a new console warning about it too)

ericclemmons commented 3 years ago

@ackl Nice workaround! We're having to do the same thing for webpack (5) since it doesn't polyfill by default:

https://github.com/aws-amplify/amplify-js/blob/eb3b707722084f07d025344bf6bbc34927b79bf5/.github/actions/bundle-size-action/webpack/webpack.config.js#L13-L27

What stinks is that CRA is closed to extension (unless you eject or use 3rd party libs like craco), so we'd like to continue working towards an out-of-the-box solution...

hkjpotato commented 3 years ago

I have the same issue for CRA bundle size due to the require keyword for 'crypto', adding it to the externals of webpack config help reduce the bundle size quite a bit.

    externals: { crypto: "var {}" },
DavidWells commented 3 years ago

We are having bundle size issues with amplify as well using next.js with webpack 5.

Has anyone figured out how to configure webpack5 to work around these issues?

I tried https://github.com/aws-amplify/amplify-js/issues/7570#issuecomment-860801238 but it did not work

image

ericclemmons commented 3 years ago

@DavidWells What are you seeing for yarn why bn.js? I'm wondering if yarn resolutions helps in this situation. Also, do you have a single aws-amplify dependency or multiple @aws-amplify/* deps? I'm seeing more bn.js than I expect under Amplify, which is strange πŸ€”

DavidWells commented 3 years ago

Using only import Auth from '@aws-amplify/auth' and import Amplify from 'aws-amplify' Amplify.configure(amplifyConfig) in the app.

Not using yarn as package manager, just NPM.

I've tried this setup with "aws-amplify": "^3.3.26" and "aws-amplify": "^4.1.1", both contain all the extra deps.

It would be cool to see an example next.js project with an optimized setup. Battling webpack & not getting any changes is rough πŸ˜…

aside: there is an interesting super lightweight cognito client https://github.com/ravenscar/franken-srp/

afenton90 commented 3 years ago

For anyone coming here looking for a solution to this issue when using next@10.2.0 I have this config which resolved the issue and maintained functionality.

const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
});

module.exports = withBundleAnalyzer({
  webpack: (config, { isServer }) => {
    if (!isServer) {
      config.module.rules.push({
        test: /\.jsx?$/,
        resolve: {
          fallback: {
            crypto: false,
          },
          fullySpecified: false,
        },
      });
    }
    return config;
  },
  future: {
    webpack5: true,
  },
});

Heavily inspired by https://github.com/aws-amplify/amplify-js/issues/7570#issuecomment-860801238 & https://github.com/aws-amplify/amplify-js/blob/main/.github/actions/bundle-size-action/webpack/webpack.config.js

MrJadaml commented 3 years ago

The above config change by @afenton90 did help bring our bundle size down, though bundle sizes are still looking too big. Here is our specific comparison from master (pre-auth), to Amplify, next-auth, and Amplify post config change.

Screen Shot 2021-07-17 at 2 05 31 PM
hkjpotato commented 3 years ago

Hi friends, The bundle size issue due to crypto-js is fixed by https://github.com/brix/crypto-js/pull/364, and released in its 4.1.1 version.

Amplify has upgraded its crypto-js to 4.1.1 by https://github.com/aws-amplify/amplify-js/pull/8626

This should help wipe out those unnecessary packages for browser environment (e.g. bn.js), please try the newer version of amplify to see if it works for you. Thank you.

voigtito commented 3 years ago

First of all, thanks for all the afford on this matter.

Project: Next.js 10.1.3 with typescript

I updated to aws-amplify@4.2.2 as @hkjpotato said but it doesn't changed anything on my first load JS.

I am using the followings next.config.js:

const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
});

module.exports = withBundleAnalyzer({
  distDir: '.next',
  webpack: (config, options) => {
    if (!options.isServer) {
      config.node = {
        fs: 'empty',
        crypto: 'empty',
      }
    }
    return config
  }
})

But still got: image

Without amplify config on _app.tsx: image

The only thing that worked for me was to have modular import from @aws-amplify/core and @aws-amplify/auth. It has reduced the size like -40kb.

I tried @ericclemmons workaround but had no effect:

 module.exports = {
   target: 'serverless',
   webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
     config.resolve.extensions = ['.web.js', ...config.resolve.extensions]
     return config
   },
 }

Just confirming my aws-amplify package.json versions: image

Other fact that happened is that i had still to install aws-amplify package because i am using withSSRContext for using Auth on getServerSideProps. So my modular import for @aws-amplify/auth is almost useless. This is also mentioned in #8435

Its very sad because on AWS Amplify docs it has a topic for this but it is not helpfull. https://docs.aws.amazon.com/amplify/latest/userguide/server-side-rendering-amplify.html#app-too-large-to-deploy

So i feeling like i am reaching into a dead end, and my only options is stop using aws-amplify or changing my hole project to Create React App (CRA) with the risk of having some trouble over this kind of stuff again.

voigtito commented 3 years ago

(if it helps) image

ericclemmons commented 3 years ago

@voigtito Just to be sure I understand, you're blocked from deployment because of a RequestEntityTooLargeException error because lambda invocation payloads are limited to 256kB?

If that's the case, the first thing we should do is to remove defaultModules from withSSRContext and make it purely opt-in – this would behave like your modular import for aws-amplify/auth would, removing any other dependencies. That would almost certainly guarantee a substantially smaller payload.

voigtito commented 3 years ago

@ericclemmons yes! Changing to @aws-amplify/auth and @aws-amplify/core it was ok to deploy. But before that it was blocked because of RequestEntityTooLargeException.

https://docs.aws.amazon.com/amplify/latest/userguide/server-side-rendering-amplify.html#app-too-large-to-deploy i tried the solution in the link but it ended up not changing any size on my build.

Nice! I will try to remove them manually and report here :) thank you

hkjpotato commented 3 years ago

@voigtito Can you help check if the large bundle size is due to crypto-js? For example does it contain any file from "crypto-browserify" or its dependency like"bn.js". I wonder if it is because the fix is mainly for client side build (browser target) and does not address the node target build. Will look more into it.

voigtito commented 3 years ago

@hkjpotato as i see crypto is not a problem anymore! The amount of bn.js files reported from others here on the post did not apear on my bundle, perhaps the recent update had solved this problem :)

About the removing the packages manually as @ericclemmons suggested, it had a small impact on the First Load JS. Like (-2kb to -10kb). Thanks for the efford and attention btw :D

I guess the best alternative for now is to use next-auth for better performance (just to give a second option for those who are reading). It has integrations with cognito through the the hosting ui. https://next-auth.js.org/providers/cognito

ericclemmons commented 3 years ago

@voigtito Can you share your package.json for your Next.js project that had issues with deployment?

@evcodes & I are working on reproducing to get this resolved πŸ™

sammartinez commented 3 years ago

Reopening this issue as we are diving deeper on it

voigtito commented 3 years ago

Here it is :D

{
  "name": "",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "analyze": "ANALYZE=true next build",
    "start": "next start"
  },
  "dependencies": {
    "@aws-amplify/auth": "^4.2.0",
    "@aws-amplify/core": "^4.2.2",
    "@chakra-ui/core": "^0.8.0",
    "@chakra-ui/react": "^1.5.2",
    "@emotion/react": "^11.1.5",
    "@emotion/styled": "^11.3.0",
    "@hookform/resolvers": "^2.5.0",
    "@next/bundle-analyzer": "^11.0.1",
    "apexcharts": "^3.26.1",
    "aws-amplify": "^4.2.2",
    "axios": "^0.21.1",
    "dotenv": "^10.0.0",
    "framer-motion": "^4.1.6",
    "lodash.debounce": "^4.0.8",
    "next": "10.1.3",
    "react": "17.0.2",
    "react-apexcharts": "^1.3.9",
    "react-color": "^2.19.3",
    "react-dom": "17.0.2",
    "react-hook-form": "^7.4.2",
    "react-icons": "^4.2.0",
    "react-input-mask": "^2.0.4",
    "react-query": "^3.16.0",
    "yup": "^0.32.9"
  },
  "devDependencies": {
    "@testing-library/dom": "^7.31.2",
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^11.2.7",
    "@types/faker": "^5.5.5",
    "@types/node": "^14.14.41",
    "@types/react": "^17.0.3",
    "babel-jest": "^27.0.2",
    "faker": "^5.5.3",
    "jest": "^27.0.4",
    "jest-dom": "^4.0.0",
    "miragejs": "^0.1.41",
    "typescript": "^4.2.4"
  }
}