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

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.

  • OS: Windows 10
  • Browser: Chrome 87
  • aws-amplify 3.3.13

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 100
  • Comments: 120 (17 by maintainers)

Commits related to this issue

Most upvoted comments

YES!!! I’ve been stuck on this for days!!! Thanks to @armenr a couple comments up I was able to get things running with just ‘aws-amplify’ (haven’t tried with the components library yet) All i actually needed was to add

export default defineConfig({
  resolve: {
    alias: {
      './runtimeConfig': './runtimeConfig.browser',
    },
  },
  ...

Then i can use aws-amplify and actually have the project build as normal

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

...

Amplify.configure(configs)

...

For the record i’m using Vite, React, TS. Bootstrapped the project with the vite react template.

"vite": "2.6.12", "aws-amplify": "4.3.3"

(now I’m just waiting for something else to go wrong as I progress through adding more functionality with amplify. Hope this helps you all that are struggling)

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

@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

For @sveltejs/kit@1.0.0-next.190 with typescript@4.4.4 and @amplify/core@4.3.3 (using Node 14), the following steps worked for me.

For dev scripts, add the following to the top of the <head> tag in app.html:

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

For builds to succeed, add the following in the config.kit.vite object of svelte.config.js:

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

And for preview runs, if you face an “Amplify.configure is not a function” error, change Amplify to a named import:

import { Amplify } from '@aws-amplify/core'

@armenr solution worked for me with Vite + React + Amplify, updating index.html & vite.config.js with below

<script> if (global === undefined) { var global = window; } </script>

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

Since this is still not resolved here are a few tips: As others already mentioned, you can fix these errors by adding the following config to vite.config.js

define: {
  global: {}, //fix dev build
},
resolve: {
  alias: {
    "./runtimeConfig": "./runtimeConfig.browser", //fix production build
  },
},

The above configuration will FAIL if you’re using React Router 6.4 data API.

import {createBrowserRouter, RouterProvider} from "react-router-dom";

const router = createBrowserRouter([
  {
    index: true,
    element: <Landing />,
  }
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

You will have to stick to using React Router components.

<BrowserRouter>
  <Routes>
    <Route index element={<Landing />} />
  </Routes>
</BrowserRouter>

Hope this helps some poor soul. God knows how much time I wasted figuring this out.

@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();
  }
}

I had to update my Vite config to the following to get both build time & dev working (only the relevant parts of the config are included):

export default defineConfig({
  ...(process.env.NODE_ENV === 'development'
    ? {
      define: {
        global: {},
      },
    }
    : {}),
  resolve: {
    alias: {
      ...(process.env.NODE_ENV !== 'development'
        ? {
          './runtimeConfig': './runtimeConfig.browser', //fix production build
        }
        : {}),
    },
  },
});

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',

We are working on removing the need for these manual configurations on Amplify, for now - for Vite customers can you try the workaround mentioned in this comment to see if that resolves build issues for you? https://github.com/kevinold/repro-vite-amplify/commit/4d6b42291dbbcc9cee08f0ec52b416efd5ed7145

I’ve been fighting this one for a few days and finally got it to work. This is what worked for me for vite and react.

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

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

Please don’t close this ticket without fixing the underlining issue.

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)

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.

configuring like this worked for me.

vite.config.js

export default defineConfig({ plugins: [vue()], resolve: { alias: { “./runtimeConfig”: “./runtimeConfig.browser”, //fix production build } } })

@armenr solution worked for me with Vite + React + Amplify, updating index.html & vite.config.js with below

<script> if (global === undefined) { var global = window; } </script>

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

This solution also works in SvelteKit as well. Adding the resolve bit to the svelte.config.js file and adding the <script> tag to the app.html file (above all your other files) fixed everything!

svelte.config.js

import adapter from '@sveltejs/adapter-auto';

const config = {
	resolve: {
		alias: {
			'./runtimeConfig': './runtimeConfig.browser',
		},
	},
	kit: {
		adapter: adapter()
	}
};

export default config;

and the app.html file

<head>
		<meta charset="utf-8" />
		<meta name="description" content="" />
		<link rel="icon" href="%svelte.assets%/favicon.png" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />

		<script>
			// This is required for AWS Amplify
			if (global === undefined) {
				var global = window;
			}
		</script>

<!-- ... All your other standard svelte stuff here -->
</head>

And depending on your specific setup, don’t forget to add your aws-exports.js file. Mine looks like this:

const urlBase = "https://www.your-domain.com";
const hostname = "your-domain.com";

const awsconfig = {
    aws_project_region: "region",
    aws_cognito_region: "region",
    aws_user_pools_id: "user-pool-id",
    aws_user_pools_web_client_id: "cliend-id",
    oauth: {
        domain: "domain",
        scope: ["email", "openid", "aws.cognito.signin.user.admin"],
        redirectSignIn: `${urlBase}/`,
        redirectSignOut: `${urlBase}/login`,
        responseType: "code",
        client_id: "client-id",
    },
    cookieStorage: {
        domain: hostname,
        secure: false,
        path: "/",
        expires: 0.0416, // one hour (in fractions of a day)
    },
};

export default awsconfig;

and then in my __layout.svelte file, I added:

import Amplify, { Auth } from 'aws-amplify';
import awsconfig from '$lib/aws-exports';
Amplify.configure(awsconfig);

Still having trouble with Build

This works fine locally. I’m able to log in, log out, do all that fun stuff.

When I go to build the Sveltekit project with npm run build, I get this error:

✓ 1974 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: C:/project.../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
    at error (C:\project...\node_modules\rollup\dist\shared\rollup.js:198:30)
    at Module.error (C:\project...\node_modules\rollup\dist\shared\rollup.js:12477:16)
    at Module.traceVariable (C:\project...\node_modules\rollup\dist\shared\rollup.js:12835:29)
    at ModuleScope.findVariable (C:\project...\node_modules\rollup\dist\shared\rollup.js:11465:39)
    at FunctionScope.findVariable (C:\project...\node_modules\rollup\dist\shared\rollup.js:6433:38)
    at ChildScope.findVariable (C:\project...\node_modules\rollup\dist\shared\rollup.js:6433:38)
    at FunctionScope.findVariable (C:\project...\node_modules\rollup\dist\shared\rollup.js:6433:38)
    at ChildScope.findVariable (C:\project...\node_modules\rollup\dist\shared\rollup.js:6433:38)
    at Identifier.bind (C:\project...\node_modules\rollup\dist\shared\rollup.js:7724:40)
    at CallExpression.bind (C:\project...\node_modules\rollup\dist\shared\rollup.js:5298:23)

YES!!! I’ve been stuck on this for days!!! Thanks to @armenr a couple comments up I was able to get things running with just ‘aws-amplify’ (haven’t tried with the components library yet) All i actually needed was to add

export default defineConfig({
  resolve: {
    alias: {
      './runtimeConfig': './runtimeConfig.browser',
    },
  },
  ...

Then i can use aws-amplify and actually have the project build as normal

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

...

Amplify.configure(configs)

...

For the record i’m using Vite, React, TS. Bootstrapped the project with the vite react template.

"vite": "2.6.12", "aws-amplify": "4.3.3"

(now I’m just waiting for something else to go wrong as I progress through adding more functionality with amplify. Hope this helps you all that are struggling)

Thank you, work for me

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?

Temporary workaround that WORKS!

Tl;dr

Go to my example repo: https://github.com/armenr/amplify-vitesse-repro

Howdy folks! I’ve got a working setup for aynone that’s trying to get @aws-amplify/ui-components working with VITE + Vue3 - but it’s just slightly hacky, and I stumbled upon it TOTALLY by chance.

Wanna give a shout out to @ErikCH for:

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

Wanna give another shoutout to @simlevesque for:

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

Are you ready kids?! (SpongeBob reference - feel free to disregard).

Notes before you dive in

I am working off of an increasingly popular (and honestly AMAZING) starter template called Vitesse

Why do I love vitesse? (recommend you go to the repo and see the readme for more extensive details)

  • really solid plugins included (and they are well supported/active)
  • extremely flexible
  • extremely fast
  • extremely productive
  • Supports SSR, SPA, and SSG…all with zero-config PWA (out of the box, no configs required)
  • +1 --> I got it working with Amplify

Amplify-related caveats of Vitesse that I’ve discovered

  • Use YARN in your build pipeline instead of pnpm (easy to do by including your own amplify.yml file in your repo)
  • Setting up your project this way (to get amplify-js + amplify-ui-components working) will break SSG builds, but I’m working on patching that too

Solution

Step 1: vite.config.ts

You need to add the the ./runtimeConfig alias

  resolve: {
    alias: {
      '~/': `${path.resolve(__dirname, 'src')}/`,
      './runtimeConfig': './runtimeConfig.browser',
    },
  },

You need to add vue --> template --> compiler options

      template: {
        compilerOptions: {
          isCustomElement: tag => tag.startsWith('amplify-'),
          sourceMap: true,
        },
      },

Added this, but not sure if it’s needed (please help me test if you’d like!):

// In your imports section

import resolve from '@rollup/plugin-node-resolve'

// in your vite defineConfig --> plugins section
    resolve({
      browser: true,
      preferBuiltins: false, // new!
    }),

My entire config -->

import path from 'path'
import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'
import Markdown from 'vite-plugin-md'
import Pages from 'vite-plugin-pages'
import Prism from 'markdown-it-prism'
import { VitePWA } from 'vite-plugin-pwa'
import WindiCSS from 'vite-plugin-windicss'
import Layouts from 'vite-plugin-vue-layouts'
import resolve from '@rollup/plugin-node-resolve'
import ViteComponents, { HeadlessUiResolver /* PrimeVueResolver */ } from 'vite-plugin-components'
import VueI18n from '@intlify/vite-plugin-vue-i18n'
import ViteIcons, { ViteIconsResolver } from 'vite-plugin-icons'

// @ts-expect-error missing types
import LinkAttributes from 'markdown-it-link-attributes'

const markdownWrapperClasses = 'prose prose-sm m-auto text-left'

// ViteConfig
export default defineConfig({
  resolve: {
    alias: {
      '~/': `${path.resolve(__dirname, 'src')}/`,
      './runtimeConfig': './runtimeConfig.browser',
    },
  },

  // Load plugins
  plugins: [
    resolve({
      browser: true,
      preferBuiltins: false, // new!
    }),

    Vue({
      include: [/\.vue$/, /\.md$/],
      template: {
        compilerOptions: {
          isCustomElement: tag => tag.startsWith('amplify-'),
          sourceMap: true,
        },
      },
    }),

    // https://github.com/hannoeru/vite-plugin-pages
    Pages({
      extensions: ['vue', 'md'],
    }),

    // https://github.com/JohnCampionJr/vite-plugin-vue-layouts
    Layouts(),

    // https://github.com/antfu/vite-plugin-md
    Markdown({
      wrapperClasses: markdownWrapperClasses,
      headEnabled: true,
      markdownItSetup(md) {
        // https://prismjs.com/
        md.use(Prism)
        md.use(LinkAttributes, {
          pattern: /^https?:\/\//,
          attrs: {
            target: '_blank',
            rel: 'noopener',
          },
        })
      },
    }),

    // https://github.com/antfu/vite-plugin-components
    ViteComponents({
      // allow auto load markdown components under `./src/components/`
      extensions: ['vue', 'md'],

      // allow auto import and register components used in markdown
      customLoaderMatcher: id => id.endsWith('.md'),

      // generate `components.d.ts` for ts support with Volar
      globalComponentsDeclaration: true,

      // auto import icons
      customComponentResolvers: [
        // PrimeVueResolver(),
        HeadlessUiResolver(),
        // https://github.com/antfu/vite-plugin-icons
        ViteIconsResolver({
          componentPrefix: '',
          // enabledCollections: ['hero'],
        }),
      ],
    }),

    // https://github.com/antfu/vite-plugin-icons
    ViteIcons(),

    // https://github.com/antfu/vite-plugin-windicss
    WindiCSS({
      safelist: markdownWrapperClasses,
    }),

    // https://github.com/antfu/vite-plugin-pwa
    VitePWA({
      registerType: 'autoUpdate',
      includeAssets: ['favicon.svg', 'robots.txt', 'safari-pinned-tab.svg'],
      manifest: {
        name: 'Beep',
        short_name: 'BeepBeep',
        theme_color: '#ffffff',
        icons: [
          {
            src: '/pwa-192x192.png',
            sizes: '192x192',
            type: 'image/png',
          },
          {
            src: '/pwa-512x512.png',
            sizes: '512x512',
            type: 'image/png',
          },
          {
            src: '/pwa-512x512.png',
            sizes: '512x512',
            type: 'image/png',
            purpose: 'any maskable',
          },
        ],
      },
    }),

    // https://github.com/intlify/vite-plugin-vue-i18n
    VueI18n({
      runtimeOnly: true,
      compositionOnly: true,
      include: [path.resolve(__dirname, 'locales/**')],
    }),
  ],

  // Server conifg
  server: {
    fs: {
      strict: true,
    },
  },

  // Build settings
  // build: {
  //   polyfillDynamicImport: true,
  //   sourcemap: true,
  //   rollupOptions: {
  //     shimMissingExports: true,
  //     output: {
  //       manualChunks: undefined,
  //       inlineDynamicImports: true,
  //     },
  //   },
  // },

  // https://github.com/antfu/vite-ssg
  ssgOptions: {
    script: 'async',
    formatting: 'minify',
  },

  // OptimizeDeps build settings
  optimizeDeps: {
    include: ['vue', 'vue-router', '@vueuse/core'],
    exclude: ['vue-demi'],
  },
})

./modules/Amplify.ts

So, in Vitesse, there’s a concept of “modules” that is similar to “boot” files in the Quasar framework.

I created a “module” to load up Amplify on App boot, and this is where I use @simlevesque’s import workaround

import Amplify from 'aws-amplify'

import {
  applyPolyfills,
  // defineCustomElements,
} from '@aws-amplify/ui-components/loader'

import { defineCustomElements } from '@aws-amplify/ui-components/dist/components/index'

// @ts-expect-error missing types
import awsmobile from './../aws-exports'
import { UserModule } from '~/types'

export const install: UserModule = async({ app }) => {
  // NOTE: "await" might not be doing anything useful here, at all
  // TODO: Revisit/refactor this
  await Amplify.configure(awsmobile)
  await applyPolyfills()
  await defineCustomElements(window)

  // NOTE: Uncertain if this is necessary
  // TODO: Revisit, test, and remove if not necessary
  app.config.compilerOptions.isCustomElement = tag => tag.startsWith('amplify-')
}

Still not working! What happens next?

Once you get THIS far, you’ll see three IMPORTANT errors in your console/terminal

Error in console/terminal refers to @stenciljs/core missing a require/export

We install @stencil/core directly into our project --> pnpm install @stencil/core

Error in console/terminal refers to zen-observable missing a default export

pnpm install https://github.com/abdonrd/zen-observable

Here, we’re installing a fork for zen-observable directly from a fork on GitHub that has a pending PR that the zen-observable maintainers are ignoring (the PR for this branch is neglected, but it works!)

Error in console/terminal refers to buffer library

Add package resolution overrides for buffer in package.json (example covers pnpm and yarn)

  "pnpm": {
    "overrides": {
      "buffer": "^6.0.3"
    }
  },
  "resolutions": {
    "buffer": "^6.0.3"
  }

Final steps --> clear out your node_modules and re-install everything

  1. rm -rf node_modules in your project or your monorepo package folder
  2. pnpm install or yarn or whatever package manager you’re using

Results:

Screen Shot 2021-08-01 at 3 08 35 PM

@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.

@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.

The best way is to get rid of amplify and roll your own wrapper around amazon-cognito-identity-js, tbh.

We are working on removing the need for these manual configurations on Amplify, for now - for Vite customers can you try the workaround mentioned in this comment to see if that resolves build issues for you? kevinold/repro-vite-amplify@4d6b422

To say that this is annoying would be an understatement.

This is a horrible developer experience. The least you could do is make this lack of integration support known up front so we don’t waste our time on another amplify product.

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

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,
      },
    },
  },
});

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

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

still getting this for me:

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

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

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

thanks this worked for me

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

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.

ugh whatever I’m going back to CRA then.

npm install --save-dev rollup-plugin-polyfill-node vite.config.js


import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import nodePolyfills from "rollup-plugin-polyfill-node";
export default defineConfig({
  plugins: [react()],

  define: {
    global: {},
  },
  resolve: {
    alias: {
      "./runtimeConfig": "./runtimeConfig.browser",
    },
  },
  build: {
    rollupOptions: {
      plugins: [nodePolyfills()],
    },
  },
});

We are working on removing the need for these manual configurations on Amplify, for now - for Vite customers can you try the workaround mentioned in this comment to see if that resolves build issues for you? kevinold/repro-vite-amplify@4d6b422

I confirm this works in Sveltekit with ‘@aws-amplify/api’, ‘@aws-amplify/auth’, ‘@aws-amplify/core’ 🙏🏼

@mgerring We ended up replacing it (and eventually replacing Amplify), it isn’t a hugely horrible thing to do, took us about a day though we don’t cover all states. There are a many other reasons other than this ticket to not use @aws-amplify/ui-react and also Amplify entirely.

The sooner you migrate to a lightweight promise based wrapper around the parts of amazon-cognito-identity-js you actually need, the sooner your headaches will disappear 😃

I still saw it with:

    "aws-amplify": "6.0.9",
    "@aws-amplify/ui-react": "6.0.7",

adding the following to vite.config.ts solves it:

  optimizeDeps: {
    esbuildOptions: {
      define: {
        global: 'globalThis',
      },
    },
  },

Without this change, it still fails and the error clearly points to @aws-amplify/ui-react: Screenshot 2024-01-01 at 13 42 36 Screenshot 2024-01-01 at 13 43 08

I was told during Amplify Office Hours that v6 introduced a fix for Vite environments that removes the need to add this resolve config:

resolve: {
      alias: {
        "./runtimeConfig": "./runtimeConfig.browser", //fix production build
      }
    }

The release of v6 may or may not address everything discussed in this issue, but it felt appropriate to share this update here.

Still open in 2023 with newest Quasar (vite). and newest amplify:

Tried to use rollup-plugin-polyfill-node but quasar.config.js runs in a node env. so I can’t import it. require does not work either. Any ideas to manage it with quasar and vite somehow ?

This is the origin error when I run npx quasar build : 'request' is not exported by __vite-browser-external, imported by node_modules/@aws-sdk/client-cloudwatch-logs/node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js file: /Users/sc/dev/artbarrack/code/node_modules/@aws-sdk/client-cloudwatch-logs/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 /Users/sc/dev/artbarrack/code/node_modules/rollup/dist/shared/rollup.js:198 base = Object.assign(new Error(base.message), base);

This also affects many vite-plugin-ssr users.

I had to update my Vite config to the following to get both build time & dev working (only the relevant parts of the config are included):

export default defineConfig({
  ...(process.env.NODE_ENV === 'development'
    ? {
      define: {
        global: {},
      },
    }
    : {}),
  resolve: {
    alias: {
      ...(process.env.NODE_ENV !== 'development'
        ? {
          './runtimeConfig': './runtimeConfig.browser', //fix production build
        }
        : {}),
    },
  },
});

I got both dev and prod builds working with @ffxsam 's solution - thanks!

My whole vite.config.ts (with Vuetify):

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath } from 'url'
import vuetify from 'vite-plugin-vuetify'

// https://vitejs.dev/config/
export default defineConfig({
  ...(process.env.NODE_ENV === 'development'
    ? {
      define: {
        global: {},
      },
    }
    : {}),
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)),
      ...(process.env.NODE_ENV !== 'development'
        ? {
          './runtimeConfig': './runtimeConfig.browser', //fix production build
        }
        : {}),
    },
  },
  plugins: [vue(), vuetify({ autoImport: true })],
})

