Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular + web3.js: Module not found: Error: Can't resolve 'crypto'

I'm trying to get started with Angular and Web3.js to work with some Ethereum contracts. To reproduce:

  1. ng new
  2. npm install web3 --save
  3. ng serve

package.json:

{
  "name": "ng-eth",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~11.0.6",
    "@angular/common": "~11.0.6",
    "@angular/compiler": "~11.0.6",
    "@angular/core": "~11.0.6",
    "@angular/forms": "~11.0.6",
    "@angular/platform-browser": "~11.0.6",
    "@angular/platform-browser-dynamic": "~11.0.6",
    "@angular/router": "~11.0.6",
    "rxjs": "~6.6.0",
    "tslib": "^2.0.0",
    "web3": "^1.3.4",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1100.6",
    "@angular/cli": "~11.0.6",
    "@angular/compiler-cli": "~11.0.6",
    "@types/jasmine": "~3.6.0",
    "@types/node": "^12.11.1",
    "codelyzer": "^6.0.0",
    "jasmine-core": "~3.6.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~5.1.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "protractor": "~7.0.0",
    "ts-node": "~8.3.0",
    "tslint": "~6.1.0",
    "typescript": "~4.0.2"
  }
}

app.component.ts:

import { Component, OnInit, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import Web3 from "web3";


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  title = 'ngEth';
  
  private window: any;
  
  constructor(@Inject(DOCUMENT) private document: Document)
  {
    this.window = this.document.defaultView;
  }
  
  ngOnInit() {
    
       if (this.window.ethereum) {
        this.window.web3 = new Web3(this.window.ethereum);
        this.window.ethereum.enable();
        return true;
      }
  }
  
}

Error: ./node_modules/eth-lib/lib/bytes.js Module not found: Error: Can't resolve 'crypto' in 'C:\Users\profile\Documents\projects\ATS\ngEth\ngEth\node_modules\eth-lib\lib'

Error: ./node_modules/web3-eth-accounts/lib/index.js Module not found: Error: Can't resolve 'crypto' in 'C:\Users\profile\Documents\projects\ATS\ngEth\ngEth\node_modules\web3-eth-accounts\lib'

Error: ./node_modules/web3-eth-accounts/node_modules/eth-lib/lib/bytes.js Module not found: Error: Can't resolve 'crypto' in 'C:\Users\profile\Documents\projects\ATS\ngEth\ngEth\node_modules\web3-eth-accounts\node_modules\eth-lib\lib'

Error: ./node_modules/web3-providers-http/lib/index.js Module not found: Error: Can't resolve 'http' in 'C:\Users\profile\Documents\projects\ATS\ngEth\ngEth\node_modules\web3-providers-http\lib'

Error: ./node_modules/xhr2-cookies/dist/xml-http-request.js Module not found: Error: Can't resolve 'http' in 'C:\Users\profile\Documents\projects\ATS\ngEth\ngEth\node_modules\xhr2-cookies\dist'

Error: ./node_modules/web3-providers-http/lib/index.js Module not found: Error: Can't resolve 'https' in 'C:\Users\profile\Documents\projects\ATS\ngEth\ngEth\node_modules\web3-providers-http\lib'

Error: ./node_modules/xhr2-cookies/dist/xml-http-request.js Module not found: Error: Can't resolve 'https' in 'C:\Users\profile\Documents\projects\ATS\ngEth\ngEth\node_modules\xhr2-cookies\dist'

Error: ./node_modules/xhr2-cookies/dist/xml-http-request.js Module not found: Error: Can't resolve 'os' in 'C:\Users\profile\Documents\projects\ATS\ngEth\ngEth\node_modules\xhr2-cookies\dist'

Error: ./node_modules/cipher-base/index.js Module not found: Error: Can't resolve 'stream' in 'C:\Users\profile\Documents\projects\ATS\ngEth\ngEth\node_modules\cipher-base'

Error: ./node_modules/keccak/lib/api/keccak.js Module not found: Error: Can't resolve 'stream' in 'C:\Users\profile\Documents\projects\ATS\ngEth\ngEth\node_modules\keccak\lib\api'

Error: ./node_modules/keccak/lib/api/shake.js Module not found: Error: Can't resolve 'stream' in 'C:\Users\profile\Documents\projects\ATS\ngEth\ngEth\node_modules\keccak\lib\api'

like image 971
Darthg8r Avatar asked Mar 22 '21 16:03

Darthg8r


Video Answer


2 Answers

In Angular 12, the solution posted by @yurzui doesn't work anymore due to webpack 5 upgrade.

To fix the compilation error you need to install the required dependencies:

npm install crypto-browserify stream-browserify assert stream-http https-browserify os-browserify

Then you can use tsconfig paths to point to the required libs:

tsconfig.json

{
  "compilerOptions": {
    "paths" : {
      "crypto": ["./node_modules/crypto-browserify"],
      "stream": ["./node_modules/stream-browserify"],
      "assert": ["./node_modules/assert"],
      "http": ["./node_modules/stream-http"],
      "https": ["./node_modules/https-browserify"],
      "os": ["./node_modules/os-browserify"],
    }
  }
}

source: https://github.com/ChainSafe/web3.js/issues/4070

like image 131
Nicolas M. Avatar answered Sep 18 '22 20:09

Nicolas M.


The easist way to make it working is to patch webpack.config.js generated by Angular CLI.

Method 1(no additional dependencies required)

Create web3-patch.js file in root folder of your app.

const fs = require('fs');

// path can differ depend on Angular CLI version
const browserConfigPath = 'node_modules/@angular-devkit/build-angular/src/webpack/configs/browser.js';

fs.readFile(browserConfigPath, 'utf8', function (err, data) {
  if (err) {
    return console.log(err);
  }
  const result = data.replace(/node: false/g, 'node: {crypto: true, stream: true}');

  fs.writeFile(browserConfigPath, result, 'utf8', function (err) {
    if (err) return console.log(err);
  });
});

Execute this script on postinstall

package.json

"scripts": {
  "start": "ng serve",
  ...
  "postinstall": "node web3-patch.js"
},

Method 2

Use a module that will allow you to extend Angular CLI: ngx-build-plus or @angular-builders/custom-webpack

Execute schematic

ng add ngx-build-plus

Create webpack.config.js

module.exports = {
  node: { crypto: true, stream: true }
};

Update angular.json

"architect": {
  "build": {
    "builder": "ngx-build-plus:browser",
    "options": {
      ...
      "styles": [
        "src/styles.css"
      ],
      "scripts": [],
      "extraWebpackConfig": "webpack.config.js" <== add this
    },
    "configurations": {
      ...
  },
  "serve": {
    "builder": "ngx-build-plus:dev-server",
    "options": {
      "browserTarget": "cli1125:build",
      "extraWebpackConfig": "webpack.config.js" <== add this
    },
    ...
  },
like image 30
yurzui Avatar answered Sep 18 '22 20:09

yurzui