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.4k stars 2.11k forks source link

Cannot use amplify-js in browser environment (breaking vite / snowpack / esbuild) #9639

Closed sem4phor closed 4 months ago

sem4phor commented 3 years ago

Describe the bug

The package aws-amplify is meant to be used in the browser, isnt it? Therefore it should not rely on node builtins, which sadly is the case and prevents the usage of this package in many js build tools like rollup, snowpack or vitejs.

The @aws-sdk package which is used by aws-amplify relies on various node build in modules like fs, process or http2, ....

I described the issue also here (https://github.com/vitejs/vite/issues/1374) and Evan You the creator of vuejs and vite mentioned that webpack will drop support for node build ins in version five. Because webpack is used by tools such as create-react-app and vue-cli this will block many developers from using the amplify package soon I think!

To Reproduce Steps to reproduce the behavior:

  1. Download https://github.com/sem4phor/aws-cli-bug
  2. Run npm run dev (node required)
  3. See error in console

Expected behavior The package works in the browser and does not import any node build ins which are not available in browser environment.

Code Snippet https://github.com/sem4phor/aws-cli-bug

Screenshots

[plugin:vite:imports] Failed to resolve import "process". Does the file exist?
/Users/XXXXX/node_modules/@aws-sdk/util-user-agent-node/dist/es/index.js:1:22
1  |  import process from "process";
   |                       ^
2  |  export function defaultUserAgent(packageName, packageVersion) {
3  |      var engine = process.platform + "/" + process.version;
Error: Failed to resolve import "process". Does the file exist?
    at TransformContext.error (C:\Users\XXXXX\node_modules\vite\dist\node\chunks\dep-262f13eb.js:59552:50)
    at TransformContext.transform (C:\XXXXX\node_modules\vite\dist\node\chunks\dep-262f13eb.js:52957:30)
    at async Object.transform (C:\Users\XXXXX\node_modules\vite\dist\node\chunks\dep-262f13eb.js:59742:30)
    at async transformRequest (C:\Users\XXXXX\node_modules\vite\dist\node\chunks\dep-262f13eb.js:65977:29)
    at async C:\Users\XXXXX\node_modules\vite\dist\node\chunks\dep-262f13eb.js:66068:32

What is Configured? Not relevant for this error.

Jexordexan commented 3 years ago

I'm experiencing the same issue, I have had no luck finding a workaround. I am also using vite. Also @sem4phor, in the issue body, you mention @aws-cli but I believe the problem is with @aws-sdk.

soerenmartius commented 3 years ago

I second that. The problem seems to be in @aws-sdkSeems like the library has dependencies on node built-in types which is really bad. Seems like the library was built for webpack and is not usable with vite or rollup at the moment? Also, the coupling increases the size of the package significantly.

Are there any plans to get rid of the node dependencies anytime soon?

ebisbe commented 3 years ago

I have the same issue

Mootook commented 3 years ago

I was also getting this issue when trying to migrate an existing project onto Vite.

Apparently work is being done on the aws-sdk to update this: https://github.com/vitejs/vite/issues/1502#issuecomment-758822680

But I had to follow this to get my app running as Vite is using rollup: https://dev.to/swyx/making-aws-amplify-work-with-rollup-2d9m

ebisbe commented 3 years ago

But I had to follow this to get my app running as Vite is using rollup: https://dev.to/swyx/making-aws-amplify-work-with-rollup-2d9m

@Mootook Did that link work for you? I tried and couldn't make it work. I'm new to Rollup / Vite so I wasn't even sure it would work. I'll try again if that worked then.

mbp commented 3 years ago

But I had to follow this to get my app running as Vite is using rollup: https://dev.to/swyx/making-aws-amplify-work-with-rollup-2d9m

@Mootook Did that link work for you? I tried and couldn't make it work. I'm new to Rollup / Vite so I wasn't even sure it would work. I'll try again if that worked then.

I have the same issue (and also new to Rollup / Vite), so I am not sure how you would make the changes in e.g. vite.config.ts file where the syntax is different. Let me know if you make it work!

sem4phor commented 3 years ago

@Mootook It would be great if you could provide a repository with your suggested workaround :)

ebisbe commented 3 years ago

From what I have read the plugin interface of Vite is the same as Rollup so they should be compatible. What I don't understand is that in https://vite-rollup-plugins.patak.dev you can see that Json and node-resolve are already covered on Vite.

Mootook commented 3 years ago

@ebisbe, I didn't know that, good catch.

I have uploaded a small demo https://github.com/Mootook/aws-vite-demo/tree/main

But you're right, the plugin extension in vite.config.js is not necessary. Commenting it out, removing them as dependencies, and rebuilding seems to have no effect.

The only other issue I ran into was a global is not defined error, which has a solution in the index.html file.

sammartinez commented 3 years ago

@sem4phor Are you using Amplify JavaScript or using AWS SDK? I believe your issue is related to the AWS SDK instead of Amplify JS. Can you confirm?

ebisbe commented 3 years ago

@sammartinez Doesn't Aws-amplify use Aws-sdk? I use Aws-amplify but my errors come from node_modules/@aws-sdk and I have not installed in the package.json

ebisbe commented 3 years ago

@ebisbe, I didn't know that, good catch.

I have uploaded a small demo https://github.com/Mootook/aws-vite-demo/tree/main

But you're right, the plugin extension in vite.config.js is not necessary. Commenting it out, removing them as dependencies, and rebuilding seems to have no effect.

The only other issue I ran into was a global is not defined error, which has a solution in the index.html file.

Your code is working indeed. But when I add your vite.config.js it still fails in mine... I've been trying to sample the minimum to make it work on my project but it doesn't. Besides what you have I'm using Tailwind

sammartinez commented 3 years ago

@ebisbe correct, we use AWS SDK but it is a dependency and separate team and repo that handles errors related to it.

Mootook commented 3 years ago

@ebisbe, I updated my repo to use tailwind and it's working.

What errors are you getting? Is it still failing on the amplify dependency?

there is also a vite specific discord for general troubleshooting https://discord.gg/y44Ad4hF

mbp commented 3 years ago

@Mootook correct me if I am wrong, but I don't actually see you using aws-amplify in your repo (other than the package.json dependency)

If you insert the following code into main.js:

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

Amplify.configure({});

Then npm run build will start failing with

'request' is not exported by __vite-browser-external, imported by node_modules\@aws-sdk\credential-provider-imds\dist\es\remoteProvider\httpRequest.js

This is the error message originally reported in the chain of issues: https://github.com/vitejs/vite/issues/1502 => https://github.com/vitejs/vite/issues/1374#issuecomment-754820938 => this

Mootook commented 3 years ago

@mbp Ah! Yes, you're correct. Apologies, I just went off the original steps to reproduce, which just included npm run dev (which does work, even with Amplify.configure()...odd), but the error is present in npm run build.

So credential provider is expecting the node http global which is not bundled with rollup. There is the 'rollup-plugin-node-builtins' package, but it seems outdated and sort of undercuts what Vite is striving for.

ebisbe commented 3 years ago

@ebisbe, I updated my repo to use tailwind and it's working.

What errors are you getting? Is it still failing on the amplify dependency?

there is also a vite specific discord for general troubleshooting https://discord.gg/y44Ad4hF

It's funny because when I moved my code to your repo it's all working but in mine it still failing. I've forked your repo with my code added in https://github.com/ebisbe/aws-vite-demo and my failing code in here https://github.com/ebisbe/skedr-prototype/tree/live

The error I get is:

⌊☻ yarn dev
yarn run v1.22.10
$ vite --open
Pre-bundling dependencies:
  vue
  vue-router
  aws-amplify
  luxon
  lodash/groupBy
  (...and 1 more)
(this will be run only when your dependencies or config have changed)
 > node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js: error: No matching export for import "request"
    4 │ import { request } from "http";
      ╵          ~~~~~~~

 > node_modules/@aws-sdk/shared-ini-file-loader/dist/es/index.js: error: No matching export for import "readFile"
    2 │ import { readFile } from "fs";
      ╵          ~~~~~~~~

 > node_modules/@aws-sdk/shared-ini-file-loader/dist/es/index.js: error: No matching export for import "homedir"
    3 │ import { homedir } from "os";
      ╵          ~~~~~~~

 > node_modules/@aws-sdk/shared-ini-file-loader/dist/es/index.js: error: No matching export for import "join"
    4 │ import { join, sep } from "path";
      ╵          ~~~~

 > node_modules/@aws-sdk/shared-ini-file-loader/dist/es/index.js: error: No matching export for import "sep"
    4 │ import { join, sep } from "path";
      ╵                ~~~

 > node_modules/@aws-sdk/credential-provider-process/dist/es/index.js: error: No matching export for import "exec"
    4 │ import { exec } from "child_process";
      ╵          ~~~~

 > node_modules/@aws-sdk/node-http-handler/dist/es/write-request-body.js: error: No matching export for import "Readable"
    1 │ import { Readable } from "stream";
      ╵          ~~~~~~~~

 > node_modules/@aws-sdk/node-http-handler/dist/es/node-http-handler.js: error: No matching export for import "Agent"
    3 │ import { Agent as hAgent, request as hRequest } from "http";
      ╵          ~~~~~

 > node_modules/@aws-sdk/node-http-handler/dist/es/node-http-handler.js: error: No matching export for import "request"
    3 │ import { Agent as hAgent, request as hRequest } from "http";
      ╵                           ~~~~~~~

 > node_modules/@aws-sdk/node-http-handler/dist/es/node-http-handler.js: error: No matching export for import "Agent"
    4 │ import { Agent as hsAgent, request as hsRequest } from "https";
      ╵          ~~~~~

 > node_modules/@aws-sdk/node-http-handler/dist/es/node-http-handler.js: error: No matching export for import "request"
    4 │ import { Agent as hsAgent, request as hsRequest } from "https";
      ╵                            ~~~~~~~

 > node_modules/@aws-sdk/node-http-handler/dist/es/node-http2-handler.js: error: No matching export for import "connect"
    4 │ import { connect, constants } from "http2";
      ╵          ~~~~~~~

 > node_modules/@aws-sdk/node-http-handler/dist/es/node-http2-handler.js: error: No matching export for import "constants"
    4 │ import { connect, constants } from "http2";
      ╵                   ~~~~~~~~~

 > node_modules/@aws-sdk/node-http-handler/dist/es/stream-collector/collector.js: error: No matching export for import "Writable"
    2 │ import { Writable } from "stream";
      ╵          ~~~~~~~~

 > node_modules/@aws-sdk/util-body-length-node/dist/es/index.js: error: No matching export for import "lstatSync"
    1 │ import { lstatSync } from "fs";
      ╵          ~~~~~~~~~

 > node_modules/@aws-sdk/eventstream-serde-node/dist/es/EventStreamMarshaller.js: error: No matching export for import "Readable"
    4 │ import { Readable } from "stream";
      ╵          ~~~~~~~~

 > node_modules/@aws-sdk/hash-stream-node/dist/es/hash-calculator.js: error: No matching export for import "Writable"
    2 │ import { Writable } from "stream";
      ╵          ~~~~~~~~

 > node_modules/@aws-sdk/hash-stream-node/dist/es/index.js: error: No matching export for import "createReadStream"
    1 │ import { createReadStream } from "fs";
      ╵          ~~~~~~~~~~~~~~~~

error when starting dev server:
Error: Build failed with 18 errors:
node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js:4:9: error: No matching export for import "request"
node_modules/@aws-sdk/credential-provider-process/dist/es/index.js:4:9: error: No matching export for import "exec"
node_modules/@aws-sdk/eventstream-serde-node/dist/es/EventStreamMarshaller.js:4:9: error: No matching export for import "Readable"
node_modules/@aws-sdk/hash-stream-node/dist/es/hash-calculator.js:2:9: error: No matching export for import "Writable"
node_modules/@aws-sdk/hash-stream-node/dist/es/index.js:1:9: error: No matching export for import "createReadStream"
...
    at failureErrorWithLog (/Volumes/Data/Development/skedr/next_prototype/node_modules/esbuild/lib/main.js:1124:15)
    at buildResponseToResult (/Volumes/Data/Development/skedr/next_prototype/node_modules/esbuild/lib/main.js:879:32)
    at /Volumes/Data/Development/skedr/next_prototype/node_modules/esbuild/lib/main.js:974:20
    at /Volumes/Data/Development/skedr/next_prototype/node_modules/esbuild/lib/main.js:541:9
    at handleIncomingPacket (/Volumes/Data/Development/skedr/next_prototype/node_modules/esbuild/lib/main.js:624:9)
    at Socket.readFromStdout (/Volumes/Data/Development/skedr/next_prototype/node_modules/esbuild/lib/main.js:508:7)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:298:12)
    at readableAddChunk (_stream_readable.js:273:9)
    at Socket.Readable.push (_stream_readable.js:214:10)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
