aws / aws-sdk-js

AWS SDK for JavaScript in the browser and Node.js
https://aws.amazon.com/developer/language/javascript/
Apache License 2.0
7.59k stars 1.55k forks source link

aws-sdk is not compatible with Angular 12 #3824

Closed hinddeep closed 9 hours ago

hinddeep commented 3 years ago

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

Describe the bug I'm building an application using Ionic 6.16.3, Capacitor 3, and Angular 12. After installing 'aws-sdk node module' production build fails with the following error message: Error: Module not found: Error: Can't resolve 'util' in '/Users/hinddeeppurohit/Documents/battle-of-brands/node_modules/aws-sdk/lib' Did you mean './util'? Requests that should resolve in the current directory need to start with './'. Requests that start with a name are treated as module requests and resolve within module directories (/Users/hinddeeppurohit/Documents/****, node_modules). If changing the source code is not an option there is also a resolve options called 'preferRelative' which tries to resolve these kind of requests in the current directory too.

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:

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

If on Node.js, are you running this on AWS Lambda? NA

Details of the browser/Node.js version Browsers: Chrome: 91.0.4472.114 Node: v14.16.1

SDK version number Example: v2.466.0 "aws-sdk": "^2.942.0"

To Reproduce (observed behavior) 1) Upgrade to angular 12 if using an older version of angular: ng update @angular/core@12 @angular/cli@12 2) Create a blank ionic capacitor project: ionic start 3) Install aws: npm i aws-amplify @aws-amplify/ui-angular aws-sdk 4) Add the following code to src/polyfills.ts: (window as any).global = window; (window as any).process = { env: { DEBUG: undefined }, }; 5) Add "esModuleInterop": true to compiler options in ts.config.json 6) Replace types array in tsconfig.app.json with "types": ["node"] 7) Import Location from aws-sdk: import Location from "aws-sdk/clients/location"; 8) Use it like so: const credentials = await Auth.currentCredentials(); console.log(credentials); const client = new Location({ credentials, region: awsmobile.location_region });

  const params = {
    IndexName: "IndexName",
    Text: "Indianapolis",
  };
  client.searchPlaceIndexForText(params, (err, data) => {
    if (err) console.error(err);
    if (data) console.log(data);
  });

9) Run production build: ng build --source-map=false --progress=false --configuration production

Expected behavior The app should compile after running the production build and I should be able to use the Location API from aws-sdk

Screenshots

Additional context My Package.json file: { "name": "name of project", "version": "0.0.1", "author": "Ionic Framework", "homepage": "https://ionicframework.com/", "scripts": { "start": "ng serve", "build": "ng build --source-map=false --progress=false", "prod": "ng build --source-map=false --progress=false --configuration production", "android": "ionic cap run android -l --external", "ios": "ionic cap run ios -l --external", "serve": "ionic serve -- --hmr", "test": "ng test", "lint": "ng lint --fix", "e2e": "ng e2e", "postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points", "res": "cordova-res --skip-config --copy" }, "private": true, "dependencies": { "@angular/common": "~12.0.1", "@angular/core": "~12.0.1", "@angular/forms": "~12.0.1", "@angular/platform-browser": "~12.0.1", "@angular/platform-browser-dynamic": "~12.0.1", "@angular/router": "~12.0.1", "@aws-amplify/ui-angular": "^1.0.14", "@capacitor-community/facebook-login": "^3.0.0", "@capacitor/android": "^3.0.2", "@capacitor/app": "1.0.2", "@capacitor/core": "3.0.2", "@capacitor/dialog": "^1.0.2", "@capacitor/haptics": "1.0.2", "@capacitor/keyboard": "1.0.2", "@capacitor/status-bar": "1.0.2", "@capacitor/storage": "^1.0.2", "@ionic/angular": "^5.5.2", "aws-amplify": "^4.1.3", "aws-sdk": "^2.942.0", "rxjs": "~6.6.0", "tslib": "^2.0.0", "zone.js": "~0.11.4" }, "devDependencies": { "@angular-devkit/build-angular": "~12.0.1", "@angular-eslint/builder": "~12.0.0", "@angular-eslint/eslint-plugin": "~12.0.0", "@angular-eslint/eslint-plugin-template": "~12.0.0", "@angular-eslint/template-parser": "~12.0.0", "@angular/cli": "~12.0.1", "@angular/compiler": "~12.0.1", "@angular/compiler-cli": "~12.0.1", "@angular/language-service": "~12.0.1", "@capacitor/cli": "3.0.2", "@ionic/angular-toolkit": "^4.0.0", "@types/jasmine": "~3.6.0", "@types/jasminewd2": "~2.0.3", "@types/node": "^12.11.1", "@typescript-eslint/eslint-plugin": "4.16.1", "@typescript-eslint/parser": "4.16.1", "eslint": "^7.6.0", "eslint-plugin-import": "2.22.1", "eslint-plugin-jsdoc": "30.7.6", "eslint-plugin-prefer-arrow": "1.2.2", "jasmine-core": "~3.7.1", "jasmine-spec-reporter": "~5.0.0", "karma": "~6.3.2", "karma-chrome-launcher": "~3.1.0", "karma-coverage": "~2.0.3", "karma-coverage-istanbul-reporter": "~3.0.2", "karma-jasmine": "~4.0.0", "karma-jasmine-html-reporter": "^1.5.0", "protractor": "~7.0.0", "ts-node": "~8.3.0", "typescript": "~4.2.4" }, "description": "An Ionic project" }

carloshd25 commented 3 years ago

hola ya le diste solucion? tengo tu mismo problema

abhinavaggarwal8 commented 3 years ago

Same issue npm install --save-dev @types/node does not solves the problem.

DmitryGulin commented 3 years ago

Angular 12 migrated to Webpack 5, which seems to have changed the defaults. You can tweak Webpack configuration in order to let it resolve the proper file.

npm i --save-dev @angular-builders/custom-webpack
{
  "projects": {
    "angular-client-app": {
      "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./extra-webpack.config.ts"
            },
            "outputPath": "dist/angular-client-app",
            "index": "src/index.html",
import { Configuration } from 'webpack';

export default {
    resolve: {
        fallback: {
            util$: './util.js',
        },
    },
} as Configuration;

Clarification:

The custom configuration below uses Webpack 5 resolve.fallback feature to search for ./util.js file every time it fails to locate util module for a line like var params = require('util').inspect(censoredParams, true, null);.

Requests that should resolve in the current directory need to start with './'.

It seems like Angular 12 build system (which was built on top of WebPack 5) changed the default behavior for resolving relative path modules, thus, you can either use resolve.fallback configuration to configure fallback rules for a subset of libraries or override global resolve.preferRelative rule, setting it to true, which might result in breaking other libraries.

jccote-infor commented 3 years ago

what is that pointer to util.js? not clear on what that's meant to do

louisl commented 2 years ago

Will this be getting fixed here or somewhere else i.e. (webpack, angular)? I've tried a bunch of different things and googled the crap out of this and it still won't work so I'm a bit stuck.

Sumon-TWeb commented 2 years ago

Hi. I am getting same issue on angular 12. Is their any solution available for implement aws-sdk in angular 12?

AtozEvo commented 2 years ago

Bumping this. And I'm also wondering, is there/will there be a solution for this? Currently I've managed to work-around it, but it required me to add some commonJs depended packages to my project and i aint very happy with the bloating :(

collindutter commented 2 years ago

I fixed it by installing util:

npm i util

and then adding:

(window as any).global.util = (window as any).global.util || require('util').util;

to my polyfills.ts

azronio commented 2 years ago

I fixed it by installing util:

npm i util

and then adding:

(window as any).global.util = (window as any).global.util || require('util').util;

to my polyfills.ts

This is not really fixing the problem. Here you are replacing the AWS util module with the node-util one, which probably will cause some runtime issues if you are using the aws-sdk in your app.

I think the solution from @DmitryGulin with resolve.fallback is best, although I haven't tried it personally yet. The 'preferRelative' option as he states could have downstream effects.

JamesJansson commented 2 years ago

For people who are coming across this issue, here are some "non-solutions" to this incompatibility: 1) If you have a mono repo with both front end and back end functionality in the same repo for code re-use reasons, you can restructure your code to prevent the aws-sdk being imported into the front end. For the common functions, ensure that those functions are not in files that import the aws-sdk somewhere along the way. 2) If you're using s3 functionality on the front end, maybe try using the client library instead: https://www.npmjs.com/package/@aws-sdk/client-s3

celowsky commented 1 year ago

Writing here to help gain some momentum on this issue, as it affects my project too.

azronio commented 1 year ago

Writing here to help gain some momentum on this issue, as it affects my project too.

The solution by @DmitryGulin that I mentioned worked for me using Angular 12 and 13. Have you tried the custom-webpack solution? If so, what specific errors are you encountering?

aBurmeseDev commented 5 days ago

Hi everyone! Thank you all for your input on this issue. After reviewing the comments, it seems that this problem is specific to Angular and/or Webpack, and not directly related to the AWS SDK. The proposed solutions and workarounds appear to be unrelated to the AWS SDK itself.

If anyone can provide concrete evidence that the AWS SDK is the root cause of this issue, please share that information. However, if there is no direct connection to the AWS SDK, I will proceed to close this issue.

Unless there is a clear indication that the AWS SDK is the culprit behind this problem, it would be more appropriate to address this issue in the context of Angular and Webpack as the proposed solutions and workarounds are specific to those frameworks and tools.