Укажите основные поля веб-пакета в каждом конкретном случае.

Webpack имеет конфигурацию resolve.mainFields: https://webpack.js.org/configuration/resolve/#resolvemainfields

Это позволяет контролировать, какое поле package.json следует использовать в качестве точки входа.

У меня есть приложение, которое использует десятки различных сторонних пакетов. Вариант использования заключается в том, что я хочу указать, какое поле использовать в зависимости от имени пакета. Пример:

  • Для пакета foo используйте поле main в node_modules/foo/package.json
  • Для пакета bar используйте поле module в node_modules/bar/package.json

Некоторые пакеты, на которые я полагаюсь, не связаны должным образом, код, на который указывает поле module, не соответствует этим правилам: https://github.com/dherman/defense-of-dot-js/blob/master/proposal.md Это приводит к тому, что приложение сломаться, если я полностью изменю конфигурацию веб-пакета на:

resolve: {
  mainFields: ['module']
}

mainFields должно быть установлено на main, чтобы в настоящее время приложение работало. Это приводит к тому, что он всегда извлекает версию CommonJS для каждой зависимости и пропускает встряску деревьев. В надежде сделать что-то вроде этого:

resolve: {
   foo: {
     mainFields: ['main']
   },
   bar: {
     mainFields: ['module'],
}

Пакет foo подключается к моему приложению через поле main, а пакет bar подключается через поле module. Я понимаю преимущества treeshaking с пакетом bar и не ломаю приложение с пакетом foo (имеет поле модуля, которое не соответствует синтаксису модуля).


person Sasha K.    schedule 23.07.2019    source источник
comment
У вас есть список/конфигурация того, какой пакет нуждается в какой точке входа? Это то, что вы могли бы создать?   -  person ChrisR    schedule 27.01.2020


Ответы (1)


Один из способов добиться этого - вместо использования resolve.mainFields вы можете использовать параметр resolve.plugins и написать свой собственный преобразователь, см. https://stackoverflow.com/a/29859165/6455628, потому что, используя свой собственный преобразователь, вы можете программно разрешать разные пути для разных модулей.

Я копирую сюда Ricardo Stuven's ответ

Да, это возможно. Чтобы избежать двусмысленности и упростить реализацию, мы будем использовать префиксный хеш-символ в качестве маркера вашего соглашения:

require("#./components/SettingsPanel");

Затем добавьте это в свой файл конфигурации (конечно, вы можете изменить его позже):

var webpack = require('webpack');
var path = require('path');

var MyConventionResolver = {
  apply: function(resolver) {
    resolver.plugin('module', function(request, callback) {
      if (request.request[0] === '#') {
        var req = request.request.substr(1);
        var obj = {
          path: request.path,
          request: req + '/' + path.basename(req) + '.js',
          query: request.query,
          directory: request.directory
        };
        this.doResolve(['file'], obj, callback);
      }
      else {
        callback();
      }
    });
  }
};


module.exports = {
    resolve: {
      plugins: [
        MyConventionResolver
      ]
    }
    // ...
};
person Tripurari Shankar    schedule 28.01.2020