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

Support Rollup

Open bennypowers opened this issue 7 years ago • 33 comments

With imports of the type

import { AuthenticationDetails } from 'amazon-cognito-identity-js';

and rollup.config.js featuring:

import sourcemaps from 'rollup-plugin-sourcemaps';
import resolve from 'rollup-plugin-node-resolve';
import builtins from 'rollup-plugin-node-builtins';
import globals from 'rollup-plugin-node-globals';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';

export default {

  input: 'src/eve-redux/eve-redux-store.js',

  output: {
    file: 'src/bundle.js',
    format: 'iife',
  },

  watch: {
    include: 'src/**',
  },

  plugins: [
    sourcemaps(),
    resolve(),
    json(),
    builtins(),
    globals(),
    commonjs({
      include: 'node_modules/**',
      namedExports: {
        'node_modules/inferno-redux/index.js': ['Provider'],
      },
    }),
  ],

};

rollup -c produces the output:

src/eve-redux/eve-redux-store.js → src/bundle.js...
preferring built-in module 'util' over local alternative at 'FOO/node_modules/util/util.js', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning
preferring built-in module 'process' over local alternative at 'FOO/node_modules/process/index.js', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning
preferring built-in module 'util' over local alternative at 'FOO/node_modules/util/util.js', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning
[!] Error: 'util' is not exported by node_modules/aws-sdk/global.js
https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module
node_modules/amazon-cognito-identity-js/es/AuthenticationHelper.js (20:9)
18:  */
19:
20: import { util } from 'aws-sdk/global';
             ^
21:
22: import BigInteger from './BigInteger';

error Command failed with exit code 1.

bennypowers avatar Oct 21 '17 18:10 bennypowers

By modifying the rollup.config.js slightly I've succeeded at bundling without error, however we're not out of the woods yet.

import sourcemaps from 'rollup-plugin-sourcemaps';
import resolve from 'rollup-plugin-node-resolve';
import builtins from 'rollup-plugin-node-builtins';
import globals from 'rollup-plugin-node-globals';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';

export default {

  external: ['aws-sdk'],

  globals: {
    'aws-sdk': 'AWS',
  },

  input: 'src/eve-redux/eve-redux-store.js',

  output: {
    file: 'src/bundle.js',
    name: 'EVE',
    format: 'iife',
  },

  watch: {
    include: 'src/**',
  },

  plugins: [
    json(),
    commonjs({
      include: 'node_modules/**',
      ignoreGlobal: true,
      namedExports: {
        'node_modules/inferno-redux/index.js': ['Provider'],
        'node_modules/aws-sdk/global.js': ['util'],
      },
    }),
    globals(),
    builtins(),
    resolve({
      preferBuiltins: true,
    }),
    sourcemaps(),
  ],

};

Rollup successfully bundles the SDK, however, the browser complains:

bundle.js:2316 Uncaught TypeError: Cannot read property 'memoizedProperty' of undefined

which takes us to this line:

var memoizedProperty$1 = util_1.memoizedProperty;

and

var util_1 = util;

and

/**
 * A set of utility methods for use with the AWS SDK.
 *
 * @!attribute abort
 *   Return this value from an iterator function {each} or {arrayEach}
 *   to break out of the iteration.
 *   @example Breaking out of an iterator function
 *     AWS.util.each({a: 1, b: 2, c: 3}, function(key, value) {
 *       if (key == 'b') return AWS.util.abort;
 *     });
 *   @see each
 *   @see arrayEach
 * @api private
 */