Polyfilling node APIs worked for me.

Rollup plugin mentioned here might be worth looking at.

Hey all, I don’t know if this helps, but I paid someone to come up with a solution so that AWS Amplify would work within Nuxt 3 (which uses Vite under the hood).

This is the code he wrote. This is way over my head, but it looks like it’s a custom Vite plugin. BTW, this is just a workaround until AWS fixes stuff on their end. I’ve talked with the Amplify team, and they fully intend to update their SDK to use some of the more modern features of Node.js like import/export maps, and using proper ESM, which will fix these issues.

import { pathToFileURL } from 'url';
import { defineNuxtModule } from '@nuxt/kit';
import { parseURL } from 'ufo';
import { dirname, join } from 'pathe';

export default defineNuxtModule({
  meta: {
    name: 'nuxt-amplify',
  },
  setup(_options, nuxt) {
    nuxt.options.build.transpile.push(
      'aws-amplify',
      /@aws-sdk/,
      /@aws-amplify/,
    );
    nuxt.hook('vite:extendConfig', (config, { isClient }) => {
      if (!isClient) return;

      config.plugins = config.plugins || [];
      config.plugins.push({
        name: 'nuxt:aws-browser',
        enforce: 'pre',
        resolveId(id, importer) {
          if (
            !importer ||
            !importer.includes('node_modules') ||
            !importer.includes('aws')
          ) {
            return;
          }
          const path = isRelative(id) ? join(dirname(importer), id) : id;
          const { pathname, search } = parseURL(
            decodeURIComponent(pathToFileURL(path).href),
          );
          if (pathname.endsWith('runtimeConfig') && !id.includes('browser')) {
            return pathname + '.browser.js' + search;
          }
        },
      });
    });
  },
});

