Добавление CopyPlugin в next.config.js

#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.