Как правильно передавать параметры в конфиг webpack при выполнении скрипта сборки?

Не могу понять как работает передача параметров в конфиг вебпака (версия вебпака 5). Какое-то странное поведение.

Вот конфиг вебпака, webpack.config.js:

const path = require('path');

module.exports = (env, argv) => {
  return {
    mode: env.mode,
    entry: './src/index.js',
    output: {
      filename: 'main.js',
      path: path.resolve(__dirname, 'dist'),
      clean: true
    }
  }
};

Вот конфиг самого node-проекта, package.json:

{
  "name": "mywebpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^5.93.0",
    "webpack-cli": "^5.1.4"
  }
}

Вот так я вызываю скрипт билда:

npm run build --env mode=development

Ожидаемое поведение - что у параметра env в функции из конфига вебпака появится поле mode, значением которого будет строка "development". Но на деле этого не происходит, я получаю ошибку

[webpack-cli] Unknown command or entry 'mode=development'

из которого понятно, что никакого env.mode нет.

Если добавить в скрипт билда произвольный параметр, например вот так:

"scripts": {
    "build": "webpack --env foo=bar"
  }

И снова запустить npm run build --env mode=development, тогда env.mode заполняется. Я могу судить об этом по изменению в конечном файле main.js, внутри него появляется девелоперская "мишура", а если передать production, то соответственно она исчезает.

Т.е. выглядит так, что если в описании скрипта не описано ни одного параметра, то объект под параметры попросту не создается. Но стоит нам описать хотя бы один параметр в описании скрипта, то мы сможем при вызове этого скрипта передавать хоть 10 параметров и все они станут полями первого параметра (env). Так это работает? Это первый вопрос.

Плюс не понятно назначение второго параметра, argv. Судя по документации, в него должны собираться все параметры при запуске скрипта, которые мы передаем через -- (а не через --env). Т.е. например если npm run build --hello="Hello, world!", то в argv.hello будет строка "Hello, world!". Однако это не так:

const path = require('path');

module.exports = (settings, argv) => {
  console.log("argv.hello=" + argv.hello);  // argv.hello=undefined

  return {
    mode: argv.mode,
    entry: './src/index.js',
    output: {
      filename: 'main.js',
      path: path.resolve(__dirname, 'dist'),
      clean: true
    }
  }
};

В документации правда передавали --mode=production, т.е. можно подумать будто так нельзя передавать произвольные параметры, а только известные вебпаку, вроде mode. Однако я пробовал и --mode так передавать, он тоже undefined. Как в итоге правильно пользоваться этим вторым параметром argv? Это второй вопрос.


Ответы (1 шт):

Автор решения: johnymkp

Дело оказалось в том, что npm принимал параметр на свой счет, поэтому ошибка. Так что если в описании скрипта не описано ни одного параметра, тогда запускать скрипт надо с дополнительным -- в начале, вот так:

npm run build -- --env mode=development

Тогда будет работать.

А argv попросту не работает в вебпаке, начиная с 5 версии, для КАСТОМНЫХ параметров. Т.е. через argv можно передавать только параметры, известные вебпаку, например, mode. История с -- применима и тут:

npm run build -- --env message="Hello, webpack!" --mode=development

--mode мы могли бы передать не только после env, но и до.

→ Ссылка