const IS_RELATIVE_RE = /^\.{1,2}\//;
function isRelative(id: string) {
  return IS_RELATIVE_RE.test(id);
}

https://github.com/aws/aws-sdk-js/issues/3673 seems to be along similar issues. I too am seeking solutuin for sveltekit + aws-amplify and using I believe the correct “adapter” (new to this part) but as mentioned in the linked issue https://ui.docs.amplify.aws/ui/getting-started/installation?platform=vue seams to have a soltution for vite in vue but of course svelte has its own way of doing this. Does anyone know the “translation” of this to sveltekit?

I have in my app.html

<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>

which seems equivalent to their recommended vue index.html of

<script>
        window.global = window;
        var exports = {};
  </script>

Next the config. I have in my svelte.config.js which i added adapter-node (which again im new to) https://github.com/sveltejs/kit/tree/master/packages/adapter-node

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

// export default 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'
			}
		})
	}
};

The amplify fixes for vue vite say make vite.config.ts

export default defineConfig({
  plugins: [vue()],
  resolve: {
      alias: [
      {
        find: './runtimeConfig',
        replacement: './runtimeConfig.browser',
      },
    ]
  }
})

I’m not sure what the translation to svelte.config.js would be

Then lastly they add to tsconfig.json

...
  "compilerOptions": {
    "skipLibCheck": true,
...

Appreciate all help and people that have figured this stuff out thus far

@ErikCH and for anyone else who might find it useful --> here’s a reproducible sample repo

https://github.com/armenr/amplify-vitesse-repro

ping - added feature-request label so stalebot skips.

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

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

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.

@TeoTN thanks for your feedback, it seems that it may be specific to the UI library. Will do additional testing and confirm.

With the release of the latest major version of Amplify (aws-amplify@>6), this issue should now be resolved! Please refer to our release announcement, migration guide, and documentation for more information.

If you are still facing this issue after upgrading to v6, please let us know with a reply back.

Good to hear! It seems like this issue might be solved/closable if it resolved this issue.

I was told during Amplify Office Hours that v6 introduced a fix for Vite environments that removes the need to add this resolve config:

resolve: {
      alias: {
        "./runtimeConfig": "./runtimeConfig.browser", //fix production build
      }
    }

The release of v6 may or may not address everything discussed in this issue, but it felt appropriate to share this update here.

@charlieforward9 v6 works perfectly out of the box with SvelteKit, just tested it today, but there’s another problem with SSR, which I don’t know how to solve yet, described it here: https://github.com/aws-amplify/amplify-js/issues/12578 .

There’s no more withSSRContext, so I need to figure out how to get cognitoUser on the server side… Otherwise, v6 looks good to me.

For Quasar I had to add it to the build section in quasar.config.js (extending the vite config didn’t work).

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

The missing global definitions is added directly inside index.html

    <script>
      /* https://ui.docs.amplify.aws/vue/getting-started/troubleshooting */
      window.global = window;
      var exports = {};
    </script>

We are working on removing the need for these manual configurations on Amplify, for now - for Vite customers can you try the workaround mentioned in this comment to see if that resolves build issues for you? kevinold/repro-vite-amplify@4d6b422

Thanks! this helped, here’s my vite.config.vue

import { fileURLToPath, URL } from "node:url";

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  define: {
    global: {},
  },
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)),
      "./runtimeConfig": "./runtimeConfig.browser",
    },
  },
});

