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

Vite apps will not build or run while using Amplify libraries with AWS-SDK #3673

Closed
3 tasks done
ErikCH opened this issue Mar 23, 2021 · 38 comments
Closed
3 tasks done
Labels
bug This issue is a bug. p2 This is a standard priority issue workaround-available

Comments

@ErikCH
Copy link

ErikCH commented Mar 23, 2021

Confirm by changing [ ] to [x] below to ensure that it's a bug:

Describe the bug
Customers using the Amplify library are not able to use Vite, a native ESM no-bundle dev server, for Vue, React and Preact. After installing the package customers trying to run the dev server will get this error.

Uncaught ReferenceError: global is not defined
    at index.js:43
    at aws-amplify.js?v=b14c5c6f:14
    at AuthenticationHelper.js:17

Users trying to build their app will get this error.

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/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js
    at error ...

After further research with the Amplify team we have found a workaround as illustrated in 7499.

This workaround explicitly tells Vite, which uses rollup, to alias the runtimeConfig to the runtimeConfig.browser file.

We believe the problem is that Vite doesn't respect the browser field in @aws-sdk/client- package.json. This is a deliberate action made on the maintainers behalf, as outlined here.

vitejs/vite#2329
okta/okta-auth-js#641

This is what we learned as discussed from this comment here.

  1. @aws-sdk/credential-provider-imds is only required by @aws-sdk/credential-provider-node
  2. @aws-sdk/credential-provider-node is defined in runtimeConfig.ts within the @aws-sdk/client-* packages.`

Is it possible for the @aws-sdk/client libraries to update their package.json's so Vite, and other ESM bundlers would correctly use the correct browser packages, and not the Node built-ins, since it's not respecting the browser field? The maintainer has recommended using exports as one possible solution.

Anecdotally, this issue might also exist with Snowpack, another ESM dev server, however, it has a workaround by using the --polyfill-node pollyfill argument, that Vite does not have.

Is the issue in the browser/Node.js?
Browse

SDK version number
Example: latest

To Reproduce (observed behavior)
I have a repo with the work around here.
To reproduce the issue remove the alias from the vite config, and the <script> tag in the index.html.

Or create a new vite app

$ yarn create @vitejs/app
$ cd new-vite-app
$ yarn

Install amplify

yarn add aws-amplify

Add amplify to main.js file

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

Amplify.configure({});

Run the server and then try to build the server

yarn run dev
yarn run build

Expected behavior
Dev server and builds should run without errors, or needing to add global and exports into script tag for HTML.

@ErikCH ErikCH added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Mar 23, 2021
@half2me
Copy link

half2me commented Jun 1, 2021

any update on this? I have the exact same issue using SvelteKit

@woniupapa
Copy link

@ErikCH
<script> var global = global || window; var Buffer = Buffer || []; var process = process || { env: { DEBUG: undefined }, version: [] }; </script>

please add these code to index.html,maybe can fix it.

@woniupapa
Copy link

@ErikCH https://stackoverflow.com/questions/66912795/in-vite-vue3-ts-project-aws-amplify-failed-to-resolve-components

@haoqunjiang
Copy link

haoqunjiang commented Jul 9, 2021

Vite actually respects the browser field. But it only reads from the package root.

However, these problematic packages have more than one package.json.

For example, the @aws-sdk/client-cognito-identity has a package.json under the dist/es/ directory. https://unpkg.com/browse/@aws-sdk/client-cognito-identity@3.20.0/dist/es/package.json
And that's what it expects the bundlers to read. It is respected in webpack but not in vite.

To be fair, this is undocumented behavior. The browser field spec never says which package.json a bundler should read.

The SDK can fix this issue by removing the nested package.jsons and use the full path in the root package.json:

"browser": {
  "./dist/cjs/runtimeConfig": "./dist/cjs/runtimeConfig.browser",
  "./dist/es/runtimeConfig": "./dist/es/runtimeConfig.browser"
}

@hkjpotato
Copy link

hkjpotato commented Jul 9, 2021

@sodatea thank you for the sync up and update on this.

attached the screenshot for reference:
Screen Shot 2021-07-09 at 11 40 24 AM


update:

  1. notice that if you upgrade to the latest vite 2.4.1, the nested package.json issue will be solved.
  2. this is because the esbuild used by vite can recognize the nested package.json (during building at pre-bundling stage stage).
  3. even esbuild can recognize the nested package.json, "vite should handle the resolving..to support vite plugin and to be compatible with rollup plugin, so as to ensure the consistency between dev and build"..quoted from sodatea.
  4. related nodejs spec https://nodejs.org/api/packages.html#packages_conditions_definitions

@ajredniwja
Copy link
Contributor

Related to aws/aws-sdk-js-v3#2564

@ajredniwja ajredniwja added workaround-available and removed needs-triage This issue or PR still needs to be triaged. labels Sep 30, 2021
@chovyprognos
Copy link

I don't have a runtimeConfig.js file, what is it? What do I put in it?

@chovyprognos
Copy link

I'm getting this error:

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

@ErikCH
Copy link
Author

ErikCH commented Oct 27, 2021

Hi @chovyprognos , while this is being worked on, have you tried this work around? IN this documentation. https://ui.docs.amplify.aws/ui/getting-started/installation?platform=vue

@24jr
Copy link

24jr commented Nov 3, 2021

I'm having this issue trying to build sveltekit site with vite and aws-amplify @ErikCH thanks for sending that im sure some variation of that is what I'll need for sveltekit.

P.S. I've been watching your youtube for long time so when I come across issues and search only to see you always being a solutions guy two steps ahead of me for aws-amplify issues I'm just like man Erik is a man of the people. Keep it up

@kaleabmelkie
Copy link

@24jr Have you tried these three steps mentioned in aws-amplify/amplify-js#9639

This workaround for aws-amplify in SvelteKit has been working for me for sometime now. Let me know if I can help if you're facing any specific issues afterwards.

@24jr
Copy link

24jr commented Nov 3, 2021

@kaleabmelkie well that is for vue do you know how I do that in sveltekit?
this is what svelte.config.js was by default

/** @type {import('@sveltejs/kit').Config} */
const config = {
	kit: {
		// hydrate the <div id="svelte"> element in src/app.html
		target: '#svelte'
	}
};

export default config;

then I add the adapter like this

/** @type {import('@sveltejs/kit').Config} */
import adapter from '@sveltejs/adapter-node';

export default {
	kit: {
    target: '#svelte',
		adapter: adapter({
			// default options are shown
			out: 'build',
			precompress: false,
			env: {
				host: 'HOST',
				port: 'PORT'
			},
		})
	}
};

now I need to add the resolve part

/** @type {import('@sveltejs/kit').Config} */
import adapter from '@sveltejs/adapter-node';

export default {
	kit: {
    target: '#svelte',
		adapter: adapter({
			// default options are shown
			out: 'build',
			precompress: false,
			env: {
				host: 'HOST',
				port: 'PORT'
			},
      resolve: {
        alias: {
          './runtimeConfig': './runtimeConfig.browser',
        },
      },
		})
	}
};

this is not working but something like this do you by chance know?

@kaleabmelkie
Copy link

kaleabmelkie commented Nov 3, 2021

The 'resolve' is not meant to be inside the adpater's options. It should be directly inside the 'kit.vite' object.

@kaleabmelkie
Copy link

kaleabmelkie commented Nov 3, 2021

@24jr Here's how it might look for your config:

import adapter from '@sveltejs/adapter-node'

/** @type {import('@sveltejs/kit').Config} */
export default {
  kit: {
    target: '#svelte',

    adapter: adapter({
      // default options are shown
      out: 'build',
      precompress: false,
      env: {
        host: 'HOST',
        port: 'PORT'
      },
    }),

    vite: {
      resolve: {
        alias: {
          './runtimeConfig': './runtimeConfig.browser',
        },
      },
    },
  },
}

P.S. it should work with any or no svelte adapters. (I've tried it with adapter-static, adapter-vercel & without any adapters).

@24jr
Copy link

24jr commented Nov 3, 2021

@kaleabmelkie Wow extremely helpful. I'm not well versed on what adapter is other than that is translates svelte code to a simple clean build of what is actually used. When you say without any adapters is there a built in default and dont need to import others necessarily? Like such? (which still gave 'request' is not exported by __vite-browser-external, imported by node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js )

/** @type {import('@sveltejs/kit').Config} */
const config = {
	kit: {
		// hydrate the <div id="svelte"> element in src/app.html
		target: '#svelte'
	},
  vite: {
    resolve: {
      alias: {
        './runtimeConfig': './runtimeConfig.browser',
      },
    },
  },
};

export default config;

Now using adapter-node how you did successfully created the build files however there must be issue with how I'm using amplify-configure getting red 'Amplify.configure is not a function' on completion of build and when run npm run preview

Run npm run preview to preview your production build locally.

> Using @sveltejs/adapter-node
> Amplify.configure is not a function

which I am using in my __layout.svelte file like

<script context="module">
  import "../app.css";
  import Layout from "$lib/views/Layout/index.svelte";
  import Amplify from "aws-amplify";
  import awsExports from "../aws-exports";
  Amplify.configure({ ...awsExports, ssr: true });
  import { initAuth } from "$lib/components/Auth/store";
  initAuth();
</script>

Is that how you did yours? there isnt like a main.js or anything (idk if ssr even doing anything but might be)

@kaleabmelkie
Copy link

I used a named Amplify import (instead of the default import) for the 'Amplify.configure is not a function' issue during previews.

See the last part of this comment: aws-amplify/amplify-js#9639

@24jr
Copy link

24jr commented Nov 4, 2021

@kaleabmelkie I absolutely appreciate you. Everything is working great. Stay gold

Side note I am having issue building it in aws amplify but that may be diff issue aws-amplify/amplify-hosting#2318

@ghost
Copy link

ghost commented Nov 11, 2021

I'm using vite + react + amplify and I'm having the same phenomenon.
I tried the script but it didn't improve.
Is there an effective solution or workaround?

 <script>
      var global = global || window;
      var Buffer = Buffer || [];
      var process = process || {
        env: { DEBUG: undefined },
        version: []
      };
</script>

@24jr
Copy link

24jr commented Nov 12, 2021

@yogarasu this is how mine is not sure if will work different than yours

<script>
  // Need this for aws amplify to not give error...idk
	// https://github.com/aws-amplify/amplify-js/issues/7499#issuecomment-804386820
	const isBrowser = () => typeof window !== 'undefined';
	const isGlobal = () => typeof global !== 'undefined';
	var exports = {};
	if (!isGlobal() && isBrowser()) {
		var global = window;
	}
</script>

@mikhael28
Copy link

mikhael28 commented May 19, 2022

This works - Amplify team has the libraries properly switching to the browser context with Webpack, but not with Vite/Rollup.

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import resolve from "@rollup/plugin-node-resolve";
import { visualizer } from 'rollup-plugin-visualizer';

export default defineConfig({
    plugins: [
      react(),
      {
        ...resolve({
          preferBuiltins: false,
          browser: true,
        }),
        enforce: 'pre',
        apply: 'build',
      },
      visualizer()
  ],
});

ivorscott added a commit to ivorscott/saas-client that referenced this issue May 21, 2022
Vite doesn't work with aws amplify aws/aws-sdk-js#3673
@Nizari
Copy link

Nizari commented May 24, 2022

I solved this issue thanks to this post: https://stackoverflow.com/questions/70938763/build-problem-with-react-vitejs-and-was-amplify

In vite.config.js add:

resolve: {
    alias: {
      './runtimeConfig': './runtimeConfig.browser',
    },
}

@mrcego
Copy link

mrcego commented May 25, 2022

@wcheek
Copy link

wcheek commented Jun 24, 2022

I solved this issue thanks to this post: https://stackoverflow.com/questions/70938763/build-problem-with-react-vitejs-and-was-amplify

In vite.config.js add:

resolve: {
    alias: {
      './runtimeConfig': './runtimeConfig.browser',
    },
}

Thanks! This is actually what fixed the problem for me.

@justinfarrelldev
Copy link

Still having the issue even after trying all of the rest of the solutions. I've been using Vite@2.7.13 (but tried with Vite@latest as well) and React and it appears that Vite and the AWS SDK simply don't work together.

@mikhael28
Copy link

@justinfarrelldev it does... there is something about your config that isn't quite right. Please post your error messages. Delete your .lock files, update your node modules.

@elilambnz
Copy link

I solved this issue thanks to this post: https://stackoverflow.com/questions/70938763/build-problem-with-react-vitejs-and-was-amplify

Using the full config in this answer also adds the necessary polyfills for Error: AMQJS0010E WebSocket is not supported by this browser. related errors when using the Amplify PubSub library.

@shinspiegel
Copy link

I'm having the same issue with this one,
None of the work arounds helped me. My issue is related to the Cognito cannot find global object.
Does anyone have any insight on how to deal with this issue?

@clintfoster
Copy link

@shinspiegel I don't want to muddy the waters since so many good workarounds and descriptions have already been posted here, and my understanding of exactly what is going wrong is minimal. However, the following index.html hack from an earlier commenter worked for me in iterative Quasar/Vue3/Vite dev builds:

For release builds I had to implement a separate hack adapted from the following:

Since I'm using Quasar I had to make the change in quasar.config.js instead of directly in vite.config.js:

extendViteConf(viteConf, { isServer, isClient }) {
        viteConf.resolve.alias['./runtimeConfig'] = './runtimeConfig.browser'
      },

Periodically I see comments indicating the problem might have been fixed in amplify. I regularly update aws-amplify, @aws-amplify/ui-components and @aws-amplify/ui-vue. But the problem always returns if I remove the hacks.

The same goes for Vite. For example, over time I've seen comments saying a particular version fixes the problem, e.g. 2.9.9. But when I remove the hacks the problem returns.

Note: I don't have a direct dev dependency on Vite since I'm using it within Quasar's build system. Instead, I depend on @quasar/app-vite. Thus, whenever it is updated I check to see if its transitive dependency on Vite was also updated. I haven't tried directly depending on a newer version of Vite.

@bilal-korir
Copy link

bilal-korir commented Feb 3, 2023

This solution worked for me. In case you're using Astro, which uses Vite, edit astro.config.mjs as follows:

import {defineConfig} from 'astro/config'
import rollupNodePolyFill from 'rollup-plugin-node-polyfills'
import react from '@astrojs/react'
import tailwind from '@astrojs/tailwind'

export default defineConfig({
  integrations: [react(), tailwind()],
  vite: {
    optimizeDeps: {
      esbuildOptions: {
        define: {
          global: 'globalThis',
        },
      },
    },
    build: {
      rollupOptions: {
        plugins: [rollupNodePolyFill()],
      },
    },
    resolve: {
      alias: {
        './runtimeConfig': './runtimeConfig.browser',
      },
    },
  },
}) 

Orginal answer can be found here

@ccdilan
Copy link

ccdilan commented Feb 5, 2023

add alias './runtimeConfig': './runtimeConfig.browser', into vite.config.ts.

Then my vite.config.ts looks like this

plugins: [vue()],
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)),
      "./runtimeConfig": "./runtimeConfig.browser",
    },
  },
});

@RanVaknin RanVaknin added p1 This is a high priority issue p2 This is a standard priority issue and removed p1 This is a high priority issue labels Mar 27, 2023
@aliHamid98
Copy link

any one have a solution for this problem please this is very bad thing and amazon aws must solve it

@elilambnz
Copy link

@aliHamid98 a workaround has been posted above your comment for Vite which you can use until this has been resolved

@tinaboyce
Copy link

I have recently encountered the issues and attempted to try the solution above but it did not work. What worked for me is the following with a different polyfill module.

import { nodePolyfills } from 'vite-plugin-node-polyfills'

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      './runtimeConfig': './runtimeConfig.browser',
    },
  },
  build: {
    rollupOptions: {
      plugins: [nodePolyfills()],
    },
  },
  optimizeDeps: {
    esbuildOptions: {
      define: {
        global: 'globalThis',
      },
    },
  },
})

@RanVaknin
Copy link
Contributor

Hi everyone,
This issue seems to be solved with a config option for Vite, and not something we can do on the SDK side. Please upgrade to JS SDK v3 where there is an ESM distribution for bundlers.

Thanks,
Ran~

@RanVaknin RanVaknin closed this as not planned Won't fix, can't repro, duplicate, stale Jul 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. p2 This is a standard priority issue workaround-available
Projects
None yet
Development

No branches or pull requests