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

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

Closed sem4phor closed 6 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.

siegerts commented 3 years ago

ping - added feature-request label so stalebot skips.

jarrodu commented 3 years ago

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

mgerring commented 3 years ago

I have the same issue as @radiosilence -- looks like there are workarounds for everything except for @aws-amplify/ui-react. Replacing the authentication UI components isn't in scope for us for now, so we're stuck for the time being.

radiosilence commented 3 years ago

@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 :)

charles-stuart-appdetex commented 3 years ago

@radiosilence is amazon-cognito-identity-js deprecated though, or did it just get moved? I find varying information on it.

armenr commented 3 years ago

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)

Amplify-related caveats of Vitesse that I've discovered

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

ErikCH commented 3 years ago

@armenr Awesome! Thanks for the great work around!

armenr commented 3 years ago

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

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

Robert-Nickel commented 2 years ago

@armenr I encounter the same issue while trying to use vite + svelte + amplify (for auth), can you/someone hint me towards solving the configuration puzzle there? What is the equivalent to "add vue --> template --> compiler options" in svelte?

jarrodu commented 2 years ago

Maybe they will fix the issue soon. It looks like they have been working on it. I found this thread in March and have postponed a project because of it.

radiosilence commented 2 years ago

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

chovyprognos commented 2 years ago

What goes in this runtimeConfig.js file??? I'm using svelte kit.

kaleabmelkie commented 2 years ago

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'
chovyprognos commented 2 years ago

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 commented 2 years ago

@chovyprognos , if you'd like to check I put an ssr repo for sveltekit + amplify (https://github.com/adnansmajlovic/svk-amplify-ssr), but there's also one for spa there too. I use svk + amplify in production, and all works perfect.

RussMax783 commented 2 years ago

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)

sem4phor commented 2 years ago

Nice to hear @RussMax783 . As I started the issue this repository was amplify-js and not amplify-ui. Glad to see things improve!

24jr commented 2 years ago

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

cesswhite commented 2 years ago

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

DomWeldon commented 2 years ago

Unfortunately this didn't work for me, but this slight hack did...

try {
    Amplify.configure(cfg);
} catch (e) {
    // did it error because node defaults were used?
    if (e.name == "TypeError") {
        // @ts-ignore
        Amplify.default.configure(cfg);
    } else {
        throw e;
    }
}
curiosity26 commented 2 years ago

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',
    },
  ],
})
sam-frampton commented 2 years ago

@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' } }

zvoss-eb commented 2 years ago

@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)
micksatana commented 2 years ago

Got it works in

By putting this in app.html

<script>
      const isBrowser = () => typeof window !== 'undefined';
      const isGlobal = () => typeof global !== 'undefined';
      if (!isGlobal() && isBrowser()) {
        var global = window;
      }
</script>

And svelte.config.js

import adapter from '@sveltejs/adapter-cloudflare';
import preprocess from 'svelte-preprocess';

/** @type {import('@sveltejs/kit').Config} */
const config = {
  preprocess: preprocess({
    postcss: true
  }),
  kit: {
    adapter: adapter(),
    floc: true,
    alias: {
      $assets: 'src/assets',
      $components: 'src/components',
      $pages: 'src/pages',
      $routes: 'src/routes',
      $stores: 'src/stores'
    },
    vite: {
      resolve: {
        alias: {
          './runtimeConfig': './runtimeConfig.browser'
        }
      }
    }
  }
};

export default config;

In __layout.svelte

<script lang="ts">
  import '../app.css';
  import NavigationBar from '$components/NavigationBar.svelte';
  import { onMount } from 'svelte';
  import { Auth } from 'aws-amplify';
  import { IdentityPoolId, Region, UserPoolId, UserPoolWebClientId } from '$stores/constants';

  onMount(async () => {
    Auth.configure({
      identityPoolId: IdentityPoolId,
      userPoolId: UserPoolId,
      userPoolWebClientId: UserPoolWebClientId,
      region: Region,
      identityPoolRegion: Region
    });

    const creds = await Auth.currentCredentials();

    console.log('creds', creds);
  });
</script>

Confirmed it can npm run dev, npm run build and deploy on CloudFlare Pages without an issue.

You need to have @aws-sdk/client-cognito-identity installed along with aws-amplify else it will have issues like Could not resolve "@aws-sdk/protocol-http".... etc.

penairdes commented 2 years ago

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

I am using Vite + React + Amplify

I was abe to do a build and publish the site, however, When loading the site I get the following error in the browser: Uncaught TypeError: Cannot read properties of undefined (reading 'memoizedProperty') at index.6c2d94c0.js:2603:8441

