Closed ngraef closed 5 years ago
Nice feature! Did you test it?
I tested (diff -r
) against the official project
, nano
, module
, and project-typescript
templates with default options to verify the generated file trees and contents were identical before and after this change.
Additionally, I tested the new functionality on my personal template that uses {{serviceName}}.service.js
. More complex handlebars expressions like file{{#hasFlag}}.flag{{/hasFlag}}.js
don't currently work because of the /
character. We could add support for transforming {{:helper}}
into {{/helper}}
when passed to the renderer, but I left that out for now because I'm not aware of all the cross-platform naming restrictions.
If you have suggestions for additional tests, I'd be happy to do that.
Great!
Actually, why is /
cause problem in renderer? It is used in file contents.
Actually, why is
/
cause problem in renderer? It is used in file contents.
Short answer: the problem isn't in the renderer, it's in the file system reader. Most file systems don't allow /
in file names because it is a directory separator. As far as I understand it, macOS will let you create file names with /
but when that's exposed to the command line tools, it's replaced with :
. For example, test/file.js
appears as test:file.js
.
So the problem is that metalsmith tries to load the file from filename(which is a template) earlier than handlebars renders the correct filenames.
From my experiments, metalsmith loads the files just fine. The problem is that the filename metalsmith sees contains :
instead of /
, which breaks the handlebars template. Example:
file{{#hasFlag}}.flag{{/hasFlag}}.js
.file{{#hasFlag}}.flag{{:hasFlag}}.js
(notice the :
substitution).file{{#hasFlag}}.flag{{:hasFlag}}.js
and fails because the :
token is invalid.I see a couple solutions:
{{:
with {{/
before sending it to handlebars. Something like
const fixed = filename.replace(/({{):/g, '$1/');
render(fixed, metadata, function (err, res) { /**/ });
My experiments have only been on macOS so far. More research is needed to see how other platforms handle /
in file names.
This change adds the ability for
moleculer init
to evaluate handlebars template expressions in file names. For example, a template could define a fileservices/{{serviceName}}.service.js
, which could outputservice/my-service.service.js
. This evaluation respects theskipInterpolation
meta property.