如何优雅地限制Webpack的`require.context`?

6
我正在使用Webpack和React开发一个小型静态网站生成器。目前我正在使它更加动态化,其中一个部分是使它更加可配置。

假设有这样一种网站结构:

.
├── _book
├── assets
├── build
├── drafts
├── manuscript
├── node_modules
├── pages
├── project_source
└── styles

我只想从特定的一个或多个目录中导入文件。在这种情况下,只需从manuscript导入Markdown文件即可。天真地写var req = require.context('manuscript', true, /^\.\/.*\.md$/)就行了。

问题是当我通过站点生成器配置传递目录时,这需要变成动态的。由于require.context依赖于固定的值,我认为我需要改变上下文到站点根目录,使用类似var req = require.context('.', true, /^.*\.md$/)的代码,然后检查req.keys()来匹配我的配置。

实际上,这种方法非常慢,因为它会遍历整个目录树!特别是node_modules可能包含大量的文件,这是应该尽量避免的。

有没有一种简洁的方法可以将node_modules排除在require.context之外?我想一些形式的正则表达式可能会起作用,但我也接受其他的想法。


调用 require.context 会覆盖先前的上下文吗? - Olim Saidov
你能否使用fs.readdirSync和调用require.context来遍历目录,忽略node_modules文件夹? - Olim Saidov
require.context 应该允许更细粒度的方式来指定目录和最大遍历深度。 - vaughan
@vaughan 是的,我同意。API 不是很理想,正则表达式有点痛苦。如果你有时间,请设置一个问题并链接给我。 :) - Juho Vepsäläinen
@bebraw https://github.com/webpack/webpack/issues/1316 - vaughan
显示剩余3条评论
2个回答

12

你可以尝试:

var req = require.context('.', true, /^((?![\\/]node_modules|vendor[\\/]).)*\.md$/);

排除包含 node_modulesvendor 文件夹路径的匹配。


谢谢!这是个很棒的想法。我可能稍后会尝试一下,因为这将大大简化我的当前配置,并将这些东西隐藏起来,不让最终用户看到。 - Juho Vepsäläinen
这依然很慢,因为正则表达式必须与找到的每个文件进行比较。 - vaughan

0

我最终通过将require.context推到静态站点生成器之外并放在外部配置中来解决了这个问题。我在那里有一些小片段,像这样:

paths: {
    demo: {
        path: function() {
            return require.context('./demo', true, /^\.\/.*\.md$/);
        },
    }
}

然后在生成器端,我只需使用这些上下文。

虽然不是我希望的解决方案,但它能够工作。


不确定这是否是您正在寻找的 https://github.com/webpack/webpack/issues/118 - bsr
谢谢。require.context 到目前为止一直表现得非常好。 :) - Juho Vepsäläinen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接