@mkilp, I just went through the same path of converting from CRA to Vite. Same issues, dev worked, production build crashed with error about Crypto. I also tried some of the various npm poly fill packages I see that you have as well.

I ended up doing a clean Vite install with a new amplify project and moved my project over piece by piece. Then copied the vite.config.js back to my original project. Below is my vite.config.js file. It turned out to be much simpler setup than all the various things I tried. I think that a lot of the poly fill packages were used for earlier versions of vite/amplify and are no longer needed. (I think, not sure about that)

Note: the setupTests.js file in the test section @imports testing-library/jest-dom for vitest.

And I also, deleted npm_modules and the package-lock.json file to make sure the setup was clean as possible. I had other issues from the package-lock.json file so I don’t know if it effected the vite config.

It has been working fine for about a mouth with several deploys to production. Although it was so much more work than I expected, I am happy I did it.

Hope this will help.

Regards,

vite.config.js

import { defineConfig } from ‘vite’ import react from ‘@vitejs/plugin-react’ import rollupNodePolyFill from “rollup-plugin-node-polyfills”;

// https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], define: { ‘process.env’: {} }, optimizeDeps: { esbuildOptions: { // Node.js global to browser globalThis define: { global: “globalThis”, //<-- AWS SDK }, }, }, build: { rollupOptions: { plugins: [ // Enable rollup polyfills plugin // used during production bundling rollupNodePolyFill(), ], }, }, test: { globals: true, setupFiles: ‘setupTests.js’, }, resolve: { alias: { ‘./runtimeConfig’: ‘./runtimeConfig.browser’, // <-- Fix from above }, } })

@pedersenderekserif - we understand this is not ideal, and are actively working on removing the need for additional configurations when using our library. We have also enriched our documentation with the steps you would need to get started with a Vue/Vite project.

@abdallahshaban557 Yes this worked for me with aws-amplify 3.3.7, i.e., quite an old version.

@dancingfrog Thanks for that solution, it is working for me for vite build, however for local dev there is a console error thrown Uncaught ReferenceError: aws_amplify is not defined. Did you get it to work for your dev server?

Edit: disregard my question, it was due to outDir being set to “…/dist” and not having access to the upper folder in dev mode

Thank you @armenr.

@armenr Awesome! Thanks for the great work around!

@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?