8

Webpack 有一个resolve.mainFields配置:https ://webpack.js.org/configuration/resolve/#resolvemainfields

这允许控制应将哪个 package.json 字段用作入口点。

我有一个应用程序可以引入几十个不同的 3rd 方包。用例是我想根据包的名称指定要使用的字段。例子:

  • 对于包,请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如果我将 webpack 配置更改为:

resolve: {
  mainFields: ['module']
}

mainFields必须设置为当前main使应用程序正常工作。这导致它总是拉入每个依赖项的 CommonJS 版本并错过 treeshaking。希望做这样的事情:

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

包通过其字段foo捆绑到我的应用程序中,main并且包通过其字段捆绑到我的应用程序barmodule。我意识到使用包进行 treeshaking 的好处bar,并且我不会使用foo包破坏应用程序(具有不正确的模块语法的模块字段)。

4

1 回答 1

4

实现此目的的一种方法是,resolve.mainFields您可以使用resolve.plugins选项并编写自己的自定义解析器,而不是使用,请参阅https://stackoverflow.com/a/29859165/6455628,因为通过使用自定义解析器,您可以以编程方式为不同的路径解析不同的路径模块

我在Ricardo Stuven's这里复制粘贴答案

是的,这是可能的。为了避免歧义并更容易实现,我们将使用前缀哈希符号作为您的约定的标记:

要求(“#./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
      ]
    }
    // ...
};
于 2020-01-28T12:04:23.507 回答