8
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

[Angular] Angular 12 (Webpack 5)アップデート記念ビルドエラー対処メモ

Angular 12から、Webpackが5になりました。

そのせいではないと思うのですが、ビルド時にいくつかエラーになりました。

これはその対処メモです。

環境

Warning: Module not found: Error: Can't resolve '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"]

Warning: Module not found: Error: Can't resolve 'stream'

起こったこと

先のcryptoと同内容なので省略します。

解決策

stream-browserifyパッケージをインストールし、tsconfig.jsonファイルを編集しました。

npm i stream-browserify
{
  "compilerOptions": {
  ...
+    "paths": {
+      "stream": ["./node_modules/stream-browserify"]

Warning: CommonJS or AMD dependencies can cause optimization bailouts.

起こったこと

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"
+            ]

Error: Module not found: Error: Can't resolve 'fs'

起こったこと

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の設定箇所を探してみると、このへんで下記の呼び出し結果をまとめている様子です。

上記をまとめた結果はこんなんです。

resolve: {
  roots: [projectRoot],
  extensions: ['.ts', '.tsx', '.mjs', '.js'],
  symlinks: !buildOptions.preserveSymlinks,
  modules: [wco.tsConfig.options.baseUrl || projectRoot, 'node_modules'],
  mainFields: ['es2015', 'browser', 'module', 'main'],
},

fallbackを差し込む余地はなさそうです。

@angular-devkit/build-webpackを使えばよいのですが、自前でWebpackの設定を用意するのはしんどそう。。。

エラー出力箇所を追ってみる

よくわからないので、ソースを追ってみます。

エラーメッセージを出力しているのは、WebpackのCompilation.jsのようです。

出力しているModuleNotFoundErrorに渡るCan't resolve '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 buildng serveがエラーなくできるようになりました。

参考リンク

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
8
Help us understand the problem. What are the problem?