The front end of an example full-stack app built using Vue and Node
github.com
github.com
1. Add the backend under same repo.
2. Add a root docker-compose.yml instead of sending interested party to "install backend".
root
| - frontend
| - Dockerfile
| - ... code
| - README.md
| - backend
| - Dockerfile
| - ... code
| - README.md
| - .gitignore
| - README.md
| - docker-compose.yml
ThanksEven though simple projects don't necessarily need Docker to work, they are 100 times better off using Docker than doing things by hand, because that alternative means they are only deploying once and never again (updates, new environment, dev/staging/prod) and that's just not true.
Why?
[1] Are you running this in the cloud? On Google? On AWS? Cloud functions? A containerized VM? Maybe you're running it on an old Mac in your basement. If you're deploying on Linux, you're using lots of bash scripts but -- whoopsie -- those won't work on Windows.
A well written Dockerfile and docker-compose files contain and describe all the dependencies you need and you can copy them to an Ansible playbook or just a script for your choice of OS/environment.
I think that's the only thing I'm strongly opinionated about as a developer.
--- EDIT
This is a classic. Reading the backend "how to run" guide I see:
DATABASE=<your-mongodb-connection-string>
PORT=5000
SERVER_URL=http://localhost:5000
This should settle any debate about docker being "overkill". Developers are notoriously reluctant to install things on their dev machines. As-is this repo has non-trivial setup friction which will reduce # of potential users/testers.TL;DR: docker-compose up
Pretending that using Docker is as easy as "docker-compose up" is either disingenuous, or you simply haven't used Docker as much as I have. Either way, I still contend that Dockerfiles have no room in a source code repository.
btw enabling VT-x is required for other tools as well (Android Studio for device emulation).
Dockerfiles are super useful in a source code repository and has saved me a ton of time.
Not with Docker. Docker makes that problem a thing of the past.
Do you know how many billion dollar companies use Docker in production every day with no breaking?
> Why should that preclude me from a simple "yarn run" or whatever? It's insanity.
because your UI backed by an API is really useless without Postgres :)
I get that my opinion is controversial (and, in fact, I use Docker daily and it has a cozy spot on my resume), but keep in mind that you can say this about all kinds of mediocre technologies that have become massively popular.
The only acceptable alternative to Docker, is, IMHO, a makefile. If I open your project and see a Dockerfile, I'm just going to `docker build && docker run`. If I see a makefile, I'm just going to run `make help ; make run || make`. It greatly reduces the cognitive load if I only want to quickly see what the project does.
Real app built using this - https://github.com/sheshbabu/freshlytics
In a real world situation, I would attach id attributes to the elements for automated QA testing purposes.
And now I am questioning the whole Javascript ecosystem.
With stacks like Vue and Node I always feel I have to do the same work twice. Double models, validation in the front end and validation in the back end, and so on.
With frameworks like Blazor you are much more productive. And I believe this will be the future of developing SPAs.
I think you can substitute Blazor with a large number of frameworks (RoR, Meteor, django, etc) and find a lot of people who believe it is the future of developing SPAs.
I don't even think that bytecode->WASM and Java->JavaScript should be that inherently different for frontend purposes. Then again, I never thought we'd need hyper-optimized JIT compilers for friggin' simplistic UIs, where you'd think that Microsoft BASIC would be fast enough... (Sure, it's great for lunning Linux, Quake or Alexa in the browser…)
But I'll try not ending up sounding facetious. From a code quality and ease of use POV, Blazor might be better, haven't done too much to argue that. And even rebranding the same technology after a few year's of both Moore's law and lessened expectations by users/developers is often a big difference from a marketing standpoint. And that does count, as it increases the community, which is where a lot of projects fail.
Then I saw Bolero (F# framework built on Blazor). Now I'm super interested.
<base-button
v-if="isLoggedIn && currentUser.can('own_topics:write')"
class="new-topic-button"
:to="{ name: 'CreateTopic' }"
>
There is logic embedded in the view. Does this get compile-time checked (assuming you used a compiler such as TypeScript)? In my opinion this is the weak-point of Vue. It is possible to use JSX in Vue. But it is also possible to use non-compile-time-checked expressions. In React you only have compile-time-checkable syntax. That's better because when a code is written using React (by someone other than you) you immediately have some reassurance that some poor coding patterns are excluded.https://github.com/vuejs/vetur/pull/681#issuecomment-3631127...
I'm assuming that is so... Only I've seen some crazy stuff in front-end centric tutorials that seem to assume code injection isn't possible (if by malware or the js console..).
And you're doubly correct, the back-end better verify those requests as well. Can't trust user input, which includes HTTP requests from client apps...
What logic is that? The v-if part? I've done a few larger vue apps where users have many different permissions. I don't see anything wrong with hiding something on the front end if a user doesn't have the permission. What would the alternative be? I remember the days of handling permissions via HTML templating engines... certainly a simple v-if statement in vue is better than that.
I'm sure it's more, it's just not clear to me with my lack of experience in this area.
I'm, obviously, pulling some rabbits out of thin air here but... see this:
import Vue from 'vue'
Not knowing anything about Vue, you can still guess that Vue is serious magic just by looking at the way the code for the project is laid out.That's it.
Ah, but why is it noteworthy?
Cause assume, just for a second, you had a private package, that may also be able to pull rabbits out of dark places, and you had reasons to keep it unpublished. Like, you wouldn't want to release the code, not even in bundled apps. In that case, you would look at this HN item, and repo, and note that, yes, one can release code for a magic based app without releasing the code for the magic lib itself. And that this may allow someone at HN to comment Nice work! Just goes to show how clean and readable [insert magic lib name] code is. And this can start a conversation and lead to opportunities.
And that's worth noting.
But also worth nothing. Cause it's nonsense. You can always do neither.
Edit: I’m not saying this is the reason this specific item is on the front page or commenting on the repo itself (the code looks solid). I’m just herding speculative rabbits.
I apologize for that.
When a rabbit picture is sent over a fax machine, the machine makes a lot of noise. Unfortunately even if one listens intently, one will not be able to see the rabbit. The message still goes through though.
Few weeks ago a colleague suggested Vue for a project. Initially I was skeptical, but as I learn it, my mind is blown. Esp. look at quasar.dev, it's Vue with batteries included.
I've found out however that unit testing works fine for those cases.
Can you summarize what it does? The site isn't clear, but it looks interesting.
My reaction was the opposite of yours - I found the syntax to be some confusing "not really JS" that follows hard-to-discover rules and scoping. It felt very much like JSP - simple enough if you're just dropping in values, but as soon as something gets even slightly complex, it gets ugly quick. Error messages were also far less informative than React (to be fair, React has done a ton in the past couple of years to improve their error messaging).
Example: In react, if I want a <ui> with a bunch of <li>s, I tend to output a JSX <ul> with a bunch of <li>s from some JS loop. A 1:1 relationship between the tags I produce and the tags that are generated. My loop logic is pure JS, so no surprises there.
In Vue, the syntax is:
<ul id="example-1">
<li v-for="item in items"> {{ item.message }} </li>
</ul>Which seems perfectly readable, but...The "<li> tag doesn't represent what gets rendered, it's a TEMPLATE of what gets rendered. Can I reference "item" in another "v-" attribute of the <li>? What happens if I wanted to conditionally include/not-include an <li> for the list of items?
A list shouldn't be where "complex" problems start. A list should still be "simple"
My anecdote doesn't beat yours, (and, generally, your anecdote is the more common one), but I wanted to offer an opposing data point, because I expected Vue to be less involved than React, and I found the opposite to be true.
<ul id="example-1">
<template v-for="item in items">
<li>{{ item.message }}</li>
</template>
</ul>What you have here does fix the 1:1 issue, but introduces an extra layer of abstraction that still feels unnecessary/less straight-forward compared to the React version.
<li v-for="item in items" :title="item.hint"> {{ item.message }} </li>
I really don't have a problem thinking of them as templates. In a sense that's all we can do anyway with dynamic lists— I don't know how React works but it seems disadvantageous to be forced to run the loop again rather than be able to do a diff & DOM insert/splice behind the scenes.My only real complaint is that the HTML attribute gets lost a little too easily. I could probably hack up some syntax highlighting augmentations to fix that, but it doesn't really bother me enough.
For what it's worth, JSX is supported in Vue as well, although I've found it's not really my thing compared to Vue templates.
As you say, rendering a list shouldn’t be where the problems start.
If you want to display only some items of an array, it is recommended to compute a new array that only includes the items you want to display[1]. A less performant way is to put a v-if into your v-for loop[2].
If you have a v-for loop `item in items` you can access `item` in any attribute. See [3] for an example.
[1] https://vuejs.org/v2/guide/list.html#Displaying-Filtered-Sor...
[2] https://vuejs.org/v2/guide/list.html#v-for-with-v-if
[3] https://vuejs.org/v2/guide/list.html#v-for-with-a-Component
Depending on the use-case, I wouldn't want to put the conditional in the template.
Instead, I'd filter the array of `items`. Maybe using a computed property `filteredItems`.
The idea being, you shouldn't be putting Too Much Logic within the template.
Idk though, I started off in Vue and am very much enjoying it; I haven't spent a lot of time dabbling with React yet
To take the example from the Vue docs:
// Component with a slot
<ul>
<li v-for="todo in filteredTodos" v-bind:key="todo.id">
<slot name="todo" v-bind:todo="todo">
{{ todo.text }}
</slot>
</li>
</ul>
// Consuming component
<todo-list v-bind:todos="todos">
<template v-slot:todo="{ todo }">
<span v-if="todo.isComplete">x</span>
{{ todo.text }}
</template>
</todo-list>
This can be rewritten in React with much simpler, cleaner code: // Component with a "slot"
<ul>
{filteredTodos.map(todo => props.renderTodo ? props.renderTodo(todo) : todo.text)}
</ul>
// Consuming component
<TodoList todos={todos} renderTodo={todo =>
`${todo.isComplete ? "x " : ""}${todo.text}`
}/>
Simplicity is key. In the React version you don't have to worry about the `slot` syntax, build a mental model of how Vue treats it, or risk running into the limitations of the feature.I just don't like mixing html and js like that, maybe that's why it also seems messy to me.
The vue example also isn't the greatest, some cruft could be removed using default slot and shorter syntax.
> Where's the span for x?
I assumed Vue was only using the span for v-if, in React we don't need that extra node.
> <li>'s are generated by magic?
Whoops -- an omission on my part. They should be wrapping the inside of the mapping function.
> I just don't like mixing html and js like that, maybe that's why it also seems messy to me.
But this is where the magic is. It's exactly why React didn't need to invent a concept for "slots". I admit it's vaguely unfamiliar at first but if it increases both the power and simplicity of your template it's a no-brainer.
On the second note it's copy-pasted code from the official Vue docs.
Right, and my argument is building this in JavaScript directly (rather than a HTML-ish/JavaScript-ish template language that gets converted into JavaScript) is a better model.
1. https://vuejsdevelopers.com/2017/10/02/vue-js-scoped-slots/ 2. https://2014.jsconf.eu/speakers/sebastian-markbage-minimal-a...
Vue.js uses templates, and the idea of slots already existed in other template languages for years. Angular, ERB/Rails, Razor, Django, Handlebars, Jinja, WPF, even some wikis: all those have the same concept, maybe implemented diferently.
On the other hand, React uses JSX, which is novel and wasn't really used anywhere else before. JSX also has the disadvantage of requiring a very complex toolchain (Babel and Webpack etc), something that Vue.js doesn't require.
The real win here, even if you're familiar with other template solutions, is that you never have to ask the question "How do I do X in template solution Y?". React's JSX "templates" can be fully described in a single sentence: write some (X)HTML and use curly brackets to insert a JavaScript statement that evaluates to a primitive. There are no other concepts to learn provided you know JS and HTML -- and having spent lots of time introducing React to developers of various levels of front-end experience that's something I've come to really appreciate.
That's moving the goalposts. Your point was that Vue invented a new concept and that was a negative. I'm just mentioning how it wasn't an invention at all, it was already a popular concept present in multiple other systems. For people used to templating languages the concept of a slot is not confusing, maybe you just weren't familiar with it?
And it is false to say that JSX doesn't introduce new concepts and rules. The way JS and HTML interact inside JSX is not intuitive at all, and you can't use a lot of JS constructs inside JS, such as `for` loops and `ifs`. Of course there are other ways to solve it, but it's far from intuitive (and the fact that Babel returns "Unexpected token" when you do it doesn't help). For what is worth, passing components inside props in React is also not intuitive, unless someone shows you or tell you it's possible. When you do a few React tutorials you pick it, of course, and that's exactly the same for Vue.js.
Maybe you just find React easier because you learned it first? Maybe do a few tutorial lessons before judging it? Just because something is different or not familiar to you doesn't mean it's worse or is difficult.
Both frameworks are great, there's no need to pit one against each other.
> The way JS and HTML interact inside JSX is not intuitive at all, and you can't use a lot of JS constructs inside JS, such as `for` loops and `ifs`
You didn't read my one sentence definition. It has to be a statement that evaluates to a primitive. Obviously putting a for loop doesn't work there -- how could it? If you find yourself faced with that desire the obvious solution is to call a function that does whatever `for` and `if` statements you want and returns a value.
> Maybe you just find React easier because you learned it first? Maybe do a few tutorial lessons before judging it? Just because something is different or not familiar to you doesn't mean it's worse or is difficult.
I think it says a lot about your argument that you have to keep questioning my credentials and experience. I've been doing web development for a long time, React is closer to the twentieth framework I've used than the first. It's a big part of my job to build infrastructure for web development and teach the fundamentals to developers who are primarily backend engineers. I've had stellar success with React -- both for the "power users" and those with minimal web development expertise -- and my argument here is attempting to explain why I've had success with React where other frameworks have been struggled.
You say "obviously putting a for loop doesn't work there" but it's nowhere near obvious. Loops in JSX are not obvious. Ternary conditionals are not obvious. HOCs and component slots are not obvious.
Only if you dive deep into how JSX works and how exactly it compiles to JS you're able to develop some intuition and figure those things out by yourself, but before you do, you have to do like every other framework (including Vue.js) and learn from the documentation and from examples.
I also like React and JSX, but I think you are biased towards some piece of tech just because you're more familiar with it.
Or because I spent more than half my career fuddling with sub-optimal technologies (up to and including Angular and Vue) and React had good answers for most of my complaints.
> Loops in JSX are not obvious.
Because loops don't exist in JSX. It is obvious, because it's not clear how you would even write one. Maybe someone might naively try something like this:
const Todo = props => {
return (<ul>
{for (todo in props.todos) {
<li>{todo}</li>
}}
</ul>)
}
And get a perfectly reasonable JavaScript error: expression expected. This is just an orphaned loop, like you tried to put a loop in an argument to a function. From there it's an easy step (or a quick stack overflow) to figure out that you need to use the loop to build your array before inserting it into the JSX. Once you've seen this pattern, ternaries and "slot" components become obvious.I can vouch for all of this being very easy to learn -- I'm constantly impressed by how quickly my students pick up "advanced" React concepts. Anecdotal evidence, sure, but it makes my life easy that I can explain the entire React+JSX API in 20 minutes and under a dozen slides.
Anyways, I like Vue. I think it has some great ideas -- but I wouldn't use it without JSX and at that point I might as well use React. It's my conviction that templates are misery and I'll champion any technology that gets us away from them.
Actually the error in CRA/Webpack/Parcel/Codesandbox/Babeljs.io is "Parsing error: Unexpected token", which is hardly intuitive and not all that reasonable.
> From there it's an easy step (or a quick stack overflow) to figure out that you need to use the loop to build your array before inserting it into the JSX
Maybe v-for wouldn't be "confusing" to you if you had the same attitude towards Vue. And maybe if you were less biased (as you admit you are against templates) and less extremist you'd see that students are quick to pick up concepts that you find confusing in Vue.js too.
Again, my opinions are formed from doing this for a living, and honestly I've spent much more time in my career working with templates than I have with JSX. I've built non-trivial applicatons with PHP, RoR, JSP, Django, Mustache/Handlebars, Angular, Vue, yada, yada, yada. This is coming from an informed opinion, not thoughtless favoritism. Not sure what else I can say to you.
https://jasonwatmore.com/post/2018/07/14/vue-vuex-user-regis...
The explanations are great, and the layered structure is nice and clean.
I've tried React and the learning curve was just too high for me. Learning Vue has been a joy by comparison.
https://hackernoon.com/your-node-js-authentication-tutorial-...