簡體   English   中英

自 Webpack5 升級以來,PeerDepsExternalsPlugin 中斷了構建,如何解決?

[英]PeerDepsExternalsPlugin breaks the build since Webpack5 upgrade, how to fix that?

我將我的 React 應用程序項目升級到了 Webpack5。 在升級時,我不僅處理了 Webpack,還處理了它的所有插件,試圖一一檢查,以盡可能減少問題。 問題是我幾乎立即遇到了這個問題(如果我從 Webpack 插件列表中刪除new PeerDepsExternalsPlugin(),則不會發生此問題。但是任何更新都在 lib peer-deps-externals-webpack-plugin上完成"^1.0.4"

這是主要的 webpack 配置:

module: {
    rules: [
      {
        test: /\.(js|jsx|tsx)(\?.*)?$/,
        exclude: [/node_modules/],
        use: 'babel-loader'
      },
      {
        test: /\.tsx?$/,
        exclude: [/node_modules/],
        use: 'ts-loader'
      },
      {
        include: path.resolve(__dirname, assetsPath),
        use: [
          {
            loader: 'file-loader',
            options: {
              context: path.resolve(__dirname, 'PRIVATE_PATH'),
              name: '[path][name].[ext]?hash=[hash:base64:5]'
            }
          }
        ]
      }
    ].filter(Boolean)
  },
  optimization: {
    minimizer: [
      new TerserPlugin({
        test: /\.min\.js$/
      })
    ]
  },
  plugins: [
    new webpack.DefinePlugin({
      ASSETS_PATH_PREFIX: `"${getFullAssetPathPrefix()}"`
    }),
    new PeerDepsExternalsPlugin(),
    ...extraPlugins,
    new LintFilename(
      /^(?!(icon|bg|img)-(?!(.*[_A-Z]|[\s]))).*(jpe?g|png|svg)$/,
      path.resolve(__dirname, 'assets/img'),
      'image'
    ),
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, 'lib/**/*.d.ts'),
          to: 'types'
        }
      ]
    })
  ]

這是構建錯誤:

$ webpack --mode production
$ cross-env BABEL_ENV=es babel lib --extensions .js,.jsx,.ts,.tsx --out-dir dist/es
[build:js:frontend-es] Successfully compiled 125 files with Babel (4423ms).
[build:js:frontend-es] yarn run build:js:frontend-es exited with code 0
[build:js:frontend] internal/crypto/hash.js:84
[build:js:frontend]     throw new ERR_INVALID_ARG_TYPE(
[build:js:frontend]     ^
[build:js:frontend]
[build:js:frontend] TypeError [ERR_INVALID_ARG_TYPE]: The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined
[build:js:frontend]     at Hash.update (internal/crypto/hash.js:84:11)
[build:js:frontend]     at BulkUpdateDecorator.update (/project/node_modules/webpack/lib/util/createHash.js:49:14)
[build:js:frontend]     at ExternalModule.updateHash (/project/node_modules/webpack/lib/ExternalModule.js:465:8)
[build:js:frontend]     at Compilation.createModuleHashes (/project/node_modules/webpack/lib/Compilation.js:2726:12)
[build:js:frontend]     at /project/node_modules/webpack/lib/Compilation.js:2064:11
[build:js:frontend]     at eval (eval at create (/project/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
[build:js:frontend]     at /project/node_modules/webpack/lib/optimize/ModuleConcatenationPlugin.js:449:32
[build:js:frontend]     at processTicksAndRejections (internal/process/task_queues.js:75:11) {
[build:js:frontend]   code: 'ERR_INVALID_ARG_TYPE'
[build:js:frontend] }

有任何想法嗎? 謝謝

我遇到了同樣的問題,原來插件的 repo 上有一個開放的 PR

與此同時,我從那個 PR 中刷了代碼,並將其作為external-plugin.js保存在我的項目根目錄中。

'use strict';

const ExternalModuleFactoryPlugin = require('webpack/lib/ExternalModuleFactoryPlugin');

class PeerDepsExternalsPlugin {
  apply(compiler) {
    const peerDependencies = getPeerDependencies();

    // webpack 5+
    if (typeof compiler.options.output.library === 'object') {
      compiler.hooks.compile.tap('PeerDepsExternalsPlugin', ({ normalModuleFactory }) => {
        new ExternalModuleFactoryPlugin(
          compiler.options.output.library.type,
          peerDependencies
        ).apply(normalModuleFactory);
      });
    }
    // webpack 4+
    else {
      compiler.hooks.compile.tap('compile', params => {
        new ExternalModuleFactoryPlugin(
          compiler.options.output.libraryTarget,
          peerDependencies
        ).apply(params.normalModuleFactory);
      });
    }
  }
}

function getPeerDependencies() {
  try {
    const { resolve } = require('path');
    const pkg = require(resolve(process.cwd(), 'package.json'));
    return Object.keys(pkg.peerDependencies);
  } catch(err) {
    return [];
  }
}

module.exports = PeerDepsExternalsPlugin;

然后在我的 webpack 配置中,我將導入更改為使用此文件,而不是 npm 中的 package:

const PeerDepsExternalsPlugin = require('./external-plugin');

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM