这里很长。即使我对答案或解决方案的期望不高(或没有任何期望),仍然感觉像是一个要共享/尝试的有趣的问题。
我有一个带有2个入口点的应用。它们都导入同一个文件main.ts
,而文件又导入了一个Handlebars模板main.hbs
:
entry1.ts
└ main.ts
├ main.hbs
└ …
entry2.ts
└ main.ts
├ main.hbs
└ …
main.ts
还导入了其他TS类(数千个),这些类又导入了其他HBS模板(数百个),但是几乎所有这两个类在两个条目之间共享。这些条目只需使用某些特定于条目的选项从main.ts
调用Main类即可。
有人要求我为HBS模板创建特定于条目的“变体”,以便entry1
将加载main.v1.hbs
,而entry2
将加载main.v2.hbs
(如果有这样的文件)存在。并且,如果其他任何导入的.ts
文件也导入了其他任何.hbs
文件,它们还将返回各自的*.v1.hbs
/ *.v2.hbs
变体。
由于我希望它尽可能自动化,并且对实际源代码的更改尽可能少,所以我决定要走的路是让Webpack“重定向”导入:
entry1.ts
导入main.ts
导入main.hbs
实际加载main.v1.hbs
main.ts
导入的menu.ts
实际上加载了menu.v1.hbs
entry2.ts
导入main.ts
导入main.hbs
实际加载main.v2.hbs
main.ts
导入的menu.ts
实际上加载了menu.v2.hbs
我认为这种方法会给我带来很多好处:
不必更改所需文件中的源代码(实际上是数百个文件)。
如果我对此不关心,则可以使用require with expression,然后使用摇树来仅保留每个条目中使用的模板。但是...
require()
语法,而不适用于ES样式的静态import
,因此与前向兼容甚至可以在“重定向”之前检查是否存在变体文件,如果不存在,则回退到默认文件。
重要的是,随着创建了更多新的“ v2”变体文件,这些文件使我可以逐步进行此过渡,而无需保持静态导入列表以映射到哪个文件或其他文件。 / p>
也许可以在一次编译运行中进行此转换。
如果我不在乎,我可以单独编译每个条目,并在每次运行时设置适当的选项。但是,该应用程序非常大,需要花费几分钟才能构建,甚至需要增加Node内存限制。因此,按顺序或并行构建每个条目并不是太好了,尽管如果没有其他方法,这是我的最后选择。无论如何,考虑到Webpack的功能,我觉得这是我应该可以在单个构建中完成的事情。
这是Webpack内置的插件,乍一看似乎可以满足我的需要:拦截require
对特定模块的调用并将其更改为其他模块,它甚至还具有正则表达式和谓词功能支持。但是,由于映射在编译期间无法更改,因此我很快放弃了这一点。这意味着我不能为每个条目设置不同的替换规则。
现在,我们深入战es。我想,为什么不写自己的装载机来解决这个问题?加载器is capable读取其根条目,因此从理论上讲,我应该能够使用该信息来代替main.hbs
为main.v1.hbs
和{{1 }} entry1
。
尽管这最初看起来很有效(尽管我讨厌这种方法的非无状态性),但我发现Webpack似乎在第一次执行时就缓存了需求/解决方案:在处理main.v2.hbs
时。因此,即使具有所有逻辑,我的加载程序每个文件也仅被调用一次,而不是每个entry2
被调用一次,而且我无法实现我想要的目标。
我研究了告诉Webpack“不要缓存它,下次再读”的方法,我没有运气。由于两个条目都导入main.ts
,而后者仅导入一次require
,因此Webpack会将TS和HBS都视为仅1个模块,而不管它们是否导入到多个条目文件中。我想这是必须要做的优化,但是对于这种特定情况,我没有找到解决的办法。
由于装载机无法满足我的需求,因此我尝试编写插件。我浏览了详细的文档,并尝试使用main.ts
和main.hbs
,但是并没有太过深入。我浏览了compiler
的{{3}},并以相同的方式插入了compilation
(文档似乎没有涵盖)。最终,通过更改适当资源的请求以包含每个条目的“变量”(正是我所需要的),或多或少地重新实现了我以前在插件系统中进行Loader尝试的功能。但是,令人遗憾的是,我遇到了与Loader相同的障碍-文件(和我的代码)只能访问一次。
我还尝试了“从外到内”-查看生成的块,其中每个条目在树中都有HBS文件的模块,但是这些模块已经过处理和编译,这似乎并不意味着成功。
最后,与常规插件类似,我决定尝试使用解析插件。我一直在想:“我只需要这些NormalModuleReplacementPlugin
调用即可解决其他问题,这不难!”
但是那还行不通,存在同样的“钩子每个文件仅被调用一次”的问题,现在我什至无法从所需文件中获取入口点,因为它们甚至还没有得到适当解决。 / p>
因此,如果我可以让我的插件或加载程序告诉Webpack“嘿,下一次我NormalModuleFactory
时该文件将有所不同,请再次检查”,我认为这将解决所有问题并使所有工作正常我想要的方式。
如果这不可能,那么我可能只会恢复到顺序构建:
require
解析为require
的{{1}} entry1.js
解析为*.hbs
的{{1}} 以及刻录时间和RAM。但是你能做什么。
感谢您阅读。
答案 0 :(得分:-1)
我有同样的问题。唯一帮助我的是Webpack Virtual Modules。我根据某些模板动态生成了入口模块的多个实例。因此,这些模块具有不同的ID,并且在条目之间不共享。