#reactjs #webpack #next.js
#reactjs #webpack #next.js
Вопрос:
Я хочу добавить следующее в свою конфигурацию webpack!
module.exports = {
...otherConfig,
plugins: [
new CopyPlugin([{
from: './node_modules/@pdftron/webviewer/public',
to: './dist/public/webviewer'
}]
),
],
};
Однако, поскольку я использую Next.js , Я следую документам здесь:
https://nextjs.org/docs/api-reference/next.config.js/custom-webpack-config
Это мой код, с которым я в итоге столкнулся:
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
// Note: we provide webpack above so you should not `require` it
// Perform customizations to webpack config
const newconfig = config.plugins.push(
new CopyPlugin([
{
from: './node_modules/@pdftron/webviewer/public',
to: './public/webviewer',
},
]),
);
// Important: return the modified config
return newconfig
},
}
Почему это не работает?
В этом и заключается ошибка:
ready - started server on http://localhost:3000
ValidationError: Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.
- options[0] misses the property 'patterns'. Should be:
[non-empty string | object { from, to?, context?, globOptions?, filter?, toType?, force?, info?, transform?, transformPath?, noErrorOnMissing? }, ...] (should not have fewer than 1 item)
at validate (D:CodeJavascriptnextjs-projectsnew-amsterdamnode_modulescopy-webpack-pluginnode_modulesschema-utilsdistvalidate.js:104:11)
at new CopyPlugin (D:CodeJavascriptnextjs-projectsnew-amsterdamnode_modulescopy-webpack-plugindistindex.js:40:31)
at Object.webpack (D:CodeJavascriptnextjs-projectsnew-amsterdamnext.config.js:8:13)
at getBaseWebpackConfig (D:CodeJavascriptnextjs-projectsnew-amsterdamnode_modulesnextdistbuildwebpack-config.js:136:360)
at async Promise.all (index 0)
at async HotReloader.start (D:CodeJavascriptnextjs-projectsnew-amsterdamnode_modulesnextdistserverhot-reloader.js:14:2403)
at async DevServer.prepare (D:CodeJavascriptnextjs-projectsnew-amsterdamnode_modulesnextdistservernext-dev-server.js:15:414)
at async D:CodeJavascriptnextjs-projectsnew-amsterdamnode_modulesnextdistclinext-dev.js:22:1 {
errors: [
{
keyword: 'required',
dataPath: '[0]',
schemaPath: '#/required',
params: [Object],
message: "should have required property 'patterns'",
schema: [Object],
parentSchema: [Object],
data: [Object],
children: [Array]
}
],
schema: {
definitions: { ObjectPattern: [Object], StringPattern: [Object] },
type: 'object',
additionalProperties: false,
properties: { patterns: [Object], options: [Object] },
required: [ 'patterns' ]
},
headerName: 'Copy Plugin',
baseDataPath: 'options',
postFormatter: null
}
Заранее благодарю вас!
Ответ №1:
Код в вашем ответе правильный, и я надеюсь, что смогу помочь объяснить, почему. Были две ошибки, которые я мог видеть в вашем исходном коде, о котором идет речь:
1. copy-webpack-plugin был настроен неправильно.
Ваша первоначальная конфигурация представляла собой массив с одним объектом:
new CopyPlugin([
{
from: './node_modules/@pdftron/webviewer/public',
to: './public/webviewer',
},
]),
Но чтобы получить желаемый результат, вам нужно было предоставить плагину объект конфигурации с ключом «patterns» (который содержит массив), как вы сделали в своем ответе:
new CopyPlugin({
patterns: [
{
from: './node_modules/@pdftron/webviewer/public',
to: './public/webviewer',
},
],
})
Сообщение об ошибке, которое вы опубликовали в своем вопросе, объясняет, как плагин был неправильно настроен, просто не самым интуитивно понятным способом:
ValidationError: Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.
- options[0] misses the property 'patterns'. Should be:
[non-empty string | object { from, to?, context?, globOptions?, filter?, toType?, force?, info?, transform?, transformPath?, noErrorOnMissing? }, ...] (should not have fewer than 1 item)
2. Возвращаемое значение вашего метода «webpack» было неверным.
В вашем исходном коде вы назначили переменную «newconfig» для получения результата config.plugins.push(...)
, а затем вернули его:
const newconfig = config.plugins.push(
// ... plugin config ...
// Important: return the modified config
return newconfig
Но, как вы можете видеть из документации MDN по Array.push, возвращаемое значение Array.push — это длина массива.
Поэтому, когда вы писали return newconfig
, это было похоже на написание return config.plugins.length
, когда next.js ожидает, что вы вернете весь объект конфигурации целиком.
Когда вы помещаете элемент в массив, массив изменяется на месте, поэтому вам не нужно записывать новое значение. Поэтому вы могли бы просто вернуть исходную конфигурацию:
// Important: return the modified config
return config
Код из вашего ответа в целом работает так, как должен:
const CopyPlugin = require('copy-webpack-plugin')
module.exports = {
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
// Note: we provide webpack above so you should not `require` it
// Perform customizations to webpack config
config.plugins.push(
new CopyPlugin({
patterns: [
{
from: './node_modules/@pdftron/webviewer/public',
to: './public/webviewer',
},
],
})
)
// Important: return the modified config
return config
},
}
Я не уверен, зачем вам нужно было также удалять и переустанавливать copy-webpack-plugin
пакет, если я чего-то не упускаю.
Ответ №2:
Это глупо, потому что я не понимаю, почему это работает, но…
мой новый код таков
const CopyPlugin = require('copy-webpack-plugin')
module.exports = {
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
// Note: we provide webpack above so you should not `require` it
// Perform customizations to webpack config
config.plugins.push(
new CopyPlugin({
patterns: [
{
from: './node_modules/@pdftron/webviewer/public',
to: './public/webviewer',
},
],
})
)
// Important: return the modified config
return config
},
}
И
Мне пришлось бежать
npm uninstall copy-webpack-plugin --save
npm install copy-webpack-plugin@6.2.1 --save
Теперь ошибок нет… странно
Комментарии:
1. Я также не знаю почему, но я должен предположить, что это несовместимость между последней версией webpack и последней версией nextjs. Я вернулся к версии, которую вы использовали для webpack (6.2.1), и это сработало. Я нахожусь на nextjs 12.0.7.