关于handlebars-loader无法按预期处理内联partial的技术求助
我完全懂你的闹心——本来想用{{#*inline}}定义的内联partial填充wrapper里的{{> column1}},结果handlebars-loader直接把它当成了外部文件去加载,最后报错失败,这确实和预期差得有点远。
问题本质
handlebars-loader的默认逻辑是:把所有{{> partialName}}语法都解析成外部文件引用,它并没有自动识别内联partial的机制,所以才会傻乎乎地去寻找column1.hbs这类不存在的文件,最终触发错误。
可行解决方案
你的需求一点都不苛刻,这是Handlebars很常见的用法,只是需要调整下写法或者loader配置就行,这里给你几个靠谱的方案:
方案1:用官方推荐的多内联块写法(最省心)
既然你提到了{{> @partial-block}},其实Handlebars本身支持传递多个命名内联块,只需要把wrapper里的引用改成{{#block "partialName"}}的形式就行:
修改你的index.hbs(写法不用变,保持原来的内联定义):
{{#>wrapper}} {{#*inline "column1"}} This is test for col 1 {{/inline}} {{#*inline "column2"}} This is test for col 2 {{/inline}} {{/wrapper}} {{#>wrapper}} {{#*inline "column1"}} This is another test for col 1 {{/inline}} {{#*inline "column2"}} This is another test for col 2 {{/inline}} {{/wrapper}}
然后调整wrapper.hbs,用{{#block}}调用内联partial:
<div class="wrapper"> <div class="column1"> {{#block "column1"}}{{/block}} </div> <div class="column2"> {{#block "column2"}}{{/block}} </div> </div>
这种写法是Handlebars官方支持的多内联块传递方式,loader不会把{{#block}}当成外部文件,能完美解析你的需求。
方案2:配置loader忽略特定partial名称
如果你坚持要用{{> column1}}的写法,可以在webpack配置里给handlebars-loader加noParse选项,告诉它不要解析这些内联partial的名称:
module.exports = { module: { rules: [ { test: /\.hbs$/, loader: 'handlebars-loader', options: { noParse: [/column1/, /column2/], // 让loader跳过这些partial的文件查找 partialDirs: [path.resolve(__dirname, 'your-partials-folder')] // 保留你的外部partial目录 } } ] } };
这样loader就不会去加载对应文件,而是留给Handlebars运行时去处理内联partial。
方案3:自定义前置loader(进阶玩法)
如果上面的方案都不符合你的习惯,可以写一个极简的前置loader,在handlebars-loader处理前,把{{> column1}}这类引用替换成{{#block "column1"}}{{/block}},再交给handlebars-loader处理。比如写个小脚本:
// inline-partial-loader.js module.exports = function(source) { return source.replace(/{{> (\w+)}}/g, '{{#block "$1"}}{{/block}}'); };
然后在webpack配置里把它放在handlebars-loader前面:
module.exports = { module: { rules: [ { test: /\.hbs$/, use: [ 'handlebars-loader', path.resolve(__dirname, 'inline-partial-loader.js') ] } ] } };
总结
最推荐方案1,用官方的{{#block}}语法,兼容性最好也最容易维护,完全能满足你的需求,根本不算苛刻~
内容的提问来源于stack exchange,提问作者a1mak

