mixmaxhq / rollup-plugin-handlebars-plus

Rollup plugin to compile Handlebars templates including support for partials and more.
https://www.mixmax.com/careers
MIT License
17 stars 9 forks source link

Сouldn't get partials working well #12

Open greebamax opened 6 years ago

greebamax commented 6 years ago

Hi, I'm trying to use your plugin to manage Handlebars templates, but I'm getting the following errors when trying to build my simple app.

src/main.js → build/main.js...
(!) Unresolved dependencies
https://github.com/rollup/rollup/wiki/Troubleshooting#treating-module-as-external-dependency
_testPartial.html (imported by src/client/js/views/message.html)
_testCommonPartial.html (imported by src/client/js/views/message.html)
created build/main.js in 793ms

I followed your example but it doesn't work for me. You can see sample repo here.

Even if I solve the problem of how the rollup resolves modules using relative paths (see below) I start getting an error on runtime.

<!-- src/index.html -->
<div>{{> './_testPartial' }}</div>
<div>{{> '/_testCommonPartial' }}</div>

Exceptions:

  "Error: The partial ./_testPartial could not be found  ...
  "Error: The partial ./_testCommonPartial could not be found  ...

Could you please help me with what I'm doing wrong?

greebamax commented 6 years ago

Looking through the code I was found that rollup-plugin-root-import is expected to have leading slash in module id to decide either should target module to be resolved or not:

    // file: node_modules/rollup-plugin-root-import/dist/index.js:313-329
    resolveId: function resolveId(importee, importer) {
      // Don't try to resolve the entry unless we have explicit roots.
      if (!importer && hadNoRoots) return;

      if (importee[0] === '/') {
        // If we've cached this import, don't bother trawling the filesystem
        // again.
        var cached = cache[importee];
        if (cached) return cached;

        return resolve(importee, imports).then(function (resolved) {
          // Save this in the cache in case we see it again.
          cache[importee] = resolved;
          return resolved;
        });
      }
    }
  };

So to solve the importing issue with common partials which I describe in issue above we need to add leading slash in hbs template end remove ending slash from config

<!-- src/index.html -->
<div>{{> '/_testCommonPartial' }}</div>
// rollup.config.js
...
const partialRoots = [
  `${__dirname}/src/common/views`
];
...

But still it isn't possible to import partials by its names. I was noticed that partials always should be resolved by rollup-plugin-root-import by adding all directories which contains views into partialsRoot of rollup-plugin-handlebars-plus configuration. Rollup attempts to register partials by its full paths when trying to resolve it by itself. It cause runtime error because Handlebars invokes partials by its relative path. See final bundle below:

...
var Template = runtime$2.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
        var helper;

    return "<p class=\"message-body\">"
        + container.escapeExpression(((helper = (helper = helpers.message || (depth0 != null ? depth0.message : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"message","hash":{},"data":data}) : helper)))
        + "</p>";
},"useData":true});
// attempt to register partial by its full name
runtime$2.registerPartial('/Users/greebamax/Projects/rollup-hbs/src/client/js/views/_testPartial', Template);
...

return "<div>"
        // invokes partial by its relative path which was used in parent layout
    + ((stack1 = container.invokePartial(partials["./_testPartial"],depth0,{"name":"./_testPartial","data":data,"helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "</div>\n<div>"
    + ((stack1 = container.invokePartial(partials["/_testCommonPartial"],depth0,{"name":"/_testCommonPartial","data":data,"helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "</div>";
...

I believe it would be better to provide similar interface to register partials as it is used for helpers

ba55ie commented 4 years ago

We had the same issue. I wrote a quick and dirty plugin based on this one. It contains a recursive function that checks for partials within a Handlebars (partial) template.

https://gist.github.com/ba55ie/21045ca9f29f08fa4092798c0f31e3c1