8 ms·
I feel like I'm in an alien world when it comes to Vue - it has this weird pattern of making strings do loads of heavy lifting. The Github Commits[1] example o
by zkldi 5y ago
I feel like I'm in an alien world when it comes to Vue - it has this weird pattern of making strings do loads of heavy lifting.
The Github Commits[1] example on their documentation has a load of stuff that just doesn't sit right with me.
Things like
v-for="record in commits"
to loop over something is insane to me - this isn't code, this is a string inside a html attribute! How can you get any sort of good type analysis/variable checking/syntax highlighting inside this?
Similarly, accessing properties like
:href="record.html_url"
has the exact same issues - what if there's a typo here? My IDE can't highlight that this is wrong because it's *not code* and is just a string.
Maybe I'm just the odd one out here, but vue (and angular) love to use strings as a makeshift programming language, which to me is a major smell.
^[1]: https://v3.vuejs.org/examples/commits.html https://v3.vuejs.org/examples/commits.html
- AbuAssar 5y agoThis is not a regular string, it is a template. And the tooling handles it just fine. You get type checking, linting, syntax highlighting etc.
- zkldi 5y agoIf it's a template then it's a very complex one, and under closer inspection it reads almost like storing code in a string and evalling it. Let's say we want to iterate over commits in reverse. A google shows that we can do something like this: v-for="item in items | orderBy 'field' -1" So, there's pipes now, and Vue has essentially re-invented a programming language inside HTML attributes. But then comes this example below it: v-for="item in _.reverse(items)" And this line is terrifying! If this string is able to use lodash, then that means it's able to access the JS global scope, and therefore is very powerful - yet the resulting template is nonsense js, but still at some point involves JS evaluation? Maybe I'm missing something though - I don't use Vue and if something is this big with this approach, I'm definitely missing something. EDIT: A search for *new Function(` calls in the vue github repository shows quite a lot of code that essentially evals strings.
- Drew_ 5y agoI don't know if you haven't had much experience with templating engines, but having the ability to write programmatic expressions to make a layout dynamic is a basic necessity that pretty much every known templating engine has. "It reads like storing code in a string and evalling it" sounds very funny in this context because that's exactly what every solution does and it works pretty well in practice.
- dragonwriter 5y ago> "It reads like storing code in a string and evalling it" sounds very funny in this context because that's exactly what every solution does. Its not, though. JSX-based solutions (not just React, but Solid and others) don't (actually, neither do many frameworks with more traditional-looking templates, including, AIUI, Vue, actually compile templates to render functions, so it just looks like old school “string with embedded code which is evalled” ttemplates)
- Drew_ 5y agoI know it's pedantic but this is still JavaScript we're talking about not binary so the "compiled render function" is still ultimately just "a string that gets evaled". In any case the implementation details aren't important it's what it appears to be that is apparently the problem.
- zkldi 5y ago> it's what it appears to be that is apparently the problem. Yep, Someone mentioned in another part of this thread that Vue compiles most of this out before production, so my remaning confusion pretty much stems from the DSL being a mishmash of html attribute context, vue custom syntax, and evaluated JS.
- zkldi 5y agoMy issue isn't the existance of programmatic expressions (yeah, it's the point of templating languages), but more that the way vue (and angular) do it is a mess of syntaxes that creates a really, really strange template. The lodash example is the main critique because that is not JS, but it involves evaluating JS - it's created its own programming language with its own rules -- when one was right there from the beginning!
- Exuma 5y agoVue is brilliant when you actually use it. Nothing you've mentioned is remotely ever a problem in my experience. Also :href="xxx" isn't a string, that is javascript in there. You won't ever have more than 10 characters at most in an attribute, and if you do you make a method for it and call the method. The other alternative is JSX type stuff in react where you are injecting full JS into the templates which is like committing seppuku to me. Vue is so much nicer to use than react IMO, and I've used both extensively.
- zkldi 5y ago> :href="xxx" isn't a string, that is javascript in there. This is the part I don't really follow, though. Technically: <a href="print(1//3)"></a> href here isn't a string, it's python, but it's stored as a string, representing python. In the :href example for JS, that's not JS - an engine isn't seeing that - that's a string that is evaluated as JS at some point in the vue lifecycle.
- Exuma 5y agoWithout refreshing my knowledge on it, I don't think it's actually a string. A <template> block is actually a "single file component" which is a special vue plugin/loader/whatever for webpack. It compiles template/script/style tags into a single compiled version. I'm like 60% sure that your "string' example is never run in production. So I believe that it gets compiled before vue even sees it (at build time, or dev-server compile time) into the standard method that vue is used to... a vue component: Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' }) https://v3.vuejs.org/guide/single-file-component.html https://v3.vuejs.org/guide/single-file-component.html
- zkldi 5y agoThen that sounds pretty good that it's not ran in production and compiled out! I guess my remaining alien issue is that the DSL for Vue is a mish-mash of JS, custom syntax, dom attribute context and possibly more?
- tomjen3 5y ago>My IDE can't highlight that this is wrong because it's not code and is just a string. Webstorm has zero problems letting me refactor it, because it can parse vue code in .vue files. This is seriously a non-issue.
- pbalau 5y agoA long, long time ago, in a galaxy far, far away, there was a thing called Coldfusion. And js peeps seem to want to reinvent it.
- porker 5y agoMany users - who weren't programmers by training - loved CF for the ease of understanding. They had a DX paradigm that worked and I understand why people try to emulate it. It's a question of audience, and not for the HN crowd.
- otabdeveloper4 5y agoExcept that SPA frameworks are designed to complicate things, not to make them easier to understand. And SPA framework developers are crazy expensive, mor expensive than seasoned C++ systems programmers. (The two facts are probably linked.)
- Exuma 5y agoHave you ever developed a complicated front-end system? Not using a vue/react style framework would be ludicrous (ie, building something like Facebook Ads UI or Google Analytics UI). I find it super bizarre you say "complicate things" when they do 100% the opposite. I would love to understand what you would use if you were tasked with building FB Ads manager interface: https://disruptiveadvertising.com/static/61a4440576bffd6e6a22daba55ba10ac/9d81f/facebook-ads-manager-campaigns-tab.jpg https://disruptiveadvertising.com/static/61a4440576bffd6e6a2...
- otabdeveloper4 5y ago> I find it super bizarre you say "complicate things" when they do 100% the opposite. They're way, way overengineered for the very limited use cases they're designed for. If you're going to ditch the browser API's and re-write the world in Javascript, why not take into consideration all of the history of GUI development and do it right? I.e., make a real layout engine, proper widget hierarchies, real encapsulation, etc. Instead there's some sort of frankenstein in-between state where you've ditched all the benefits of native browser API's but haven't arrived anywhere that's a true paradigm shift. TL;DR - yeah, they make some things easier to reason about, but for any sort of non-standard webapp you'll still need to write an equivalent mountain of hacks and framework adaptors.
- cdrini 5y agoYeah, this isn't really an issue; it's just a templating language. You can get an extension for your IDE to make it syntax highlight correctly. That's like saying a .js file is just a string. Um, yes I guess sure? All code is just a string. HTML is also just a string. Vue's HTML templating syntax is also just a string, but it's also code. It's code that's mainly HTML, with certain spots that allow full JavaScript. And just like normal code, you can have compile time errors, syntax errors, runtime errors, etc. Also as a side note: I'd say the best thing about Vue isn't it's templating system, but the fact that it's truly reactive. In react, only rendering is truly reactive. If you have reactive variables that depend on each other, then you have to manually mark those dependencies. Vue can deduce that dependency graph automatically, which makes coding much easier. It's like a giant spreadsheet.
- ttty2 5y agoWhat about type checks?
- cout 5y agoThis is exactly the point of vue. On the surface, it looks a lot like a cleaner angularjs, but it's very different. There's no need for a digest cycle to re-evaluate watch expressions on each iteration, because it uses getters and setters to detect changes (though it still supports watchers too). Vue is also very different from React, which (when I last used it) required components to implement shouldComponentUpdate. Vue does this at the cost of breaking compatibility with older browsers (which were not old at all when React and Angular 1.0 came out); I think the tradeoff is worth it.
- helsinkiandrew 5y ago> My IDE can't highlight that this is wrong because it's not code and is just a string Code is just a string too, treating the 'code' inside the string literals after the v-for is just an extra level of syntax handling - The IDE I use (Intellij) can handle it just fine.
- ttty2 5y agoFor my in mind-blowing that people still code with plain strings. Why in the world would you ever write text over proper JavaScript language. You lose so many features. For example you lose type check, which it's core to any project. For me it's a no brainer to use an existing language to render stuff. Tsx I know it's not just js, but I can consider as just plan js/ts code. Edit: seems like they do type checking, but I'm pretty sure can't do type checking at the whole file level.
- jansan 5y ago> My IDE can't highlight that this is wrong because it's not code and is just a string. WebStorm and its bigger brother IntelliJ IDEA can handle this.
- lenkite 5y agoWhich IDE are you using ? There is probably a plugin that parses and offers checking for Vue Template Syntax https://v3.vuejs.org/guide/template-syntax.html https://v3.vuejs.org/guide/template-syntax.html
- manigandham 5y agoAll code is text. There is no pure "code" representation, text inside attributes being parsed as JS is no different than parsing text inside some <script> tags. Also modern component-based JS frameworks all work the same way. The UI definition is a template that's compiled into a render function which produces the final output during runtime. Each framework uses different syntax: React uses JSX which is a domain specific language (DSL) that mixes HTMl-like tags into Javascript. Vue uses HTML with directives on top. Angular, Svelte, etc all use their own formats. You can even mix and match (use JSX with Vue) or write your own render function if you want, but it's the same text->parsing->lexing->compilation cycle that every language goes through before turning into actual CPU instructions.
- dmitriid 5y ago> text inside attributes being parsed as JS is no different than parsing text inside some <script> tags. It is different. Because "text inside script tags" is Javascript. Vue's templating syntax is a weird and inconsistent mishmash of custom DSL, Javascript subsets and Javascript expressions. And it also depends on when it's parsed.
- manigandham 5y agoText inside script tags is parsed as JavaScript by default. It can be other languages too, like typescript inside a .Vue file. Again, it’s all just text in different syntax. Programming languages are just a very large and well defined syntax compared to a template language, but that’s all it is. Vue’s directives offer just enough control to handle 99% of scenarios while remaining within HTML.
- dmitriid 5y ago> Text inside script tags is parsed as JavaScript by default. It can be other languages too It can be, but usually isn't. > Again, it’s all just text in different syntax. Again, it's not. And the reason is simple: the browser literally knows nothing about other syntaxes but Javascript [1] So, no, "text in Vue" is literally not the same as "text in script tags". It is a mish-mash of: - Vue's own DSL (see v-for) - JS expressions that are wrapped in some scope (see v-if) - JS-like DSL where function cals are not function calls, there are magic vars, but objects are also fine (see v-on) - Maybe JS expressions in v-bind? But depends on the attribute name? Can use string concatenation, but anything else? - Actual JS expressions in {{}} which can't be used just anywhere... but then these expressions can have pipes into filters in them? And filters once again are JS-like, but are not None of this has any coherent specification, and we rely on Vue to properly parse and break it down into actual Javascript code that can then be included in a <script> tag. Edit: I had the same laundry list of things for Svelte before Svelte 2, but Svelte 3 is significantly more consistent and coherent in what it expects in a template. [1] There are ways to make it know other syntaxes, but that is rare and has largely fallen out of favor.
- midrus 5y agoThis purism is why we can't have nice things.