Update:请注意,webpack 4 中的插件架构发生了显着变化。下面的代码将不再适用于当前的 webpack 版本。
如果您对 webpack 4 兼容版本感兴趣,请发表评论,我会将其添加到此答案中。
我找到了解决方案,主要是通过读取小doResolve()
line 在文档中 https://webpack.js.org/api/plugins/resolver.
该解决方案是一个多步骤过程:
1. 跑步callback()
不足以继续瀑布。
为了将解决任务传递回 webpack,我需要替换
callback(null, modified)
with
this.doResolve(
'resolve',
modified,
`Looking up ${modified.request}`,
callback
)
(2.修复webpack文档)
文档缺少第三个参数(message
) 的doResolve()
方法,导致使用此处所示的代码时出错。这就是为什么我放弃了doResolve()
当我在提出问题之前找到它时的方法。
我已经提出了拉取请求,文档应该很快就会修复。
3.不要使用Object.assign()
看来原来的请求对象(名为init
在问题中)不得通过重复Object.assign()
传递给解析器。
显然,它包含欺骗解析器查找错误路径的内部信息。
所以这一行
const modified = Object.assign({}, init, {
request: './lib/' + init.request.slice(1)
})
需要替换为:
const modified = {
path: init.path,
request: './lib/' + init.request.slice(1),
query: init.query,
directory: init.directory
}
就是这样。为了看得更清楚一点,这是整个MyResolver
上面的插件现在可以使用提到的修改:
function MyResolver () {}
MyResolver.prototype.apply = function (compiler) {
compiler.plugin('module', function (init, callback) {
// Check if rewrite is necessary
if (init.request.startsWith('#')) {
// Create a new payload
const modified = {
path: init.path,
request: './lib/' + init.request.slice(1),
query: init.query,
directory: init.directory
}
// Continue the waterfall with modified payload
this.doResolve(
// "resolve" just re-runs the whole resolving of this module,
// but this time with our modified request.
'resolve',
modified,
`Looking up ${modified.request}`,
callback
)
} else {
this.doResolve(
// Using "resolve" here would cause an infinite recursion,
// use an array of the possibilities instead.
[ 'module', 'file', 'directory' ],
modified,
`Looking up ${init.request}`,
callback
)
}
})
}