Webpack 2+: как применять разные загрузчики для файлов с одинаковым расширением?

Вот мой вариант использования: большинство svg должны быть встроенными. Поэтому я устанавливаю такое правило:

{test: /\.svg$/, use: "svg-inline-loader"},

В некоторых случаях мне просто нужен URL-адрес svg, а не его встраивание. В webpack 1.x они требовались мне так: require('path/to/file.svg?external').

Вот соответствующее правило:

{test: /\.svg\?external$/, use: "file-loader!image-webpack-loader"},

Похоже, что webpack 2 больше не включает часть ? при testing для правила, поскольку только первое правило применяется ко всем моим svgs после миграции.

Есть ли способ обойти это? Может быть, есть другая стратегия применения разных наборов загрузчиков для файлов одного и того же расширения при их requireинге?

PS: Я знаю, что мне может понадобиться такой файл: require('!file-loader!image-webpack-loader!path/to/file.svg'), но мои загрузчики немного сложнее этого, и я не хочу постоянно повторять их настройку.

PSS: похоже, это тоже не работает (по-прежнему применяется только первое правило)

{test: /\.svg$/, use: "svg-inline-loader", exclude: /\?external/},
{test: /\.svg$/, use: "file-loader?!image-webpack-loader", include: /\?external/}

person Daniel    schedule 06.02.2017    source источник


Ответы (3)


Недавно я посетил выступление Юхо Вепсяляйнена из webpack и нашел ответ в этот слайд:

{
  test: /.css$/,

  oneOf: [
    {
      resourceQuery: /inline/, // foo.css?inline
      use: 'url-loader',
    },
    {
      resourceQuery: /external/, // foo.css?external
      use: 'file-loader',
    },
  ],
}

resourceQuery спешит на помощь!

person Daniel    schedule 18.04.2017
comment
У меня такая же проблема. Я хочу использовать менее загрузчик для файлов *.less по умолчанию и пользовательский загрузчик для файлов *.less?module. Но я не хочу добавлять что-то вроде ?default ко всем файлам '.less'. Можешь поделиться своим конфигом? - person c4off; 05.07.2017
comment
oneOf использует первое правило сопоставления. Итак, для вашего варианта использования поместите resourceQuery: /module/ в первую запись и вообще не resourceQuery во вторую. - person Daniel; 05.07.2017
comment
@Даниэль, спаситель жизни! - person Vishal Sharma; 04.06.2021

resolveLoader.alias будет решением для вас.

Ваш конфиг будет выглядеть так:

resolveLoader: {
  alias: {
    myLoader1: "svg-inline-loader", // and much more
    myLoader2: "file-loader!image-webpack-loader" // and much more
  }
}

и использование:

require('myLoader1!path/to/file1.svg');
require('myLoader2!path/to/file2.svg');

Или, если вы хотите, чтобы, например, конфигурация myLoader1 использовалась по умолчанию и время от времени использовались загрузчики myLoader2, используйте такую ​​конфигурацию:

{
  test: /\.svg$/,
  use: "svg-inline-loader" // and much more
}

// ...

resolveLoader: {
  alias: {
    myLoader: "file-loader!image-webpack-loader" // and much more
  }
}

и используйте так:

require('path/to/file1.svg'); // default svg-inline-loader
require('!myLoader!path/to/file2.svg'); // specific file-loader!image-webpack-loader
// ! at the beginning - disables loaders from default
// and myLoader enables file-loader and image-webpack-loader

PS. У меня был аналогичный вопрос здесь для веб-пакета 1, но документация говорит, что resolveLoader.alias работает так же.

person Everettss    schedule 06.02.2017
comment
Ах гениально! Да, это действительно очень полезно :) - person Daniel; 07.02.2017
comment
Похоже, что цепочка загрузчиков не поддерживается: require('!myLoader!path/to/file2.svg'); приводит к ./file-1234.svg!image-webpack-loader - person Daniel; 07.02.2017
comment
Спасибо большое, пытался разобраться как отключить дефолтные загрузчики... потратил кучу времени, не зря, но тем не менее... простой восклицательный знак в начале пути... лол - person maqduni; 04.05.2019

В дополнение к test вы можете указать include/exclude условий. Из документов по параметрам конфигурации:

{
    test: /\.jsx?$/,
    include: [
      path.resolve(__dirname, "app")
    ],
    exclude: [
      path.resolve(__dirname, "app/demo-files")
    ]
    // these are matching conditions, each accepting a regular expression or string
    // test and include have the same behavior, both must be matched
    // exclude must not be matched (takes preferrence over test and include)
    // Best practices:
    // - Use RegExp only in test and for filename matching
    // - Use arrays of absolute paths in include and exclude
    // - Try to avoid exclude and prefer include
}
person simon04    schedule 06.02.2017
comment
Я только что попробовал, и мне не повезло. Я обновил свой ответ, чтобы показать, что я сделал. - person Daniel; 06.02.2017