Angular 8升级13后白屏 控制台报crypto属性未定义错误
Angular 13升级后白屏crypto读取报错修复
问题现象
Angular项目从v8升级到v13后,编译、构建流程可正常执行,浏览器访问时出现白屏,控制台抛出错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'crypto')
已安装crypto-js依赖仍无法定位错误触发点。
控制台错误截图:
现有package.json配置
{ "dependencies": { "@agm/core": "1.1.0", "@angular-devkit/build-webpack": "~0.1303.8", "@angular/animations": "^13.3.11", "@angular/common": "^13.3.11", "@angular/compiler": "^13.3.11", "@angular/core": "^13.3.11", "@angular/forms": "^13.3.11", "@angular/platform-browser": "^13.3.11", "@angular/platform-browser-dynamic": "^13.3.11", "@angular/platform-server": "^13.3.11", "@angular/router": "^13.3.11", "@aspnet/signalr": "^1.1.4", "@markpieszak/ng-application-insights": "^7.0.3", "@microsoft/applicationinsights-web": "^2.5.11", "@ttskch/select2-bootstrap4-theme": "^1.2.1", "@types/object-hash": "^1.3.0", "angular2-text-mask": "^9.0.0", "bootstrap": "^4.4.1", "change-case": "^3.1.0", "core-js": "^3.1.3", "crypto-js": "^4.1.1", "escape-string-regexp": "^4.0.0", "google-maps-ng2": "^1.0.10", "jquery": "3.5.1", "lodash": "^4.17.15", "moment": "^2.24.0", "ng2-currency-mask": "^9.0.2", "ngx-order-pipe": "^2.1.1", "node-gyp": "^4.0.0", "object-hash": "^1.3.1", "oidc-client": "1.11.5", "pikaday": "^1.8.0", "popper.js": "^1.14.7", "python": "0.0.4", "replace-in-file": "^5.0.2", "rxjs": "^6.6.7", "rxjs-compat": "~6.3.3", "save": "^2.4.0", "select2": "^4.0.7-rc.0", "select2-bootstrap4-theme": "^1.0.0", "tslib": "^2.0.0", "util": "^0.12.4", "uuid": "^3.3.2", "zone.js": "~0.11.4" }, "devDependencies": { "@angular-devkit/build-angular": "~13.3.8", "@angular/cli": "^13.3.8", "@angular/compiler-cli": "^13.3.11", "@angular/language-service": "^13.3.11", "@types/crypto-js": "^4.1.1", "@types/googlemaps": "^3.36.0", "@types/jasmine": "~3.6.0", "@types/jasminewd2": "~2.0.3", "@types/jquery": "^3.3.29", "@types/moment": "^2.13.0", "@types/node": "^12.11.1", "@types/pikaday": "^1.7.4", "@types/uuid": "^3.4.4", "codelyzer": "^6.0.0", "jasmine-core": "~3.6.0", "jasmine-spec-reporter": "~5.0.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.1.0", "karma-cli": "^2.0.0", "karma-coverage-istanbul-reporter": "~3.0.2", "karma-jasmine": "~4.0.0", "karma-jasmine-html-reporter": "^1.5.0", "protractor": "~7.0.0", "rxjs-tslint": "^0.1.7", "ts-node": "~7.0.0", "tslint": "~6.1.0", "tslint-eslint-rules": "^5.4.0", "tslint-language-service": "^0.9.9", "typescript": "^4.6.4", "typescript-tslint-plugin": "^0.3.1", "webpack": "^5.73.0" } }
根因说明
该错误和crypto-js依赖无关。Angular 8基于webpack4构建,默认会自动注入Node.js核心模块的浏览器端polyfill;升级到Angular 13后内置webpack5,默认关闭了Node核心模块的自动polyfill注入。项目中引用的旧版依赖(oidc-client@1.11.5、uuid@3.x、低版本@microsoft/applicationinsights-web)内部会尝试读取全局crypto对象,浏览器环境下该对象不存在于依赖预期的全局挂载路径上,直接触发undefined读取错误。
修复步骤
- 安装浏览器端Node核心模块polyfill依赖:
npm install crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer process --save
- 打开项目根目录的
tsconfig.json,在compilerOptions节点下添加路径映射,让构建时优先使用浏览器端polyfill替换Node原生模块:
"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"], "url": ["./node_modules/url"] } }
- 打开
src/polyfills.ts文件,在顶部添加全局对象兼容逻辑,适配旧依赖的全局变量读取逻辑:
// 全局对象挂载兼容 (window as any).global = window; (window as any).process = require('process/browser'); (window as any).Buffer = require('buffer').Buffer; // 挂载全局crypto对象兼容旧依赖读取 if (!(window as any).global.crypto) { (window as any).global.crypto = window.crypto || require('crypto-browserify'); }
- 修正依赖位置错误:
@angular-devkit/build-webpack属于构建类依赖,需要从dependencies移动到devDependencies,且版本要和本地@angular-devkit/build-angular版本保持完全一致,避免多版本webpack冲突。 - 可选优化:旧版
oidc-client已停止维护,对webpack5兼容较差,可替换为维护中的oidc-client-ts;将uuid升级到v8以上版本,新版会自动适配浏览器原生window.crypto,无需额外polyfill。
内容的提问来源于stack exchange,提问作者Sankar S
相关产品推荐
相关产品推荐