sem4phor commented 3 years ago

Are you using Amplify JavaScript or using AWS SDK? I believe your issue is related to the AWS SDK instead of Amplify JS. Can you confirm?

@sammartinez I am using amplify which has aws-sdk as it's dependency (see reproduction repository)

The vue label is kinda wrong. It is an issue with js bundlers which use native ecmascript modules. Vite is not vue-only.

sammartinez commented 3 years ago

@sem4phor I guess I am a little confused and will need more information from you. What is your use case you are looking to do ? In looking at the code sample provided, thank you by the way it was helpful, I am not seeing a direct dependency of aws-amplify or an aws-exports file for testing the configuration, just an empty object passed. To some of the errors called out in the stack traces above, we have done some clean up on the library recently to remove unused dependencies. Can you look at testing the latest version of aws-amplify with your sample?

madmod commented 3 years ago

I too am having this issue. I have imported @aws-sdk/client-cognito-identity and @aws-sdk/credential-provider-cognito-identity directly. I am using Vite and not using Amplify fyi. Hopefully that helps you track down the root cause.

madmod commented 3 years ago

I have determined that the following modules cause build errors related to expecting various node js modules in the browser such as http and fs.

        '@aws-sdk/credential-provider-imds',
        '@aws-sdk/credential-provider-process',
        '@aws-sdk/shared-ini-file-loader',
        '@aws-sdk/eventstream-serde-node',
        '@aws-sdk/hash-node',
        '@aws-sdk/node-http-handler',
        '@aws-sdk/util-body-length-node',
        '@aws-sdk/util-user-agent-node',
