Using object-hash in an Angular 8 project causes "Cannot read property 'crypto' of undefined" error

4.6k Views Asked by At

I have an Angular-CLI project which makes use of the object-hash library for creating hashes from objects. Normally I would just put

import * as objectHash from 'object-hash'

at the top of one of my component files and then do const hash = objectHash(obj) anywhere I needed a hash.

I just upgraded my project to Angular 8 and suddenly, the Angular project serves great, but when I run a production build, I get an error: Cannot read property 'crypto' of undefined.

This is because Angular 8 generates differential JavaScript, generating some bundles for newer browsers as <script type="module"> and older browsers as <script nomodule>. When a script has type="module", apparently this is treated differently- so the object-hash library's reference to this is broken: https://github.com/puleos/object-hash/issues/71

Does anyone have any insight into how I might resolve this?

Potential solutions I'm seeing are:

  • Importing the object-hash library differently somehow

  • Using a completely different browser-compatible object-hashing library (I haven't found one yet)

  • Getting Angular-CLI v8 to stop generating differential JS and just spit out old-fashioned bundles (I haven't found a solution to this one yet)
  • Downgrading to Angular 7
2

There are 2 best solutions below

0
lealceldeiro On BEST ANSWER

After the commit 1e0835c, upgrading to v2.0.1 should solve the problem (see the author's comment in the reported issue)

0
nickbullock On

I think the easiest way is to use custom webpack configuration as in the issue you mentioned, because it is a build phase problem, not runtime. As i can see angular core members will not fix this problem soon.

You will get all the features from angular/cli build (because @angular-builders/custom-webpack is based on default angular builder), but will be able to write your own webpack rules. In my opinion it is very safe additional config:

module.exports = {
  node: {
    path: true,
    crypto: true,
    fs: 'empty'
  }
}

and i think you will never break something with @angular upgrades. For example on my work project we use @angular-builders/custom-webpack in more aggressive manner: we replace some plugins and loaders and use ours. And sometimes it just breaks.