gpt4 book ai didi

javascript - 编写自定义 webpack 解析器

转载 作者:搜寻专家 更新时间:2023-11-01 00:38:16 24 4
gpt4 key购买 nike

我计划在我的 webpack 项目中使用一组更复杂的约定来导入 Assets 。所以我正在尝试编写一个插件,该插件应该重写请求的模块定位器的一部分,然后将其传递给解析器 waterfall .


假设我们只想

  • 检查请求的模块是否以# 字符和
  • 如果是这样,将其替换为 ./lib/。默认解析器现在应该查找新的模块定位器。

这意味着当文件 /var/www/source.js 执行 require("#example") 时,它实际上应该得到 /var/www/lib/example.js.


到目前为止,我已经弄清楚我显然应该使用 the module event hook以此目的。这也是选择的方式by other answers不幸的是,这对我帮助不大。

所以这是我对自定义解析插件的看法,非常简单:

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 = Object.assign({}, init, {
request: './lib/' + init.request.slice(1)
})

// Continue the waterfall with modified payload
callback(null, modified)
} else {

// Continue the waterfall with original payload
callback(null, init)
}
})

}

但是,使用它(在 resolve.plugins 中)不起作用。运行 webpack,出现以下错误:

ERROR in .
Module build failed: Error: EISDIR: illegal operation on a directory, read
@ ./source.js 1:0-30

显然,这不是做事的方式。但是由于我找不到太多关于此事的示例 Material ,所以我有点不知所措。


为了使其更易于重现,我已将此确切配置放入 GitHub 存储库中。因此,如果您有兴趣提供帮助,您可以获取它:

git clone https://github.com/Loilo/webpack-custom-resolver.git

然后只需运行 npm installnpm run webpack 即可查看错误。

最佳答案

Update: Note that the plugin architecture changed significantly in webpack 4. The code below will no longer work on current webpack versions.

If you're interested in a webpack 4 compliant version, leave a comment and I'll add it to this answer.

我找到了解决方案,它主要是通过读取小的 doResolve()in the docs 触发的.

解决方案是一个多步骤过程:

<强>1。运行 callback() 不足以继续 waterfall 。

为了将解析任务传递回 webpack,我需要替换

callback(null, modified)

this.doResolve(
'resolve',
modified,
`Looking up ${modified.request}`,
callback
)

(2.修复webpack文档)

文档缺少 doResolve() 方法的第三个参数 (message),导致在使用此处显示的代码时出错。这就是为什么我在将问题提交给 SO 之前找到 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
)
}
})

}

关于javascript - 编写自定义 webpack 解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43969772/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com