bhvngt commented 3 years ago

I am facing the same issue while using vite.

I am getting the previously reported error 'request' is not exported by __vite-browser-external, imported by node_modules\@aws-sdk\credential-provider-imds\dist\es\remoteProvider\httpRequest.js. Is this something that is fixed? I have tried this with the latest version of aws-amplify 3.3.22.

I tried with rollup config as suggested earlier in this thread. I also experimented with rollup-plugin-polyfill-node. Both of them fails to fix the issue.

Here's my vite.config.js

import svelte from "rollup-plugin-svelte-hot";
import autoPreprocess from "svelte-preprocess";
import nodeResolve from "@rollup/plugin-node-resolve";
import json from "@rollup/plugin-json";

export default {
    alias: {
        "@": resolve(__dirname, "src"),
    },
    root: "src",
    plugins: [
        svelte({
            preprocess: autoPreprocess(),
            dev: true,
            hot: true,
        }),
    ],
    build: {
        rollupOptions: {
            plugins: [
                nodeResolve({
                    browser: true,
                    preferBuiltins: false,
                }),
                json(),
            ],
        },
    },
};

Error dump

'request' is not exported by __vite-browser-external, imported by node_modules/.pnpm/@aws-sdk/credential-provider-imds@3.6.1/node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js
file: /temp/tst/node_modules/.pnpm/@aws-sdk/credential-provider-imds@3.6.1/node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js:4:9
2: import { ProviderError } from "@aws-sdk/property-provider";
3: import { Buffer } from "buffer";
4: import { request } from "http";
            ^
