aws-sdk-js icon indicating copy to clipboard operation
aws-sdk-js copied to clipboard

aws-sdk is not compatible with Angular 12

Open hinddeep opened this issue 3 years ago • 13 comments

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: - add a fallback 'resolve.fallback: { "util": require.resolve("util/") }' - install 'util' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "util": false }

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

hinddeep avatar Jul 09 '21 06:07 hinddeep

hola ya le diste solucion? tengo tu mismo problema

carloshd25 avatar Aug 01 '21 19:08 carloshd25

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

abhinavaggarwal8 avatar Aug 17 '21 21:08 abhinavaggarwal8

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
  • Edit angular.json file to use Custom Webpack Builders instead of the standard Angular ones and set customWebpackConfig.path value to extra-webpack.config.ts, e.g.
{
  "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",
  • create a new ./extra-webpack.config.ts file (path is relative to angular.json file):
import { Configuration } from 'webpack';

export default {
    resolve: {
        fallback: {
            util$: './util.js',
        },
    },
} as Configuration;
  • ng build should succeed now

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.

DmitryGulin avatar Sep 01 '21 03:09 DmitryGulin

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

jccote-infor avatar Sep 03 '21 17:09 jccote-infor

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.

louisl avatar Sep 08 '21 17:09 louisl

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

Sumon-TWeb avatar Oct 11 '21 14:10 Sumon-TWeb

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

AtozEvo avatar Nov 03 '21 11:11 AtozEvo

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

collindutter avatar Jan 19 '22 18:01 collindutter

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.

azronio avatar Jul 21 '22 21:07 azronio

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

JamesJansson avatar Sep 02 '22 17:09 JamesJansson

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

celowsky avatar Sep 21 '22 17:09 celowsky

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?

azronio avatar Sep 21 '22 17:09 azronio