我在一家拥有自定义require
实施的公司工作。该实现允许您仅在已下载模块时才需要该模块。如果代码路径依赖于模块,但代码路径始终不会被命中,那么模块并不总是必需的。这大大减少了我们的文件大小。
这是一个如何有用的例子:
if (page === PROFILE) {
// ProfileHelper should already be downloaded if we're on the profile page.
if (isRequired('ProfileHelper')) {
const ProfileHelper = require('ProfileHelper');
ProfileHelper.doSomething();
} else {
LogError('ProfileHelper isn\'t loaded on the profile page.');
}
} else if (page === FEED) {
// FeedHelper should already be downloaded if we're on the feed page.
if (isRequired('FeedHelper')) {
const FeedHelper = require('FeedHelper');
FeedHelper.doSomething();
} else {
LogError('FeedHelper isn\'t loaded on the feed page.');
);
}
ProfileHelper
未加载到Feed页面上,FeedHelper
未加载到个人资料页面上。 Webpack有这样的东西吗?
这里有一个潜在的解决方案:https://github.com/webpack/webpack/issues/526
然而,这是从2年前开始的,而且代码看起来非常hacky。有没有更好的办法?如果这仍然是最好的方法,请通过答案告诉我,我会将其标记为正确答案。
编辑以澄清:
如果我一直需要ProfileHelper
和FeedHelper
,那么其中一个模块将被闲置。在任何给定的页面上最多只能下载其中一个。
这与重复数据删除无关。
修改
该公司为不同的页面生成许多不同的包,但这些包共享许多文件。这些文件根据他们所处的页面表现不同。通常,并非文件引用的所有模块都将用于给定页面。在这种情况下,这些文件根本就没有捆绑。
答案 0 :(得分:3)
Webpack将对所需的所有模块进行多次重复数据删除,并且已经加载的模块将不会再次初始化(遵循CommonJS规范)。所以,基本上,只需直接要求所有依赖项,然后重新设置!
更重要的是:如果您使用网络包,请不要包装您的要求。用于确定实际使用的模块的静态分析将停止正常工作,并且webpack将捆绑太多。
答案 1 :(得分:0)
这种方法与捆绑webpack是对立的。
require语句指示webpack编译什么。它不会编译你的条件要求,因为那些将在运行时进行评估(但是webpack包是预编译的),webpack不会将它们中的任何一个添加到你的包中。
您正在寻找的是代码分割:https://webpack.js.org/guides/code-splitting-require/
教程:
答案 2 :(得分:0)
从您的问题和评论看来,ProfileHelper
是通过单独的<script>
标签加载的,并且在window
范围内可以立即使用,而无需进一步的异步加载。
此外,此帮手似乎不受requireIfLoaded
的管理,如果尚未加载,则将抛出该帮手。
因此,在这些假设下,requireIfLoaded
的作用只是检查模块在window
下是否可用,如果没有,则抛出错误。
所以...为什么不创建自己的requireIfLoaded
?
function requireIfLoaded(file) {
let m = window[file];
if(m) {
return m;
} else {
throw new Error(`Cannot find module '${file}'`)
}
}
我错过了什么吗?
答案 3 :(得分:0)
我找到了说明此问题的文档。它说 “尽管有各种加载JavaScript的选项,但仍然无法下载JavaScript文件并将其设置为在任意时间执行。您可以说立即执行,也可以推迟到DOM文档完成,但是可以t指定其他时间来执行代码。“