question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

No mechanism to directly emit a tagged template literal.

See original GitHub issue

Tagged template literals are a ES2015 feature which,afaict, cannot be emitted directly. Template literals have an interesting property where a function can be used as a tag. EG:

function myTemplate(strings, ...args) {                                                                        
  return { strings: strings, args: args };                                                                          
}
var someVar = "test"
var result = myTemplate `string 0 ${someVar} string 1`

Which, result in result having the value { strings: [ "string 0 ", " string 1"], args: ["test"]}

The application of the template literal to the function requires the abstract operation GetTemplateObject to be invoked which performs the splitting of the template into strings and args. ( https://www.ecma-international.org/ecma-262/6.0/#sec-gettemplateobject ) This abstract operation, as best I can tell, does not have an equivalent function at runtime. The language implementation is required to perform the operation when a function is applied to a template literal.

Libraries like lit-element rely on this feature. I’ve tried a few workarounds but none succeeded in implementing the required behavior exactly.

The closest workaround I have is using js.Function to evaluate a function dynamically defined:

    val capture = js.Function("element", s"""                                                                                                                             
function captureTemplate(strings, ...args) {                                                                                                                              
  return { strings: strings, args: args };                                                                                                                                
}                                                                                                                                                                         
function inner() {                                                                                                                                                        
  return captureTemplate`${raw}`;                                                                                                                                         
}                                                                                                                                                                         
return inner.bind(element)();                                                                                                                                             
""").asInstanceOf[js.Function1[js.Object, TemplateCapture]]                                                                                                               

Where raw is the template literal text and TemplateCapture is

  @js.native                                                                                                                                                              
  trait TemplateCapture extends js.Object {                                                                                                                               
    val strings: js.Array[String]                                                                                                                                         
    val args: js.Array[js.Any]                                                                                                                                            
  }                                                                                                                                                                       

This is close enough for my purposes. Only a bit awkward.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
coreyoconnorcommented, May 31, 2019

A good plan IMO. I’ll see about publishing a library with an equivalent.

1reaction
sjrdcommented, May 31, 2019

I’m afraid we don’t add non-essential stuff in the core repo anymore. We encourage people to publish small libraries with that kind of sugar, we’re happy to advertise them on the website, and if they gain traction we can consider them for the stdlib (assuming they relate to the Scala spec and/or the ES spec, which is the case here) once they are completed vetted and super-stable.

An advantage of a separate library in this case would be that it could use macros to rewrite away all the overhead. In the core repo we do not use any macros anymore, since they are not compatible with Scala 3 in the general case.

We want scala-js/scala-js to be 100% stable, backwards binary compatible forever, so we cannot afford introducing anything non-essential.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Template literals (Template strings) - JavaScript | MDN
However, a tagged template literal may not result in a string; ... Template literals coerce their expressions directly to strings, ...
Read more >
21 Using template literals and tagged templates - Exploring JS
Before we dig into the two features template literal and tagged template, let's first examine the multiple meanings of the term template.
Read more >
zspecza/common-tags: Useful template literal tags for ... - GitHub
A set of well-tested, commonly used template literal tag functions for use in ES2015+. Plus some extra goodies for easily making your own...
Read more >
Template literal trapped in a string variable - Stack Overflow
ES6 template strings are designed to be a run-time mechanism to create string literals, not a templating language whose templates can be stored ......
Read more >
@leafac/sqlite - npm
@leafac/sqlite needs the tagged template literal to manage the prepared ... it won't take effect. .migrate() has no mechanism to detect and warn...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found