Webpack: Cannot assign to read only property 'exports'

Hi,

I need to use an external library crypto when running my k6 tests.

I’m using the example here: https://github.com/k6io/k6-es6

However on running the tests, after running npm run-script webpack, firstly it takes.a very long time start the tests, I see the memory (RAM) going up and up, and then I get the error:

ERRO[0105] TypeError: Cannot assign to read only property 'exports' at file:///Users/xxx/Desktop/k6-es6-master/build/app.bundle.js:10:364601(98) 

Any ideas why - here’s the code:

In my test script:

import { sleep, check, group } from "k6";
import http from "k6/http";
import { Rate } from 'k6/metrics';
import Auth from './GreatAuth';

export function setup() {
   let x = new GreatAuth(.....)
}

....

The GreatAuth file that uses crypto looks like:

var crypto = require("crypto");

class GreatAuth {
...
}

module.exports = GreatAuth;

And the webpack config is untouched from the example project I used but FYI:

 var path = require('path');
 var webpack = require('webpack');
 module.exports = {
     mode: "production",
     entry: './main.js',
     output: {
         path: path.resolve(__dirname, 'build'),
         libraryTarget: "commonjs",
         filename: 'app.bundle.js'
     },
     module: {
         rules: [
             {
                 test: /\.js$/,
                 loader: 'babel-loader',
             }
         ]
     },
     stats: {
         colors: true
     },
     target: "web",
         externals: /k6(\/.*)?/,
     devtool: 'source-map'
 };

Any help would be appreciated.

Thanks.

Hi there,

I’m not certain about the cause of that specific error, but in general you won’t be able to require('crypto') since k6 does not run in NodeJS.

Depending on your use case, you might be able to use the built-in k6/crypto module. If that is insufficient, you can use CryptoJS as shown in this example.

HTH,

Ivan

Thanks - that k6/crypto module doesn’t allow my encrypt using a private key, so I can’t really use it.

The reason why I think that error occurs is due to the tests consuming a lot of memory. Hence I was wondering if there something I can do to help, I mean Webpack is only bundling crypto, why does it effect performance so much?

HI @psa, if the problem for the error was too much memory … that would’ve been the error.

We have seen k6 die because it doesn’t have enough memory or getting killed by the OS and in both cases, the error is very upfront about that :slight_smile:

I expect that something goes wrong … I also have no idea how webpack will polyfill crypto but probably with one of the above libraries listed in the GitHub issue that @imiric linked.

You can try to disable webpack minification so you can look at the resulting script and see what the problem is but this to me sounds like something Object.freeze-ed an object and then something else tried to overwrite this property. exports is probably module.exports which makes this strange … but not impossible.

After that you can just go and look at the code and see if you can figure it out or share it here (maybe after removing some confidential stuff :slight_smile: )

Hence I was wondering if there something I can do to help, I mean Webpack is only bundling crypto, why does it effect performance so much?

each and every k6 VU is a separate JS VM so each line of js code needs to be executed and each type for each VU separately. This means that if you have a polyfill it needs to be executed and the memory required for the polyfilled type needs to be allocated for each VU. I don’t expect that w/e crypto polyfill is used by webpack it’s going to be … small :).

Also, webpack might decide (and need) to polyfill other things in order to get the script more compatible with --compatibility-mode=base. Which you should try if you haven’t as it reduces the static amount of memory needed for each VU from around 2.8mb to around 500kb … which is big with a lot of VUs :D.

Hope this helps you :smiley:

Thanks for your response.

As this may be a deep thing to dive into, for the time being I just seperated the task, so whatever I needed with crypto, I took out the tests, I perform that first, then just k6’s open function to read a specific file with whatever secrets I need.