排错:Angular 项目构建 web3 报错 Module not found: Can't resolve XXX

  • 胡键
  • 更新于 2023-08-02 18:01
  • 阅读 1232

Angular 项目构建 web3 报错 Module not found: Can't resolve XXX

症状

某个 Angular 项目引入 web3 依赖时,构建出现了类似于下面的错误:

ERROR in ./node_modules/@pedrouid/iso-crypto/dist/cjs/helpers/env/node.js
Module not found: Error: Can't resolve 'crypto' in 'node_modules/@pedrouid/iso-crypto/dist/cjs/helpers/env'

ERROR in ./node_modules/@ethersproject/web/lib.esm/geturl.js
Module not found: Error: Can't resolve 'http' in 'node_modules/@ethersproject/web/lib.esm'

ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js
Module not found: Error: Can't resolve 'http' in 'node_modules/xhr2-cookies/dist'

ERROR in ./node_modules/@ethersproject/web/lib.esm/geturl.js
Module not found: Error: Can't resolve 'https' in 'node_modules/@ethersproject/web/lib.esm'

ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js
Module not found: Error: Can't resolve 'https' in 'node_modules/xhr2-cookies/dist'
resolve 'https' in 'node_modules/xhr2-cookies/dist'

ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js
Module not found: Error: Can't resolve 'os' in 'node_modules/xhr2-cookies/dist'

ERROR in ./node_modules/cipher-base/index.js
Module not found: Error: Can't resolve 'stream' in 'node_modules/cipher-base'

ERROR in ./node_modules/keccak/lib/api/keccak.js
Module not found: Error: Can't resolve 'stream' in 'node_modules/keccak/lib/api'

ERROR in ./node_modules/keccak/lib/api/shake.js
Module not found: Error: Can't resolve 'stream' in 'node_modules/keccak/lib/api'

ERROR in ./node_modules/@ethersproject/web/lib.esm/geturl.js
Module not found: Error: Can't resolve 'zlib' in 'node_modules/@ethersproject/web/lib.esm'

分析

由于 Angular 主要是将项目按照浏览器规格进行构建,而报错的这几个 module 比如osstreamfs之流的是 Node API 提供的,在浏览器运行环境是不提供这几个 API 的,因此构建报错,找不到这些 Node 运行环境的 module。

解决方案

Angular 底层使用 webpack,而 webpack 是支持 browserify 的,即在浏览器环境中填充部分 Node API,以便这些模块能在浏览器环境运行起来(如 web3.js 等等)。但是 Angular 本身的配置并不支持自定义 webpack 配置,因此我们需要通过打补丁的方案修正这个配置。

以下内容参考自 gist

package.json:

{...
  "scripts": {
    "postinstall": "node patch.js",
    ...
  }
}

patch.js:

// Angular >= 11
const fs = require("fs");
const f =
  "node_modules/@angular-devkit/build-angular/src/webpack/configs/browser.js";

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

  fs.writeFile(f, result, "utf8", function (err) {
    if (err) return console.log(err);
  });
});
// ----

// For Angular <11
const fs = require("fs");
const f =
  "node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/browser.js";

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

  fs.writeFile(f, result, "utf8", function (err) {
    if (err) return console.log(err);
  });
});
// ----

重新npm i之后再构建项目应该就可以修复这个错误了。

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
胡键
胡键
CSM / 架构师 / 创业者,先后就职于中兴和 SAP,现专注于工业物联网、机器学习和区块链。同时,作为机器学习和区块链技术活动的组织者和分享者活跃于本地社区。