I don't get this error in development.

vite.config.ts

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

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      './runtimeConfig': './runtimeConfig.browser'
    }
  },
  build: {
    rollupOptions: {
      plugins: [
        nodeResolve({
          browser: true,
          preferBuiltins: false
        }),
        json()
      ]
    }
  }
})

I do use aws-sdk-v3 packages within the project. Not sure what is causing the memoizedProperty error

paragvk commented 2 years ago

Do we have a proper solution two years after? Its probably causing lot of projects to reject AWS Cognito (potentially also other AWS services) from tech stack.

armenr commented 2 years ago

@paragvk - doesn't look like it, yet. But I did post a way to work around it, discussed above ^^^

It seems to have worked/keep working for a number of people.

ffxsam commented 2 years ago

Running into this issue with Nuxt 3, creating my own plugin (client-only) to use AppSync:

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

export default defineNuxtPlugin(() => {
  const {
    public: {
      awsRegion,
      graphqlEndpoint,
      identityPoolId,
      userPoolId,
      userPoolClientId,
    },
  } = useRuntimeConfig();

  Amplify.configure({
    aws_appsync_graphqlEndpoint: graphqlEndpoint,
    aws_appsync_region: awsRegion,
    aws_appsync_authenticationType: 'AWS_IAM',

    Auth: {
      identityPoolId,
      region: awsRegion,
      userPoolId,
      userPoolWebClientId: userPoolClientId,
      mandatorySignIn: false,
    },
  });

  return {
    provide: { API },
  };
});

Build output:

Nuxt CLI v3.0.0-rc.4                                                  18:43:56
ℹ Vite client warmed up in 5594ms                                     18:44:04

 ERROR  'request' is not exported by __vite-browser-external, imported by nuxt/node_modules/@aws-sdk/credential-provider-node/node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js
file: /Volumes/SuperData/Sites/reelcrafter/v2-presentation-nuxt3/nuxt/node_modules/@aws-sdk/credential-provider-node/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
dancingfrog commented 2 years ago

For my Svelte/Vite build none of the above work-arounds actually worked, but replacing import with require/assign does (and yes, a node resolve is already built-in to vite, so no need for the additional plugin):

// import Amplify from 'aws-amplify';
// import { API, graphqlOperation } from "aws-amplify";
 const awsAmplify = require('aws-amplify');
 const Amplify = awsAmplify.default;
 const API = awsAmplify.API;
 const graphqlOperation = awsAmplify.graphqlOperation;
dancingfrog commented 2 years ago

For my Svelte/Vite build ...

Yeah, npm run dev AND npm run build works, but if I try to serve the static build assets I get an error in the browser, so it's a no-go:

