Какие загрузчики заказов применяются в Webpack?

Я пытаюсь настроить загрузку файлов .pug с помощью Webpack в зависимости от временного расширения имени файла, при этом оно должно быть по умолчанию. В моем случае файлы, имена которых заканчиваются на .vue.pug, должны быть загружены по другим правилам, чем простые .pug.

В приведенной выше настройке часть { test: /\.vue.pug$/, /* ... */ } связана с фреймворком Vue, и мне порекомендовали разработчики @webdiscus/pug-loader. Последняя часть (test: /(?!.*\.vue\.pug$).*\.pug$/) — это загрузчик по умолчанию для файлов Pug.

{

  // ...

  module: {

    //
    rules: [

      // === Loading of Pug from files related with Vue
      {
        test: /\.vue.pug$/,
        oneOf: [
          // allow <template lang = "pug"> in Vue components
          {
            resourceQuery: /.vue$/u,
            loader: '@webdiscus/pug-loader', // <-- it is same pug-loader as in PugPlugin.loader
            options: {
              method: 'html', // render Pug into pure HTML string
            },
          },
          // allow import of Pug in JS/TS and for "other cases", if a file hasn't the extension `.vue`
          {
            resourceQuery: ".vue.ts",
            loader: '@webdiscus/pug-loader', // <-- it is same pug-loader as in PugPlugin.loader
            options: {
              method: 'compile', // compile Pug into template function, use it if you want pass custom data into template on clinet-side rendering.
              //method: 'render', // compile Pug into template string, use if your template has't external custom data, generates smallest file
              //esModule: true, // should be `true` for importing in ES module, e.g. `import tmpl from './myTemplate.pug';`
                              // defaults is false, used for CommonJS, e.g.  `const tmpl = require('./myTemplate.pug');`
                              // NOTE: this option is optional, if it is not defined, importing in ES module works too.
            },
          },
        ],
      },

      // Loading of Pug from files not related with Vue
      {
        test: /(?!.*\.vue\.pug$).*\.pug$/,
        loader: '@webdiscus/pug-loader',
        options: {
          method: 'render'
        },
      },

    ]
  },

  // ...

};

Хотя постройка выполняется без ошибок, если запустить скрипт в браузере, то получим ошибку:

Uncaught TypeError: _ExampleMultipleFilesComponent_vue_pug__WEBPACK_IMPORTED_MODULE_0___default(...) is not a function

Если удалить часть ниже и не импортировать файлы .pug в файлы, отличные от vue, ошибки не будет.

{
  test: /(?!.*\.vue\.pug$).*\.pug$/,
  loader: '@webdiscus/pug-loader',
  options: {
    method: 'render'
  },
}

Похоже я не понимаю, как Webpack выбирает подходящий загрузчик. Пожалуйста, объясни.

Репозиторий репродукций (убедитесь, что вы проверяете ветку @problem/default_loader)

Они загружаются снизу вверх, и ответ на этот вопрос дан здесь: stackoverflow.com/a/32234468/258174, а также в их документации. Я не понимаю, почему нельзя просто определить два правила с помощью test: /\.vue\.pug$/ и test: /\.pug$/, а затем использовать include или exclude соответственно?

morganney 16.05.2024 16:24

@morganney, спасибо за ссылку. В упомянутом вами ответе оба загрузчика будут активированы. Но что, если требуется только один из них?

Takeshi Tokugawa YD 19.05.2024 03:34
Поиск всех неиспользуемых файлов в проекте
Поиск всех неиспользуемых файлов в проекте
Количество файлов в проекте растет по мере его развития. И если быть по-настоящему честным, их продвижение происходит в геометрической прогрессии...
Настройка шаблона Metronic с помощью Webpack и Gulp
Настройка шаблона Metronic с помощью Webpack и Gulp
Я пишу эту статью, чтобы поделиться тем, как настроить макет Metronic с помощью Sass, поскольку Metronic предоставляет так много документации, и они...
3
2
71
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Хотя постройка выполняется без ошибок, если запустить скрипт в браузере, то получим ошибку:

Я не могу воспроизвести ошибку в браузере (FireFox). В браузере я вижу скомпилированные компоненты Vue:

Example single file component
Example multiple files component with custom variable "someText": Hello Pug!

Объясните, как работает мопс-погрузчик

{
  test: /\.pug$/,
  oneOf: [
    // [1] issuer is VUE file
    {
      resourceQuery: /^\?vue/u,
      loader: '@webdiscus/pug-loader',
      options: {
        method: 'html', // exports rendered HTML sting
      },
    },
    // [2] issuer is TS file
    {
      loader: '@webdiscus/pug-loader',
      options: {
        method: 'compile', // export compiled template function
      },
    },
  ],
}

Вы загружаете куда угодно файл Pug .pug, затем Webpack выбирает правило для обработки этого файла через загрузчик.

Важно, где загружается файл Pug, поскольку для каждого issuer (родителя) будет генерироваться ожидаемый результат.

