是否有Webpack配置选项可以覆盖特定导入的"resolve.mainFields"



假设我的Webpack配置中有这个,我需要这样保存:

resolve: { mainFields: ["main", "module"] }

我想使用一个同时包含CJS和ESM模块的包(@azure/storage-blob(,但桶文件不同,所以我需要专门为这个包使用ESM导出("模块"(。我是否可以添加任何Webpack配置选项来覆盖仅针对这一个包的上述mainFields设置?

到目前为止,我只找到了一个有效的解决方案:

resolve: {
mainFields: ["main", "module"],
alias: {
"@azure/storage-blob$": "@azure/storage-blob/dist-esm/storage-blob/src/index.browser.js",
"@azure/core-http$": "@azure/core-http/dist-esm/src/coreHttp.js"
}
}

这是有问题的,因为我正在将一些内部模块路径硬编码到我的Webpack配置中,这些路径可能会在未来的版本中更改。相反,我更愿意告诉Webpack使用";模块";字段而不是";主";在这些情况下。

没有。根据某些配置,这是不可能开箱即用的。Webpack配置的工作方式与此相反,这意味着您可以在模块级别(即模块的发布者(上提供解决方案。在您的情况下,颁发者是您的源文件。因此,您可以通过使用Rule.resolve告诉Webpack在发布者级别(单个源文件级别(使用自定义解析。

您的问题是为每个导入的模块逐个指定mainFields。为了实现这一点,您可以编写一个简单的辅助函数。例如,在webpack.config.js中添加以下函数:

function resolvePackage(packageName) {
// Specifiy here which fields you want to prioritize in the order
const mainFields = ['module', 'main'];
// Read the json of the npm package in question.
const json = require(`${packageName}/package.json`);
const matchedFile = mainFields.find((x) => json.hasOwnProperty(x));
if (!mainFields) {
throw 'No matching file found';
}
return {
[`${packageName}$`]: `${packageName}/${json[matchedFile]}`
};
}

当将上述函数调用为resolvePackage('@azure/storage-blob')时,您会得到一个值:

{ "@azure/storage-blob$": "@azure/storage-blob/dist-esm/storage-blob/src/index.browser.js" }

现在在您的Webpack配置中使用此功能:

module.exports = {
// ..Other configuration
resolve: {
alias: {
...resolvePackage('@azure/storage-blob'),
...resolvePackage('@azure/core-http')
},
mainFields: ['main', 'modules']
}
};

因此,默认情况下,Webpack仍将在序列中使用mainmodules,但对于这些特定的包,它将读取它们的package.json文件,并确定要在alias配置中使用的确切文件。请注意,此函数不考虑新的package.exports字段。解析exports字段非常复杂,您必须根据需要进行解析。

最后,还有一种方法是编写Webpack插件以进行自定义解析。然而,这是复杂的,你将不得不自己处理许多其他的可能性。

最新更新