[Angular] Angular 12 (Webpack 5) 更新纪念构建错误处理备忘录
从Angular 12开始,Webpack已经升级到了版本5。
想不是因为那个原因,但在构建时出现了一些错误。
这是一份处理备忘录。
环境
-
- Angular 12.0.4
pdfjs 2.7.570
pdfAnnotate 1.0.14
Node 14.17.0
警告:找不到模块:错误:无法解析 ‘crypto’
发生的事情
在运行ng serve时,会输出这样的消息。
./node_modules/crypto-js/core.js:43:22-39 - Warning: Module not found: Error: Can't resolve 'crypto' in '~/node_modules/crypto-js'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "crypto": false }
解决方案
我安装了 crypto-browserify 包并编辑了 tsconfig.json 文件。
npm i crypto-browserify
{
"compilerOptions": {
...
+ "paths": {
+ "crypto": ["./node_modules/crypto-browserify"]
警告:未找到模块。错误:无法解析 ‘stream’。
发生的事情 de
由于前面的加密内容相同,因此将其省略。
解决方案 cè)
我安装了stream-browserify包,并编辑了tsconfig.json文件。
npm i stream-browserify
{
"compilerOptions": {
...
+ "paths": {
+ "stream": ["./node_modules/stream-browserify"]
警告:CommonJS或AMD依赖可能导致优化终止。
发生的事情
在执行ng serve时,会输出此类消息。
Warning: ~/src/app/app.component.ts depends on 'annotpdf'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
解决方案
根据 https://angular.io/guide/build#configuring-commonjs-dependencies,建议避免使用CommonJS模块,但如果要使用,则需要编辑angular.json文件。
"projects": {
"project-name": {
...
"architect": {
"build": {
...
"options": {
+ "allowedCommonJsDependencies": [
+ "annotpdf"
+ ]
错误:未找到模块:错误:无法解析“fs”
发生的事情 de
在执行ng serve命令时,输出了类似的信息。
./node_modules/annotpdf/lib/annotation.js:121:25-38 - Error: Module not found: Error: Can't resolve 'fs' in '~/node_modules/annotpdf/lib'
解决(未采取)方案
我已经编辑了package.json文件。
+ "browser": {
+ "fs": false
+ }
我听说这样就可以了,但问题并没有解决。
为什么呢?
似乎只需要添加一些配置到Webpack。(?)
我在搜索中找到了一个解决方法是在Webpack的配置中添加以下内容。(?)
resolve: {
fallback: {
fs: false,
},
},
看起来Webpack是在@angular-devkit/build-angular中执行的。
当查找Webpack的配置位置时,发现以下的调用结果在这里被汇总。
-
- getCommonConfig
-
- getBrowserConfig
-
- getStylesConfig
-
- getStatsConfig
-
- getAnalyticsConfig
-
- getCompilerConfig
- getTypeScriptConfig
总结以上内容的结果是这样的。
resolve: {
roots: [projectRoot],
extensions: ['.ts', '.tsx', '.mjs', '.js'],
symlinks: !buildOptions.preserveSymlinks,
modules: [wco.tsConfig.options.baseUrl || projectRoot, 'node_modules'],
mainFields: ['es2015', 'browser', 'module', 'main'],
},
似乎没有空间插入备用方案。 (It seems that there is no room to insert a fallback.)
使用 @angular-devkit/build-webpack 应该可以,但是自己准备Webpack配置看起来很麻烦。。。
追踪错误输出位置
因不太理解,我会追踪源代码。
看起来输出错误消息的是Webpack的Compilation.js文件。
可能的一种翻译为:
出现了ModuleNotFoundError错误,无法解析’fs’,可能是resolveMatchedConfigs引起的。
这表示参考解析器无法解决该问题。
参照解析器由ResolverFactory创建,并实际上由enhanced-resolve承包。
根据enhanced-resolve文档所说,它会遵循Node.js的解析规则来解析。由于fs是核心模块,所以似乎会直接忽略它。
解决方案
有一个很好的东西叫做@angular-builders/custom-webpack。使用它似乎可以覆盖Angular默认的webpack配置。
安装。
npm i -D @angular-builders/custom-webpack
我要对 angular.json 进行修改。
"architect": {
"build": {
- "builder": "@angular-devkit/build-angular:browser",
+ "builder": "@angular-builders/custom-webpack:browser",
"options": {
+ "customWebpackConfig": {
+ "path": "webpack.config.ts"
+ },
"serve": {
- "builder": "@angular-devkit/build-angular:dev-server",
+ "builder": "@angular-builders/custom-webpack:dev-server",
"options": {
"browserTarget": "ex-pdf-annotate:build"
},
新建一个名为 webpack.config.ts 的文件。
import { Configuration } from 'webpack';
export default {
resolve: {
fallback: {
fs: false,
},
},
} as Configuration;
现在能够顺利执行 ng build 和 ng serve 而没有错误了。
请参考以下链接
- https://github.com/ghiscoding/Angular-Slickgrid/issues/769#issuecomment-849573463