У вас есть два типа эмитентов:

  1. Vue файл. Если вы используете код Pug в файле Vue, например. в ExampleSingleFileComponent.vue, затем в Webpack выберите загрузчик [1] с параметрами рендеринга Pug в чистую строку HTML, как и ожидается в данном случае.

  2. TS файл. Если вы загружаете файл Pug в TS/JS, например. в ExampleMultipleFilesComponent.vue.ts затем в Webpack выберите [2] загрузчик с параметрами для компиляции файла Pug в JS template function. Эту функцию шаблона вы можете вызвать с переменными, чтобы преобразовать ее в HTML во время выполнения в браузере.

пожалуйста, обновите версию с @webdiscus/pug-loader на 2.11.0

biodiscus 03.05.2024 18:56

Спасибо за ответ и комментарий. Я обновил репозиторий репродукций, включая обновление зависимостей. Теперь вы получите сообщение об ошибке в своем браузере. Что касается предустановки Webpack, в моем случае я установил `test: /\.vue.pug$/,, not test: /\.pug$/, so it must be applied only for files ends with .vue.pug. But for some reason, the loader with test: /(?!.*\.vue \.pug$).*\.pug$/` загружает ExampleMultipleFilesComponent.vue.pug. Ошибка в регулярном выражении?

Takeshi Tokugawa YD 11.05.2024 05:03

Я готов дать приз репутации за объяснение, которое решит эту проблему. Надеюсь, это будет ваш. Если вы будете так любезны и просмотрите репозиторий репродукций, убедитесь, что вы извлекли ветку @problem/default_loader.

Takeshi Tokugawa YD 11.05.2024 05:05

@TakeshiTokugawaYD Я создал пиар в твоей ветке. Пожалуйста, прочитайте мои комментарии в коде. Вкратце: ваша конфигурация веб-пакета была неправильной ;-)

biodiscus 11.05.2024 12:29

Спасибо за пул реквест! Я проверил ваши комментарии, и теперь воспроизведение работает нормально. Но почему я спросил: «Какой порядок...?» Мне нужно интегрировать специальный загрузчик Pug, который загружает Pug AST для файлов с определенным временным расширением имени файла (например, «**.myext.pug»). Ваш пресет довольно прост и понятен, но я полагаю, что для решения моей проблемы мне нужно его глубоко изменить. Именно поэтому я попробовал { test: /(?!.*\.vue\.pug$).*\.pug$/ }. Извините, но чтобы решить этот вопрос, мне нужно понять, как загружать файлы с определенным расширением с помощью определенных загрузчиков.

Takeshi Tokugawa YD 12.05.2024 03:40

Я объединил ваш запрос на включение, и теперь в ветке master есть новейший код. Также я добавил PugAST_Loader в проект. Пожалуйста, подскажите мне, как применить этот загрузчик только для файлов pug с определенным временным расширением имени файла (например, «**.myext.pug»).

Takeshi Tokugawa YD 12.05.2024 03:42

нет-нет, ваш PugAST_Loader.ts не будет работать. Какова цель вашего загрузчика AST? Что это делает? Какой результат возвращается?

biodiscus 12.05.2024 11:43

Любой загрузчик веб-пакета будет вызываться, когда правило загрузчика соответствует требуемому/импортированному файлу или файлу из записи. Но в вашей основной ветке PugAST_Loader нигде не используется. Сделайте, пожалуйста, ветку с примером с вашим вариантом использования в исходном коде и с ожидаемым результатом.

biodiscus 12.05.2024 11:50

@TakeshiTokugawaYD, обычно вместо { test: /(?!.*\.vue\.pug$).*\.pug$/ } следует использовать правильную конфигурацию: { test: /\.pug$/, exclude: /\.vue\.pug$/ }

biodiscus 12.05.2024 20:27

ОК, спасибо за помощь! Я принял и проголосовал за ваш ответ.

Takeshi Tokugawa YD 17.05.2024 02:10

На ваш вопрос, загрузчики в Webpack выполняются снизу вверх по массиву конфигурации. Например, для массива загрузчиков [1, 2, 3, 4, 5] порядок выполнения будет 5->4->3->2-> 1. Каждый загрузчик обрабатывает модуль, а затем передает преобразованный модуль следующему загрузчику в последовательности, позволяя нескольким загрузчикам изменять код.

В конфигурации вашего Webpack вы используете функцию oneOf. Это позволяет вам настроить список загрузчиков, которые применяются только на основе определенных условий, таких как resourceQuery. Когда загрузчик верхнего уровня, например, для файлов .pug, находит совпадение, Webpack затем проверяет список oneOf. В отличие от основной конфигурации, где загрузчики работают снизу вверх, oneOf проверяет сверху вниз. Используется только первый загрузчик, соответствующий списку oneOf, и после этого он перестает следить за ним. Таким образом, изменения, внесенные этим загрузчиком, не передаются другим загрузчикам в списке oneOf.

Другие вопросы по теме