Angular12升级至13时“require()不支持ES模块”错误修复问询
问题描述
将Angular从12版本升级至13版本后,应用启动时控制台抛出require() of ES Module not supported错误。已完成所有适配Angular 13的依赖包更新,尝试过删除node_modules、package-lock.json、dist目录后重新执行npm install,但编译生成的main.js中仍然通过require引入platform-browser模块,导致启动失败。
使用环境版本
- Node.js 16.20.0
- TypeScript 4.4.3 / 4.6.0
报错详情
Error: require() of ES Module
/node_modules/@angular/platform-browser/fesm2015/platform-browser.mjs
not supported. Instead change the require of
/node_modules/@angular/platform-browser/fesm2015/platform-browser.mjs
to a dynamic import() which is available in all CommonJS modules.
at __node_internal_captureLargerStackTrace (node:internal/errors:477:5)
at new NodeError (node:internal/errors:387:5)
at Module.load (node:internal/modules/cjs/loader:1009:11)
at Module._load (node:internal/modules/cjs/loader:846:12)
at f._load (electron/js2c/asar_bundle:2:13330)
at o._load (electron/js2c/renderer_init:2:3109)
at Module.require (node:internal/modules/cjs/loader:1035:19)
at require (node:internal/modules/cjs/helpers:102:18)
at 7258 (main.js:1:1070126)
at r (runtime.js:1:127)
at R (main.js:1:2708253)
at main.js:1:2708270
at n (runtime.js:1:3008)
at main.js:1:57
依赖配置(package.json)
"dependencies": { "@angular/animations": "~13.4.0", "@angular/cdk": "^13.3.9", "@angular/common": "13.4.0", "@angular/core": "13.4.0", "@angular/forms": "~13.4.0", "@angular/material": "^13.3.9", "@angular/platform-browser": "~13.4.0", "@angular/platform-browser-dynamic": "~13.4.0", "@angular/router": "~13.4.0", "@grpc/grpc-js": "^1.2.12", "angular-plotly.js": "^1.8.0", "archiver": "^4.0.2", "async-waterfall": "^0.1.5", "blockly": "^5.20210325.0", "bootstrap": "^4.5.2", "chokidar": "^3.5.2", "crypto-js": "^4.0.0", "dom-to-image": "^2.6.0", "downloads-folder": "^3.0.1", "electron-json-storage": "^4.5.0", "electron-log": "^4.4.1", "exceljs": "^4.3.0", "file-saver": "^2.0.2", "form-data": "^4.0.0", "google-protobuf": "^3.13.0", "http-server": "^0.12.3", "jquery": "^3.5.1", "lodash": "^4.17.21", "masonry-layout": "^4.2.2", "moment": "^2.29.1", "moment-timezone": "^0.5.32", "ng-circle-progress": "^1.5.1", "ng-click-outside": "^6.0.0", "ngx-filter-pipe": "^2.1.2", "plotly.js": "^2.9.0", "resize-observer-polyfill": "^1.5.1", "rxjs": "^6.5.3", "rxjs-compat": "^6.6.3", "split2": "^3.2.2", "systeminformation": "^5.11.9", "tslib": "^2.0.0", "yargs": "^17.0.1", "zone.js": "~0.11.4" }, "devDependencies": { "@angular-builders/custom-webpack": "^13.1.0", "@angular-devkit/build-angular": "~13.0.2", "@angular/cli": "~13.0.2", "@angular/compiler": "~13.4.0", "@angular/compiler-cli": "~13.4.0", "@angular/language-service": "~13.4.0", "@types/crypto-js": "^4.0.1", "@types/jasmine": "~3.6.0", "@types/jasminewd2": "~2.0.3", "@types/lodash": "^4.14.168", "@types/node": "^14.14.37", "codelyzer": "^6.0.0", "electron": "^22.2.1", "electron-builder": "^23.1.0", "protractor": "~7.0.0", "ts-node": "~8.3.0", "tslint": "~6.1.0", "typescript": "~4.6.4", "webpack": "^5.84.1", "webpack-node-externals": "^2.5.2" }
解决方法
1. 修复自定义Webpack配置
由于项目使用@angular-builders/custom-webpack,需在自定义Webpack配置文件中添加规则,让Webpack正确处理.mjs文件:
module.exports = { module: { rules: [ { test: /\.mjs$/, include: /node_modules/, type: 'javascript/auto' } ] } };
该配置会让Webpack将Node_modules中的.mjs文件当作普通JavaScript解析,避免CommonJS环境下的加载冲突。
2. 调整Angular构建的模块输出格式
修改angular.json中的构建配置,确保输出模块格式与Angular 13的ES模块规范匹配:
"architect": { "build": { "options": { "target": "es2020", "outputModule": "es2020", // 保留其他原有配置 } } }
Angular 13默认使用ES模块输出,若构建配置仍沿用旧的CommonJS设置,会导致模块加载方式不兼容。
3. 排查第三方依赖的模块格式冲突
部分第三方依赖可能仍使用CommonJS格式,与Angular 13的ES模块输出冲突:
- 尝试升级
angular-plotly.js、ng-circle-progress等第三方库到适配Angular 13的最新版本; - 对于无法升级的包,在Webpack配置中设置优先加载ES模块版本:
module.exports = { resolve: { mainFields: ['module', 'main'] } };
4. 彻底清理缓存后重新构建
除了删除node_modules和package-lock.json,还需清理Angular CLI和npm的缓存:
ng cache clean --all npm cache clean --force
之后重新执行安装和构建:
npm install ng build --prod
5. 调整Electron的模块加载配置
针对Electron环境,需确保其正确处理ES模块:
- 在Electron主进程的启动命令中添加
--experimental-specifier-resolution=node参数; - 或在项目根目录的
package.json中添加:
{ "type": "module" }
注意:设置"type": "module"后,所有CommonJS模块的引入需改为ES模块语法,或使用动态import()。
内容的提问来源于stack exchange,提问作者Daneshwaran M