Uncaught ReferenceError: require is not defined    <anonymous> http://localhost:5000/assets/index.67fd2eab.js:24
[index.67fd2eab.js:24:6](http://localhost:5000/assets/index.67fd2eab.js)
    <anonymous> http://localhost:5000/assets/index.67fd2eab.js:24
    InnerModuleEvaluation self-hosted:2361
    evaluation self-hosted:2322

This is definitely the problem...

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

Hopefully the aws-sdk team jumps on this in the nearish future!

tamirble commented 2 years ago

Thank you @armenr.

dancingfrog commented 2 years ago

For my Svelte/Vite build ... ...

Uncaught ReferenceError: require is not defined    <anonymous> http://localhost:5000/assets/index.67fd2eab.js:24
...

I'm hitting this same issue of unresolved references to "require", even when there are no such references in my source code, whenever I use import to include aws-amplify or directly include a specific @aws-sdk library (i.e., import { API } from '@aws-amplify/api/lib-esm') in main.jsx/main.js (React/Svelte respectively), even when I include this in my vite.config.js file:

      resolve: {
         alias: [
             // {
             //     find: '@', replacement: resolve(__dirname, './src'),
             // },
             {
                 find: './runtimeConfig', replacement: './runtimeConfig.browser',
             }
         ]
    }

^ That helps npm run build to complete, but does not resolve the mechanisms to require non-ESM dependencies that are buried in the various @aws-sdk/... libraries.

So, I personally have not successfully implemented any of the work-arounds above (including my own) for compiling/transpiling the npm version of aws-amplify into the js bundle output by Vite, but I have discovered that there is way to integrate the CDN version of the library that is included in the npm package (node_modules/aws-amplify/dist/aws-amplify[.min].js).

Here are the relevant fragments from my configuration and source code files....

package.json:

"dependencies": {
    "@aws-amplify/cli": "^9.1.0",
    "aws-amplify": "^4.3.29",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    ...
  },
  "devDependencies": {
    "@guanghechen/rollup-plugin-copy": "^1.9.8",
    "@rollup/plugin-node-resolve": "^13.3.0",
    "@vitejs/plugin-react": "^2.0.0",
    "@vitejs/plugin-react-refresh": "^1.3.6",
    ...
    "vite": "^3.0.4"
  },

vite.config.js:

import { defineConfig } from 'vite';
import copy from '@guanghechen/rollup-plugin-copy';
import nodeResolve from '@rollup/plugin-node-resolve';
import react from '@vitejs/plugin-react';
...

// https://vitejs.dev/config/
export default defineConfig({
  external: [ 'aws_amplify', 'Buffer', 'CustomEvent' ],
  ...
  plugins: [
    ...

    copy({
      hook: 'buildStart',
      targets: [
        { src: [ './node_modules/aws-amplify/dist/aws-*' ], dest: 'public/' }
      ]
    }),

    nodeResolve({
      browser: true,
      preferBuiltins: false,
      // dedupe: importee =>
      //     importee === 'svelte' || importee.startsWith('svelte/')
    }),

    react(), // svelte()
  ]
})

index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    ...

    <script src="/aws-amplify.min.js" ></script>

    <script>
        const isBrowser = () => typeof window !== 'undefined';
        const isGlobal = () => typeof global !== 'undefined';
        if (!isGlobal() && isBrowser()) {
            var global = window;
        }
    </script>
  </head>
  <body>
    ...

    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

main.jsx:

import aws_exports from "./aws-exports";

...

// import Amplify from '@aws-amplify/core/lib-esm';                  // <- DOES NOT RESOLVE require()
// import { API, graphqlOperation } from '@aws-amplify/api/lib-esm'; // <- DOES NOT RESOLVE require()
// const aws_amplify = require('@aws-amplify/core/src');             // <- DOES NOT RESOLVE require()
const Amplify = aws_amplify.default;                                 // aws_amplify is now a global var
const API = aws_amplify.API;
const graphqlOperation = aws_amplify.graphqlOperation;

Amplify.configure(aws_exports);
...
ffxsam commented 2 years ago

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);
}
emmmarosewalker commented 2 years ago

@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

dancingfrog commented 2 years ago

@emmmarosewalker

I think that means that the dev server is not sourcing aws-amplify.min.js from your public folder, so can you confirm that the file that you reference in index.html is present in public?

On another note, the resolve: { alias: [ ... ] } work-around is now working for me because I changed the structure and versions of dependencies that I am pulling in via package.json, after reading these issues about the recurring conflicts between the monolithic aws-amplify package and the various @aws-amplify/... modular packages (essentially we need to choose to depend on one or the other, not both): #2885 #7619. So, I dropped the CDN version of aws-amplify from index.html/public and I'm currently using this (modular + working) setup...

package.json:

...
  "dependencies": {
    "aws-amplify-react": "~5.1.9",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@aws-amplify/analytics": "~3.3.11",
    "@aws-amplify/api": "~3.3.3",
    "@aws-amplify/api-graphql": "~1.3.3",
    "@aws-amplify/api-rest": "~1.2.34",
    "@aws-amplify/auth": "~3.4.34",
    "@aws-amplify/cache": "~4.0.50",
    "@aws-amplify/core": "~3.8.24",
    "@aws-amplify/interactions": "~3.3.34",
    "@aws-amplify/storage": "~3.4.4",
    "@aws-amplify/ui": "~2.0.5",
    "@aws-amplify/ui-components": "~1.7.2",
    "@aws-amplify/ui-react": "~2.20.0",
    "@aws-amplify/xr": "~2.2.34",
    "@aws-sdk/credential-provider-cognito-identity": "^3.145.0",
    "@types/react": "^18.0.15",
    "@types/react-dom": "^18.0.6",
    "@vitejs/plugin-react": "^2.0.0",
    "esbuild": "^0.14.54",
    "vite": "^3.0.0"
  },
...

(... most of the @aws-amplify/... modules included are dependencies of aws-amplify-react and/or @aws-amplify/ui-react; as you will see I am using React components from aws-amplify-react and only importing styles from @aws-amplify/ui-react)

vite.config.js:

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

// https://vitejs.dev/config/
export default defineConfig({
    // set external namespaces to help `npm run build` succeed
    external: [
        'aws_amplify', 'aws_amplify_core', 'aws_amplify_react', 'Buffer', 'CustomEvent'
    ],
    plugins: [
        react()
    ],
    resolve: {
        alias: [
            // {
            //     find: '@', replacement: resolve(__dirname, './src'), // <- just to illustrate how to set multiple alias entries
            // },
            {
                find: './runtimeConfig', replacement: './runtimeConfig.browser',
            }
        ]
    }
});

