Reputation: 416
I want to add the following to my webpack config!
module.exports = {
...otherConfig,
plugins: [
new CopyPlugin([{
from: './node_modules/@pdftron/webviewer/public',
to: './dist/public/webviewer'
}]
),
],
};
However, since I'm using Next.js, I follow the docs here: https://nextjs.org/docs/api-reference/next.config.js/custom-webpack-config
This is my code that I ended up with:
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
},
}
Why doesn't it work?
This is the error:
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:\Code\Javascript\nextjs-projects\new-amsterdam\node_modules\copy-webpack-plugin\node_modules\schema-utils\dist\validate.js:104:11)
at new CopyPlugin (D:\Code\Javascript\nextjs-projects\new-amsterdam\node_modules\copy-webpack-plugin\dist\index.js:40:31)
at Object.webpack (D:\Code\Javascript\nextjs-projects\new-amsterdam\next.config.js:8:13)
at getBaseWebpackConfig (D:\Code\Javascript\nextjs-projects\new-amsterdam\node_modules\next\dist\build\webpack-config.js:136:360)
at async Promise.all (index 0)
at async HotReloader.start (D:\Code\Javascript\nextjs-projects\new-amsterdam\node_modules\next\dist\server\hot-reloader.js:14:2403)
at async DevServer.prepare (D:\Code\Javascript\nextjs-projects\new-amsterdam\node_modules\next\dist\server\next-dev-server.js:15:414)
at async D:\Code\Javascript\nextjs-projects\new-amsterdam\node_modules\next\dist\cli\next-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
}
Thank you in advance!
Upvotes: 8
Views: 14085
Reputation: 416
The code in your answer is correct, and I hope I can help to explain why. There were two errors I could see in your original code in question:
Your original configuration was an array with one object:
new CopyPlugin([
{
from: './node_modules/@pdftron/webviewer/public',
to: './public/webviewer',
},
]),
But to get the result you wanted, you needed to provide the plugin with a configuration object with the key "patterns" (which contains an array), like you did in your answer:
new CopyPlugin({
patterns: [
{
from: './node_modules/@pdftron/webviewer/public',
to: './public/webviewer',
},
],
})
The error message you posted in your question explained how the plugin was incorrectly configured, just not in the most intuitive way:
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)
In your initial code, you assigned the variable "newconfig" to get the result of config.plugins.push(...)
, and then returned it:
const newconfig = config.plugins.push(
// ... plugin config ...
// Important: return the modified config
return newconfig
But, as you can see from the MDN docs on Array.push, the return value of Array.push is the length of the array.
Therefore, when you wrote return newconfig
, that was like writing return config.plugins.length
, when next.js is expecting you to return the entire config object.
When you push an item to an array, the array is modified in place, so you don't need to capture a new value. Therefore, you could simply return the original config:
// Important: return the modified config
return config
The code from your answer, in its entirety, works as it should:
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
},
}
I'm not sure why you needed to also uninstall and reinstall the copy-webpack-plugin
package unless there's something I'm missing.
Upvotes: 13
Reputation: 416
This is dumb because I don't understand why this works but...
my new code is this
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
},
}
AND
I had to run
npm uninstall copy-webpack-plugin --save
npm install [email protected] --save
Now no errors... weird
Upvotes: 1