5: /**
6:  * @internal
error during build:
Error: 'request' is not exported by __vite-browser-external, imported by node_modules/.pnpm/@aws-sdk/credential-provider-imds@3.6.1/node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js
    at error (/temp/tst/node_modules/.pnpm/rollup@2.40.0/node_modules/rollup/dist/shared/rollup.js:5279:30)
    at Module.error (/temp/tst/node_modules/.pnpm/rollup@2.40.0/node_modules/rollup/dist/shared/rollup.js:9996:16)
    at Module.traceVariable (/temp/tst/node_modules/.pnpm/rollup@2.40.0/node_modules/rollup/dist/shared/rollup.js:10389:29)
    at ModuleScope.findVariable (/temp/tst/node_modules/.pnpm/rollup@2.40.0/node_modules/rollup/dist/shared/rollup.js:8847:39)
    at FunctionScope.findVariable (/temp/tst/node_modules/.pnpm/rollup@2.40.0/node_modules/rollup/dist/shared/rollup.js:2641:38)
    at ChildScope.findVariable (/temp/tst/node_modules/.pnpm/rollup@2.40.0/node_modules/rollup/dist/shared/rollup.js:2641:38)
    at FunctionScope.findVariable (/temp/tst/node_modules/.pnpm/rollup@2.40.0/node_modules/rollup/dist/shared/rollup.js:2641:38)
    at ChildScope.findVariable (/temp/tst/node_modules/.pnpm/rollup@2.40.0/node_modules/rollup/dist/shared/rollup.js:2641:38)
    at Identifier.bind (/temp/tst/node_modules/.pnpm/rollup@2.40.0/node_modules/rollup/dist/shared/rollup.js:4017:40)
    at CallExpression.bind (/temp/tst/node_modules/.pnpm/rollup@2.40.0/node_modules/rollup/dist/shared/rollup.js:2728:23)
jarrodu commented 3 years ago

I am so glad I found this issue since I was about to write my own.

I am also having this issue.

vovapyc commented 3 years ago

Hi @bhavinkamani-gt, have you manage to fix it?

jarrodu commented 3 years ago

I noticed that the "to-be-reproduced" tag was added to this issue. I am willing to spend a bit of time setting up a minimal example of the issue I am having. Is there a protocol for submitting an example or is a temporary public git repo with a README enough?

bhvngt commented 3 years ago

@vovawed No, I haven't yet found the solution.. As a workaround, I am using snowpack to do my production builds. Snowpack has a built-in support for node-polyfills with snowpack build --polyfill-node.

As commented here. This should have been fixed in this library by isolating node related code. However, it doesn't seem to have happen.

@sammartinez Would you have any update on this issue?

sem4phor commented 3 years ago

I think to be reprouced relates to a maintainer who needs to reproduce this. I have already submitted a reproduction repository...

Moreover the label Amplify UI Components is wrong, too IMO. The issue persists without importing ui components @sammartinez

sammartinez commented 3 years ago

Thanks for this feedback, I have removed the label. I will have my oncall look into this tomorrow.

jarrodu commented 3 years ago

When using Vite and the authentication documentation here: https://docs.amplify.aws/ui/auth/authenticator/q/framework/vue

I hit the same nodejs issues this issue describes.

So with this,

 "dependencies": {
    "@aws-amplify/ui-components": "^1.1.0",
    "aws-amplify": "^3.3.24",
    "vue": "^3.0.5"
  }

I get this,

'request' is not exported by __vite-browser-external,

asmajlovicmars commented 3 years ago

Having the same issue with SvelteKit and Amplify, and not including aws-sdk. Just Amplify js, but aws-sdk is called implicitly, as a dependency I guess...

request' is not exported by __vite-browser-external, imported by node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js file: /Users/asmajlovic/code/sveltekit/p1/node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js:4:9 2: import { ProviderError } from "@aws-sdk/property-provider"; 3: import { Buffer } from "buffer"; 4: import { request } from "http"; ^ 5: /* 6: @internal

'request' is not exported by __vite-browser-external, imported by node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js

ErikCH commented 3 years ago

I found a workaround that can help for now. Eventually this will probably need to be fixed in the @aws-sdk

Add a vite.confg.js file to the root of the project. You'll need to add a new resolve.alias.

// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

// https://vitejs.dev/config/
export default defineConfig({
        plugins: [vue()],
        resolve: {
                alias: [
                  {
                        find: "./runtimeConfig",
                        replacement: ("./runtimeConfig.browser"),
                  },
                ],
          },

});

Then inside the index.html file add a script tag below the <div id="app></div> but above the module script import

<!-- index.html -->
<script>
      window.global = window;
      var exports = {}
</script>

You need to set window.global and exports. If you don't set window.global it won't work in development. If you don't add in var exports = {} then it will build, but will throw an error when you open it up on your web browser.

I made a branch here you can take a look at too. https://github.com/ErikCH/amplify-js/tree/hotfix/error-with-vite/.github/actions/bundle-size-action/vite

bhvngt commented 3 years ago

Thanks a ton @ErikCH. It works good for now. My builds are working without a hitch.

As mentioned, will look forward to the long term solution.

rafrasenberg commented 3 years ago

Awesome!! Many thanks @ErikCH , finally a solution that works. Legend!

josephfh commented 3 years ago

Thanks a lot for the solution @ErikCH I can't believe my luck that you posted this today!

asmajlovicmars commented 3 years ago

Hi @ErikCH, I tried to do a similar thing with SvelteKit, but no luck yet. Vite.js config is stored in svelte.config.cjs. If you have any advice, please share. Thanks!

// svelte.config.cjs
const st = require('@sveltejs/adapter-static');

module.exports = {
  kit: {
    adapter: st(),
    target: '#svelte',
    vite: {
      build: {
        minify: false,
      },
      resolve: {
        alias: [
          {
            find: './runtimeConfig',
            replacement: './runtimeConfig.browser',
          },
        ],
      },
    },
  },
};

Error:

vite v2.1.2 building for production...
✓ 741 modules transformed.
'request' is not exported by __vite-browser-external, imported by node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js
file: /Users/asmajlovic/code/sveltekit/p1/node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js:4:9
2: import { ProviderError } from "@aws-sdk/property-provider";
3: import { Buffer } from "buffer";
4: import { request } from "http";
            ^
5: /**
6:  * @internal
> 'request' is not exported by __vite-browser-external, imported by node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js
Error: 'request' is not exported by __vite-browser-external, imported by node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js
    at error (/Users/asmajlovic/code/sveltekit/p1/node_modules/rollup/dist/shared/rollup.js:5307:30)
    at Module.error (/Users/asmajlovic/code/sveltekit/p1/node_modules/rollup/dist/shared/rollup.js:9716:16)
    at Module.traceVariable (/Users/asmajlovic/code/sveltekit/p1/node_modules/rollup/dist/shared/rollup.js:10104:29)
    at ModuleScope.findVariable (/Users/asmajlovic/code/sveltekit/p1/node_modules/rollup/dist/shared/rollup.js:8874:39)
    at FunctionScope.findVariable (/Users/asmajlovic/code/sveltekit/p1/node_modules/rollup/dist/shared/rollup.js:2657:38)
    at ChildScope.findVariable (/Users/asmajlovic/code/sveltekit/p1/node_modules/rollup/dist/shared/rollup.js:2657:38)
    at FunctionScope.findVariable (/Users/asmajlovic/code/sveltekit/p1/node_modules/rollup/dist/shared/rollup.js:2657:38)
    at ChildScope.findVariable (/Users/asmajlovic/code/sveltekit/p1/node_modules/rollup/dist/shared/rollup.js:2657:38)
    at Identifier.bind (/Users/asmajlovic/code/sveltekit/p1/node_modules/rollup/dist/shared/rollup.js:4042:40)
    at CallExpression.bind (/Users/asmajlovic/code/sveltekit/p1/node_modules/rollup/dist/shared/rollup.js:2744:23)
ErikCH commented 3 years ago

@asmajlovicmars In your svelte.config.cjs import your resolve.alias like this

resolve: {
        alias: {
          "./runtimeConfig": "./runtimeConfig.browser"
        }
      }
asmajlovicmars commented 3 years ago

Thanks a lot @ErikCH, Your solution unblocked the SvelteKit + Amplify build!

However, when I tried to run the built code, which works perfectly with npm run dev, it gets stuck when it gets to Amplify. If it helps, I built a small repo, which only needs a valid aws-exports.js to test this.

Repo: https://github.com/adnansmajlovic/svk Error: ReferenceError: AmplifyClass is not defined

Of course, I'm still looking into it, but if anything comes to mind, please share.

Super thankful for unblocking the build 🎉

ErikCH commented 3 years ago

@asmajlovicmars Looking at the repository, I saw some old @aws-amplify imports. You may want to double check those and switch them to named imports from version 3 import { Analytics } from 'aws-amplify';.

I did some tests and I might have found another work around for SvelteKit. To run in dev mode, take out ssr inside the config.

// remove this
ssr: {
    noExternal: Object.keys(pkg.dependencies || {})
    },

When I tested this allowed me to work in dev mode.

However, to build, I had to add it back in SSR. I also added in a few extra configurations into the config file, since it didn't seem to pick them up from the HTML file. Here is the vite portion of the config.

...
vite: {
      ssr: {
        noExternal: Object.keys(pkg.dependencies || {})
      },
      resolve: {
        alias: {
          "./runtimeConfig": "./runtimeConfig.browser"
        }
      },
      build: {
        rollupOptions: {
          output: {
            intro: "if(exports === undefined){var exports ={}; var self = {}}"
          }
        }
      }
    }
...

With this configuration I was able to use Auth, after building and running it.

Here is a test repo with it working, make sure to add your Amplify configure exports.

asmajlovicmars commented 3 years ago

Thank you @ErikCH!

It finally builds with Amplify, and as you confirmed Auth works too! I used old imports only because I had to import them dynamically in onMount, since the regular import wouldn't work, but now everything is as it should be, thanks to you! 😁 🎉

Will keep looking if it's possible to have dev and build mode working without changing ssr in svelte.config.cjs, but that's perfectly fine!

Once again, thanks a lot for your help!!! 🙌

TheDutchCoder commented 3 years ago

You can also shim this by using this pattern: https://github.com/Azure/azure-sdk-for-js/issues/14496#issuecomment-808442337

radiosilence commented 3 years ago

Am using pure Vite+React and whilst the above solved the build, I now get this in browser:

Screenshot 2021-04-30 at 10 46 48

The yellow warnings are actually mine so it looks like in some way Amplify is loading, however that's as far as it gets.

:(

Here is my vite.config.ts

import reactRefresh from '@vitejs/plugin-react-refresh';
import { defineConfig } from 'vite';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [reactRefresh()],
  resolve: {
    alias: {
      './runtimeConfig': './runtimeConfig.browser',
    },
  },
  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true,
      },
    },
  },
});
ErikCH commented 3 years ago

I was able to reproduce that as well @radiosilence .

A quick work around is don't use the @aws-amplify/ui-react library. Use the aws-amplify library instead. You'll have to create your own UI, but it should work. Here is the guide to the API https://docs.amplify.aws/lib/q/platform/js

signal-intrusion commented 3 years ago

My silly workaround for a static site with some TypeScript, but without Webpack was to import the entire library into my "main" file:

// app.ts
import * as amplify from 'aws-amplify/dist/aws-amplify.min.js'

amplify.Auth.configure() // you get the idea
simlevesque commented 3 years ago

Am using pure Vite+React and whilst the above solved the build, I now get this in browser:

@radiosilence

I get the same error, this seems to me like it's a StencilJS error.

Here's the issue: https://github.com/ionic-team/stencil/issues/2827

I fixed the error by skipping ui-vue and doing this:

import { defineCustomElements } from '@aws-amplify/ui-components/dist/components/index.js';
defineCustomElements(window);

Now Vite can build the project.

tranthaison1231 commented 3 years ago

@simlevesque I have the same error live you, do you have any idea to fix it??

simlevesque commented 3 years ago

@tranthaison1231

did you try the fix I mentionned in my previous comment ?

tranthaison1231 commented 3 years ago

image I got an error like this.

half2me commented 3 years ago

@asmajlovicmars In your svelte.config.cjs import your resolve.alias like this

resolve: {
        alias: {
          "./runtimeConfig": "./runtimeConfig.browser"
        }
      }

thanks this worked for me

radiosilence commented 3 years ago

@ErikCH Honeslty I eventually solved this by getting rid of Amplify and just writing a light wrapper around amazon-cognito-identity-js and my own login form.

Here it is if anyone wants to use it:

import * as AmazonCognitoIdentity from "amazon-cognito-identity-js";

let userPool: AmazonCognitoIdentity.CognitoUserPool;

export function configure(
  poolConfig: AmazonCognitoIdentity.ICognitoUserPoolData
) {
  userPool = new AmazonCognitoIdentity.CognitoUserPool(poolConfig);
}

function checkPool() {
  if (!userPool) throw new Error("Cognito User Pool has not been configured");
}

export async function getSession(): Promise<AmazonCognitoIdentity.CognitoUserSession> {
  checkPool();
  return new Promise((resolve, reject) => {
    const currentUser = userPool.getCurrentUser();
    if (!currentUser) return reject("not signed in");
    currentUser.getSession(
      (err: unknown, session: AmazonCognitoIdentity.CognitoUserSession) => {
        if (err) return reject(err);
        if (!session) return reject("no user data");
        resolve(session);
      }
    );
  });
}

export async function getValidSessionUser(): Promise<AmazonCognitoIdentity.CognitoUser> {
  checkPool();
  return new Promise((resolve, reject) => {
    const currentUser = userPool.getCurrentUser();
    if (!currentUser) return reject("not signed in");
    currentUser.getSession(
      (err: unknown, session: AmazonCognitoIdentity.CognitoUserSession) => {
        if (err) return reject(err);
        if (!session) return reject("no session");
        if (!session.isValid) return reject("session invalid");
        resolve(currentUser);
      }
    );
  });
}

export async function getUserData(): Promise<AmazonCognitoIdentity.UserData> {
  checkPool();
  const currentUser = await getValidSessionUser();
  return new Promise((resolve, reject) => {
    currentUser.getUserData((err, userData) => {
      if (err) return reject(err);
      if (!userData) return reject("no user data");
      resolve(userData);
    });
  });
}

export async function getUserAttributes(): Promise<Record<string, string>> {
  checkPool();
  const currentUser = await getValidSessionUser();
  return new Promise((resolve, reject) => {
    currentUser.getUserAttributes((err, userAttributes) => {
      if (err) return reject(err);
      if (!userAttributes) return reject("no user data");
      resolve(
        userAttributes.reduce(
          (acc: Record<string, string>, attribute) => ({
            ...acc,
            [attribute.Name]: attribute.Value,
          }),
          {}
        )
      );
    });
  });
}

export async function getIdToken() {
  checkPool();
  const session = await getSession();
  if (!session.isValid) throw new Error("invalid session");
  return session.getIdToken().getJwtToken();
}

export function signIn(username: string, password: string) {
  checkPool();
  return new Promise((resolve, reject) => {
    const authenticationDetails =
      new AmazonCognitoIdentity.AuthenticationDetails({
        Username: username,
        Password: password,
      });
    const cognitoUser = new AmazonCognitoIdentity.CognitoUser({
      Username: username,
      Pool: userPool,
    });
    cognitoUser.authenticateUser(authenticationDetails, {
      onSuccess: (result) => resolve(result),
      onFailure: (error) => reject(error),
      // newPasswordRequired: () => reject(new Error('not implemented: new password required')),
      newPasswordRequired: () => {
        cognitoUser.completeNewPasswordChallenge(
          password,
          {},
          { onSuccess: resolve, onFailure: reject }
        );
      },
      mfaRequired: () => reject(new Error("not implemented: mfa required")),
      totpRequired: () => reject(new Error("not implemented: totp required")),
      customChallenge: () =>
        reject(new Error("not implemented: custom challenge")),
      mfaSetup: () => reject(new Error("not implemented: mfa setup")),
      selectMFAType: () =>
        reject(new Error("not implemented: select mfa type")),
    });
  });
}

export function forgotPassword(username: string) {
  checkPool();
  return new Promise((resolve, reject) => {
    const cognitoUser = new AmazonCognitoIdentity.CognitoUser({
      Username: username,
      Pool: userPool,
    });
    cognitoUser.forgotPassword({
      onSuccess: (result) => resolve(result),
      onFailure: (error) => reject(error),
    });
  });
}

export function confirmPassword(
  username: string,
  verificationCode: string,
  newPassword: string
) {
  checkPool();
  return new Promise((resolve, reject) => {
    const cognitoUser = new AmazonCognitoIdentity.CognitoUser({
      Username: username,
      Pool: userPool,
    });
    cognitoUser.confirmPassword(verificationCode, newPassword, {
      onSuccess: () => resolve(null),
      onFailure: (error) => reject(error),
    });
  });
}

export function signOut() {
  checkPool();
  const currentUser = userPool.getCurrentUser();
  if (currentUser) {
    currentUser.signOut();
  }
}
stale[bot] commented 2 years ago

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.