#javascript #node.js #reactjs #webpack #plugins
#javascript #node.js #reactjs #webpack #Плагины
Вопрос:
Я обновил свой проект react app до Webpack5. При обновлении я занимался не только Webpack, но и всеми его плагинами, пытаясь проверять их один за другим, чтобы сталкиваться с меньшим количеством проблем, насколько это возможно. Дело в том, что у меня почти сразу возникла эта проблема (которая не возникает, если я удаляю new PeerDepsExternalsPlugin(),
из списка плагинов Webpack. Но любое обновление было выполнено в библиотеке 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] }
Есть идеи? Спасибо
Ответ №1:
Я столкнулся с той же проблемой, оказывается, в репозитории плагина есть открытый 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:
const PeerDepsExternalsPlugin = require('./external-plugin');
Комментарии:
1. красавица, спасибо, что поделилась!