var util = {//...insert AWS util obj here...}

bennypowers avatar Oct 26 '17 12:10 bennypowers

I got the same problem running on pure [email protected].

I don't have sure if order of lines should be the problem in this case, but i have:

5893: var memoizedProperty = util_1.memoizedProperty; 20350: var util_1 = util$1; 19431: var util$1 = { // amazon code

rntgspr avatar Mar 02 '18 15:03 rntgspr

Any update? Facing this issue too.

powerful235 avatar Apr 18 '18 21:04 powerful235

Check out Amazon's documentation for using aws-iot-device-sdk-js in the browser. https://github.com/aws/aws-iot-device-sdk-js#browser

It's pretty crazy, but you have to manually compile the JS and include it separately via

var AWS = require('aws-sdk');
var AWSIoTData = require('aws-iot-device-sdk');

IAmBrandonMcGregor avatar Apr 25 '18 16:04 IAmBrandonMcGregor

import AWS from 'aws-sdk' seems to be working for me. Is this the case for anybody else?

btakita avatar Jan 02 '19 16:01 btakita

How is this still an issue? This makes the library completely unusable for anyone using rollup. I would expect a bug of this magnitude to be fixed quickly but it's been over a year and no work as been done on it.

I'm by no means an expert with rollup but I suspect the issue arises from the multitude of circular dependencies.

RedHatter avatar Mar 04 '19 22:03 RedHatter

Was anyone able to solve: "Uncaught TypeError: Cannot read property 'memoizedProperty' of undefined"?

jordanranz avatar Jul 24 '19 20:07 jordanranz

Looks like I have to use either webpack or mongo stitch.

wikiwang1991 avatar Oct 28 '19 06:10 wikiwang1991

@wikiwang1991 yes, for some reason this issue is not getting solved. I use webpack, it works fine after some tinkering with the configs.

jesper-bylund avatar Oct 28 '19 08:10 jesper-bylund

This issue is not open for more than two years...

Stumbled upon this while trying to use amplify together with svelte - which uses rollup.

chufgard avatar Feb 20 '20 07:02 chufgard

This issue is not open for more than two years... Stumbles upon this while trying to use amplify together with svelte - which uses rollup.

Same reason I found this post 24 days ago. I ended up just switching to Firebase. : /

Finally found a way: You can use webpack instead of rollup to build the application, then everything works just fine.

chufgard avatar Feb 21 '20 07:02 chufgard

For those who don't want to switch from rollup to webpack, what is the recommended course of action?

tommedema avatar Apr 25 '20 01:04 tommedema

For those who don't want to switch from rollup to webpack, what is the recommended course of action?

Switch to GCP and start using Firebase instead, unfortunately, I think. 😢

saumets avatar May 06 '20 19:05 saumets

Has anyone tried rollup with the SDK v3? https://github.com/aws/aws-sdk-js-v3

cc @chufgard

jadbox avatar Jul 16 '20 03:07 jadbox

For GCP, you can instruct external dependancies to be installed on the host machine using a package.unbundled.json and supplying it to the copy plugin in your rollup.config.js.

The following worked for me:

rollup.config.js

import typescript from '@rollup/plugin-typescript'
import nodeResolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import json from '@rollup/plugin-json'
import copy from 'rollup-plugin-copy2'

export default {
    input: './src/index.ts',
    preserveSymlinks: true,
    plugins: [
        typescript(),
        nodeResolve({ preferBuiltins: true }),
        commonjs({
            namedExports: {}
        }),
        json(),
        copy({
            assets: [['./package.unbundled.json', 'package.json']]
        })
    ],
    external: ['crypto', 'firebase-admin', 'firebase-functions', '@google-cloud/firestore', 'buffer', '@google-cloud/pubsub', 'iltorb', 'aws-sdk'],
    output: {
        dir: './lib',
        format: 'cjs',
        sourcemap: true
    }
}

package.unbundled.json

{
    "dependencies": {
        "firebase-admin": "^8.9.2",
        "aws-sdk": "^2.720.0"
    }
}

tjmgregory avatar Sep 15 '20 12:09 tjmgregory

I ran into this issue recently and after further investigating found that one of the dependencies I had was importing from aws-sdk/global instead of aws-sdk and that caused this issue. So updating that dependency to use the same import and setting aws-sdk as external helped.

justindra avatar Oct 24 '20 01:10 justindra

I found a strange way for 'amazon-cognito-identity-js'

echo export default AmazonCognitoIdentity >> node_modules\amazon-cognito-identity-js\dist\amazon-cognito-identity.js and in your app

import AmazonCognitoIdentity  from 'amazon-cognito-identity-js/dist/amazon-cognito-identity.js';
...

misogihagi avatar Nov 27 '20 04:11 misogihagi

Has anyone tried rollup with the SDK v3? https://github.com/aws/aws-sdk-js-v3

cc @chufgard

This issue seems to be resolved in v3. I was encountering it with v2, and it went away when upgrading to v3.

Tenkir avatar Mar 30 '21 23:03 Tenkir

I am still facing issues with v2. Any solution for v2?

Chandana-idexcel avatar May 12 '21 14:05 Chandana-idexcel

I'am still getting the same error as @bennypowers and @jordanranz reported. BTW I'm using "vite": "^2.7.10", with "aws-sdk": "^2.1048.0" on Vue 2.

Builds with webpack still run fine but vite throws me the same error on the browser:

Uncaught TypeError: Cannot read property 'memoizedProperty' of undefined

Is there at least a workaround for this issue?

christianlmc avatar Jan 10 '22 21:01 christianlmc

After a few days of trying to fix this issue, I finally got to a working solution aka workaround.

First create a file for the functions you use on your project (in my case it was only S3)

aws-s3.js

import AWS from 'aws-sdk';

const getS3Object = () => {
    return new AWS.S3({ region: 'us-west-2' });
};

window.getS3Object = getS3Object; // Expose getS3Object to window object

Then create the webpack config file (install webpack if you don't have it).

webpack.config.js

const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
    // Specify the entry point for our app.
    entry: [path.join(__dirname, 'aws-s3.js')],
    // Specify the output file containing our bundled code.
    output: {
        path: __dirname,
        filename: 'aws-s3.min.js',
    },
    optimization: {
        minimizer: [
            new TerserPlugin({
                extractComments: false, // omit Licence.txt file generation
            }),
        ],
    },
    // Enable WebPack to use the 'path' package.
    resolve: {
        fallback: { path: require.resolve('path-browserify') },
    },
};

Add the following script to your package.json.

package.json

"scripts": {
    // ...
    "build-bundled": "webpack"
}

Then run the following command, this will run the webpack with the configurations we set up on webpack.config.js and generate our file (in this case aws-s3.min.js):

npm run build-bundled

Include the generated aws-s3.min.js to your index.html

index.html

<html>
    <body>
         <!-- Add this script tag -->
        <script type="module" src="/aws-s3.min.js"></script>
    </body>
</html>

With that, you should be able to call the aws-sdk functions with the windows object.

Before

const S3 = new AWS.S3()

After

const S3 = window.getS3Object();

christianlmc avatar Jan 12 '22 18:01 christianlmc

After a few days of trying to fix this issue, I finally got to a working solution aka workaround.

First create a file for the functions you use on your project (in my case it was only S3)

aws-s3.js

import AWS from 'aws-sdk';

const getS3Object = () => {
    return new AWS.S3({ region: 'us-west-2' });
};

window.getS3Object = getS3Object; // Expose getS3Object to window object

Then create the webpack config file (install webpack if you don't have it).

webpack.config.js

const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
    // Specify the entry point for our app.
    entry: [path.join(__dirname, 'aws-s3.js')],
    // Specify the output file containing our bundled code.
    output: {
        path: __dirname,
        filename: 'aws-s3.min.js',
    },
    optimization: {
        minimizer: [
            new TerserPlugin({
                extractComments: false, // omit Licence.txt file generation
            }),
        ],
    },
    // Enable WebPack to use the 'path' package.
    resolve: {
        fallback: { path: require.resolve('path-browserify') },
    },
};

Add the following script to your package.json.

package.json

"scripts": {
    // ...
    "build-bundled": "webpack"
}

Then run the following command, this will run the webpack with the configurations we set up on webpack.config.js and generate our file (in this case aws-s3.min.js):

npm run build-bundled

Include the generated aws-s3.min.js to your index.html

index.html

<html>
    <body>
         <!-- Add this script tag -->
        <script type="module" src="/aws-s3.min.js"></script>
    </body>
</html>

With that, you should be able to call the aws-sdk functions with the windows object.

Before

const S3 = new AWS.S3()

After

const S3 = window.getS3Object();

it works!!!

BossYi avatar Feb 13 '22 13:02 BossYi

I'am still getting the same error as @bennypowers and @jordanranz reported. BTW I'm using "vite": "^2.7.10", with "aws-sdk": "^2.1048.0" on Vue 2.

Builds with webpack still run fine but vite throws me the same error on the browser:

Uncaught TypeError: Cannot read property 'memoizedProperty' of undefined

Is there at least a workaround for this issue?

can use CDN import AWS not error

xsky-ken avatar May 09 '22 07:05 xsky-ken

I was able to get aws-sdk v2 working with rollup using @rollup/commonjs v22 and setting the new strictRequires option to true.

https://github.com/rollup/plugins/tree/master/packages/commonjs#strictrequires

airjp73 avatar May 23 '22 16:05 airjp73

import AWS from 'aws-sdk' seems to be working for me. Is this the case for anybody else?

No, not with aws-sdk v2.1143 + Vite 2.9.9.

t-lock avatar May 27 '22 17:05 t-lock

I was able to get aws-sdk v2 working with rollup using @rollup/commonjs v22 and setting the new strictRequires option to true.

https://github.com/rollup/plugins/tree/master/packages/commonjs#strictrequires

With vite, you can do the same solution using strictRequires, but since vite is on v21 of @rollup/commonjs, it requires a slightly hackier approach. This plugin removes the commonjs plugin that vite provides by default and replaces it with v22.

export const updateCommonjsPlugin = (): Plugin => {
  const commonJs22 = commonjs({
    include: [/node_modules/],
    extensions: [".js", ".cjs"],
    strictRequires: true,
  });

  return {
    name: "new-common-js",
    options(rawOptions) {
      const plugins = Array.isArray(rawOptions.plugins)
        ? [...rawOptions.plugins]
        : rawOptions.plugins
        ? [rawOptions.plugins]
        : [];

      const index = plugins.findIndex(
        (plugin) => plugin && plugin.name === "commonjs"
      );
      if (index !== -1) {
        plugins.splice(index, 1, commonJs22);
      }

      const nextConfig = { ...rawOptions, plugins };
      return commonJs22.options.call(this, nextConfig);
    },
  };
};

Then in your vite config you can do

plugins: [updateCommonjsPlugin()],

I think vite is planning on upgrading @rollup/commonjs to v22 in vite 3 (reference) at which point this workaround will become unnecessary.

airjp73 avatar May 27 '22 17:05 airjp73

`With vite, you can do the same solution using strictRequires, but since vite is on v21 of @rollup/commonjs, it requires a slightly hackier approach. This plugin removes the commonjs plugin that vite provides by default and replaces it with v22.

@airjp73 this method got rid of the Cannot read property 'memoizedProperty' of undefined error for me, but now my Svelte bundle doesn't get called in index.html, resulting in a blank page.

Are you importing aws as es module or using commonjs require?

t-lock avatar May 27 '22 18:05 t-lock

In my case, I'm not using the html output from vite so that could be why I'm not running into that issue.

airjp73 avatar May 27 '22 18:05 airjp73

I was able to get aws-sdk v2 working with rollup using @rollup/commonjs v22 and setting the new strictRequires option to true. https://github.com/rollup/plugins/tree/master/packages/commonjs#strictrequires

With vite, you can do the same solution using strictRequires, but since vite is on v21 of @rollup/commonjs, it requires a slightly hackier approach. This plugin removes the commonjs plugin that vite provides by default and replaces it with v22.

export const updateCommonjsPlugin = (): Plugin => {
  const commonJs22 = commonjs({
    include: [/node_modules/],
    extensions: [".js", ".cjs"],
    strictRequires: true,
  });

  return {
    name: "new-common-js",
    options(rawOptions) {
      const plugins = Array.isArray(rawOptions.plugins)
        ? [...rawOptions.plugins]
        : rawOptions.plugins
        ? [rawOptions.plugins]
        : [];

      const index = plugins.findIndex(
        (plugin) => plugin && plugin.name === "commonjs"
      );
      if (index !== -1) {
        plugins.splice(index, 1, commonJs22);
      }

      const nextConfig = { ...rawOptions, plugins };
      return commonJs22.options.call(this, nextConfig);
    },
  };
};

Then in your vite config you can do

plugins: [updateCommonjsPlugin()],

I think vite is planning on upgrading @rollup/commonjs to v22 in vite 3 (reference) at which point this workaround will become unnecessary.

Worked!

MichaelSzer avatar Jul 01 '22 16:07 MichaelSzer

I solved it by adding:

  resolve: {
    alias: {
      'aws-sdk': 'aws-sdk/dist/aws-sdk.min.js',
    },
  },

stavalfi avatar Jul 07 '22 13:07 stavalfi