index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React</title>

    <script>
        const isBrowser = () => typeof window !== 'undefined';
        const isGlobal = () => typeof global !== 'undefined';
        if (!isGlobal() && isBrowser()) {
            var global = window;
            var root = window;
        }
    </script>
  </head>
  <body>
    <div id="app"></div>
    <script src="/src/main.jsx" type="module"></script>
  </body>
</html>

main.jsx:

...
//import aws_exports from "./aws-exports";
import aws_config from "./aws-config"; // <- using a custom config (committed to git) 
                                       // instead of auto-generated aws-exports.js; not 
                                       // necessary for this work-around, just noting this
import * as aws_amplify_core from "@aws-amplify/core";

const Amplify = aws_amplify_core.Amplify;

Amplify.configure(aws_config);
...

App.jsx:

...
import '@aws-amplify/ui-react/styles.css';
import * as aws_amplify_react from "aws-amplify-react";
import { Auth } from "@aws-amplify/auth";
import { AuthState } from '@aws-amplify/ui-components';

const Authenticator = aws_amplify_react.Authenticator;
const SignIn = aws_amplify_react.SignIn;
const SignOut = aws_amplify_react.SignOut; //... .etc

...

... I'm importing and initializing the Amplify singleton object in the top-level main.jsx and subsequently using the modular dependencies/resources in App.jsx and child components. Now I can use <Authenticator /> from aws-amplify-react in my custom React component. NOTE: <Authenticator /> has significant differences from the equivalent component in @aws-amplify/ui-react and while I would rather use the latter, more recent component, npm run build will not succeed if I use it. For help with the aws-amplify-react implementation alongside Auth/AuthState from @aws-amplify/auth/@aws-amplify/ui-components, see https://vaibhavsethia1998.medium.com/creating-a-custom-authenticator-using-aws-amplify-cognito-and-react-js-60f24d1c84aa

rpggio commented 1 year ago

Polyfilling node APIs worked for me.

Rollup plugin mentioned here might be worth looking at.

achirita commented 1 year ago

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.

abdallahshaban557 commented 1 year ago

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

jesuscovam commented 1 year ago

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' 🙏🏼

olivier65 commented 1 year ago

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

pedersenderekserif commented 1 year ago

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.

abdallahshaban557 commented 1 year ago

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

mkilp commented 1 year ago

I am facing a similar issue right now, this time actually caused by the use of CryptoJS.

'default' is not exported by node_modules/crypto-js/core.js, imported by node_modules/amazon-cognito-identity-js/es/AuthenticationHelper.js
file: C:/Users/...../node_modules/amazon-cognito-identity-js/es/AuthenticationHelper.js:7:7
5: 
6: import { Buffer } from 'buffer';
7: import CryptoJS from 'crypto-js/core';
          ^
8: import 'crypto-js/lib-typedarrays'; // necessary for crypto js
9: import SHA256 from 'crypto-js/sha256';

My vite config is pretty wild righ tnow as I'm trying to convert from CRA to vite and had to get around a bunch of issues. Running the dev server works, the prod build fails. It seems like it has something to do with amplify.

// eslint-disable-next-line import/no-extraneous-dependencies
import { defineConfig } from 'vite';
// eslint-disable-next-line import/no-extraneous-dependencies
import react from '@vitejs/plugin-react';
import envCompatible from 'vite-plugin-env-compatible';
import copy from 'rollup-plugin-copy';
import rollupNodePolyFill from 'rollup-plugin-node-polyfills';
// npm i --save-dev @esbuild-plugins/node-globals-polyfill
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill';
// yarn add --dev @esbuild-plugins/node-modules-polyfill
import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill';
import * as _path from 'path';
import nodePolyfills from 'vite-plugin-node-stdlib-browser';
import { nodeResolve } from '@rollup/plugin-node-resolve';

