aws-sdk-js
aws-sdk-js copied to clipboard
aws-sdk is not compatible with Angular 12
Confirm by changing [ ] to [x] below to ensure that it's a bug:
- [x ] I've gone through Developer Guide and API reference
- [ x] I've checked AWS Forums and StackOverflow for answers
- [ x] I've searched for previous similar issues and didn't find any solution
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)
-
Upgrade to angular 12 if using an older version of angular:
ng update @angular/core@12 @angular/cli@12
-
Create a blank ionic capacitor project:
ionic start
-
Install aws:
npm i aws-amplify @aws-amplify/ui-angular aws-sdk
-
Add the following code to src/polyfills.ts:
(window as any).global = window; (window as any).process = { env: { DEBUG: undefined }, };
-
Add
"esModuleInterop": true
to compiler options in ts.config.json -
Replace types array in tsconfig.app.json with
"types": ["node"]
-
Import Location from aws-sdk:
import Location from "aws-sdk/clients/location";
-
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); });
-
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"
}
hola ya le diste solucion? tengo tu mismo problema
Same issue npm install --save-dev @types/node does not solves the problem.
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 setcustomWebpackConfig.path
value toextra-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 toangular.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.
what is that pointer to util.js? not clear on what that's meant to do
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.
Hi. I am getting same issue on angular 12. Is their any solution available for implement aws-sdk in angular 12?
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 :(
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
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.
For people who are coming across this issue, here are some "non-solutions" to this incompatibility:
- 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.
- 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
Writing here to help gain some momentum on this issue, as it affects my project too.
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?