export default defineConfig((env) => {
  const { mode } = env;
  /**
   * Fix build messages/errors like: `'useState' is not exported by 'node_modules/react/index.js'`
   */
  let pathReact = 'umd/react.production.min.js';
  let pathReactDom = 'umd/react-dom.production.min.js';
  let pathReactJsx = 'cjs/react-jsx-runtime.production.min.js';
  if (mode === 'development') {
    pathReact = 'umd/react.development.js';
    pathReactDom = 'umd/react-dom.development.js';
    pathReactJsx = 'cjs/react-jsx-dev-runtime.development.js';
  }
  return {
    optimizeDeps: {
      esbuildOptions: {
      // Node.js global to browser globalThis
        define: {
          global: 'globalThis',
        },
        // Enable esbuild polyfill plugins
        plugins: [
          NodeGlobalsPolyfillPlugin({
            process: true,
            buffer: true,
          }),
        ],
      },
    },
    resolve: {
      alias: [
        {
          util: 'rollup-plugin-node-polyfills/polyfills/util',
          sys: 'util',
          events: 'rollup-plugin-node-polyfills/polyfills/events',
          stream: 'rollup-plugin-node-polyfills/polyfills/stream',
          path: 'rollup-plugin-node-polyfills/polyfills/path',
          querystring: 'rollup-plugin-node-polyfills/polyfills/qs',
          punycode: 'rollup-plugin-node-polyfills/polyfills/punycode',
          url: 'rollup-plugin-node-polyfills/polyfills/url',
          string_decoder:
          'rollup-plugin-node-polyfills/polyfills/string-decoder',
          http: 'rollup-plugin-node-polyfills/polyfills/http',
          https: 'rollup-plugin-node-polyfills/polyfills/http',
          os: 'rollup-plugin-node-polyfills/polyfills/os',
          assert: 'rollup-plugin-node-polyfills/polyfills/assert',
          constants: 'rollup-plugin-node-polyfills/polyfills/constants',
          _stream_duplex:
          'rollup-plugin-node-polyfills/polyfills/readable-stream/duplex',
          _stream_passthrough:
          'rollup-plugin-node-polyfills/polyfills/readable-stream/passthrough',
          _stream_readable:
          'rollup-plugin-node-polyfills/polyfills/readable-stream/readable',
          _stream_writable:
          'rollup-plugin-node-polyfills/polyfills/readable-stream/writable',
          _stream_transform:
          'rollup-plugin-node-polyfills/polyfills/readable-stream/transform',
          timers: 'rollup-plugin-node-polyfills/polyfills/timers',
          console: 'rollup-plugin-node-polyfills/polyfills/console',
          vm: 'rollup-plugin-node-polyfills/polyfills/vm',
          zlib: 'rollup-plugin-node-polyfills/polyfills/zlib',
          tty: 'rollup-plugin-node-polyfills/polyfills/tty',
          domain: 'rollup-plugin-node-polyfills/polyfills/domain',
          find: 'common',
          replacement: _path.resolve(__dirname, './src/common'),
        },
        // react alias fix
        {
          find: /^react$/,
          replacement: require.resolve(_path.join('react', pathReact)),
        },
        {
          find: /^react-dom$/,
          replacement: require.resolve(_path.join('react-dom', pathReactDom)),
        },
        {
          /*
          2022-03-11
          https://github.com/vitejs/vite/issues/6215#issuecomment-1064247764
          */
          find: /react\/jsx-runtime/,
          replacement: require.resolve(_path.join('react', pathReactJsx)),
        },
        // End react alias fix
        {
          find: './runtimeConfig', //amplify fix
          replacement: './runtimeConfig.browser',
        },
      ],
    },
    envPrefix: 'REACT_APP_',
    plugins: [react(), rollupNodePolyFill(), nodePolyfills(), nodeResolve({
      browser: true,
      preferBuiltins: false,
    })],
});

Maybe someone here has an idea about that?

bregan commented 1 year ago

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

mkilp commented 1 year ago

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

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

@bregan Thanks alot for your help! Like you said i started from scratch and am now stuck with react-cookies being weird. But that has nothing to do with amplify. I hope AWS can solve this soon natively without an alias.

schirmerp commented 1 year ago

configuring like this worked for me.

vite.config.js

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

jawobar commented 1 year ago

Similar thing worked for me. I am using Nuxt3:

// nuxt.config.ts
export default defineNuxtConfig({
  vite: {
    resolve: {
      alias: {
        "./runtimeConfig": "./runtimeConfig.browser", //fix production build
      }
    }
  }
})
UrbanSwati commented 1 year ago

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",
    },
  },
});
ffxsam commented 1 year ago

For anyone using Vue 3 + Vitest, you'll need a conditional for that global definition, otherwise Vitest will break. This is my full Vite config:

/// <reference types="vitest" />
import { fileURLToPath, URL } from 'node:url';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vuetify from 'vite-plugin-vuetify';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), vuetify()],
  ...(process.env.NODE_ENV !== 'test'
    ? {
      define: {
        global: {},
      },
    }
    : {}),
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },
  test: {
    deps: {
      inline: ['vuetify'],
    },
    environment: 'jsdom',
    include: ['**/*.spec.ts'],
  },
});
ffxsam commented 1 year ago

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