Why we moved from Angular 2 to Vue.js and why we didn’t choose React
medium.com
medium.com
TypeScript in no way prohibits you from defining a plain old untyped object. Just don't assign a type to it, and it behaves just as it would in plain JS. I wouldn't use Angular 2/4 either, because of its needless complexity and over engineering — but not because of TypeScript. If anything, TypeScript is a bonus.
> React mixes both JSX/HTML with JS code which I just don’t like since I strongly believe in separation of concerns and it looks ugly IMHO.
This is valid only if you think separation of concerns is the same as separation of technologies. I don't think so. It makes more sense to group code based on function.
In fact Vue.js allows single file components that mix HTML, CSS and JS in a way that would violate the author's definition of separation of concern. From Vue.js' documentation: "One important thing to note is that separation of concerns is not equal to separation of file types." [1]
> Coding speed was an area Vue.js won by far, not having to learn JSX was of huge help.
It should take no more than 20 minutes to learn JSX.
1. https://vuejs.org/v2/guide/single-file-components.html#What-...
it should, but in practicality, for most front-end devs especially junior ones, it's not. Moving Angular 1 devs to Vue gets actual work going 3-4 times (anecdotal experience) quicker than with React. For most smaller shops/startups Vue is almost always a better idea - it's much easier finding devs (especially remote/<100k comp ones) with previous Angular 1 experience and the learning curve is alot nicer. React is overengineering for most web apps.
> React is overengineering for most web apps.
This is a peculiar statement, imo. Have you compared the surface APIs of React and Vue? React's API is much smaller. While Vue might be easier, React comes off as simpler.
This 'simplicity leading to complexity' issue reminds me of the many articles that argue why Lisps aren't more popular precisely because they're so powerful/simple.
I'm not experienced enough to know if the argument has merit, but I have noticed that my React projects often end up rather complex because I need so many extra packages to even get a basic app going (beyond the simple Todo demo apps anyways).
The moment I add an extra package, it's yet another choice to make, and yet another thing that makes my project less accessible to others. Where I might use Redux, others might only have experience with Baobab, Fluxt, Nuxxor, FlimFlam, or whatnot.
This situation does seem to be improving: Redux seems relatively 'safe' and standard enough, for example, and then there's stuff like create-react-app. However using Vue.js is still 'simpler' by having a more standardized ecosystem.
While personally I've always preferred simplicity and love React conceptually, I've definitely become more aware of the drawbacks of having a less standardizes ecosystem to work with. And I can definitely confirm that getting people new to front-end development started is much easier with Vue.js.
I even have a suspicion that the logic-in-template stuff, my reasons for avoiding Vue and Angular in the past, is much easier to 'get' by those who are new to front-end development. I'm not entirely sure why, but it's what I've experienced with all my 'students'.
Isn't that exactly what JSX is?
On the other hand, JSX is extremely difficult to read. I can glance at a relatively complex handlebars template I wrote two years ago and instantly understand what it renders. To do the same with a similar JSX component requires spending ten minutes to trace the control flow, understand all the helpers, and mentally re-inline all the loops and conditionals. It's conceptually simple, which is attractive, but in practice that seems to lead to noisy, nonlinear render functions that have little to no structural similarity to their final rendered DOM.
It's also worth noting that JSX is easy to pick up for javascript developers. It's next to impossible for the kind of design-focused frontend people who know HTML and CSS inside and out but only ever needed enough JS to write the occasional jQuery selector. If you're certain your project will never have any styling input from people who aren't first and foremost programmers then JSX might be a great fit, but the rest of us actually have to work with our teams.
* Yes, I know, JSX is technically not a template.
This seems more like a meme than reality. Design is hard. Someone that was able to credentialize in CSS of all things can learn some JS/JSX. Give them some professional courtesy and credit.
Saying that it's "next to impossible" seems kinda toot-my-own-horn dismissive.
As one data point, a number of years back when we needed to hire some frontend developers we actually advertised for Java developers because when we looked for JS devs the quality of candidates we got was abysmal. For another data point, when one company I worked for needed to hire Flex developers (this was a number of years ago) they once again advertised for Java developers, and when I responded asked if I was familiar with and/or willing to learn Flex, which I was. It took me about a month to fully come up to speed with Flex, and I was productive in it within a week.
I see this so much as an argument against React/JSX. I can not never figure out how putting the display logic in the display template is some how going away from separation of concerns.
As for JXF being hard to learn, that is just silly. Sure there are a few quirks but nothing in comparison to a learning a new templating tag language.
- Traditional SoC: template, styling, and logic for my app are separated
- React/ractive/vue/preact SoC: parts of my app - login boxes, payment areas, order displays - are separated. They may further be separated by template, styling, and logic or not.
You're slicing something vertically vs horizontally.
In practice I prefer one of these but saying which one wouldn't help illustrate the concept.
No, they are not. There is no real difference (other then syntax) between
{ rows.map(r=>(<Row data={r} />)) }
and
<div ng-repeat="r in rows"><Row data={{n}}/></div>
These are both logic that have to be run to display your page. The only real difference is that with JSX, it is easy and powerful enough to use that you could stick some non-display logic in there. Easy and powerful should not be an argument against it.
Some people have a little whiplash from all that, and I think it's understandable.
It turns out though that when you do that, it becomes really hard to express some more complicated (but perfectly valid) view logic, and then you end up moving a bunch of your view logic down into your business logic which is the same problem, just in the other direction. JSX takes the straightjacket off and gives you the full power of JS to express your view logic. Yes, it also opens the door to let you do bad things like in-lining all your business logic inside of your views, but realistically nobody is doing that, and the framework strongly discourages doing things like that.
People need to stop blindly following current "best practices" because they change all the time. Weigh up the pros and cons yourself. I personally don't see any difference with doing a loop in JSX and doing a loop in HTML using special tag attributes.
Best practices for web app UIs have changed dramatically as we've went from e.g. server side only logic -> jQuery/AJAX based UIs -> Backbone -> Angular 1 -> React. This clearly shows we've no idea what the "best" way to do things is yet.
Don't do that. Perform loops outside of the final template. People get confused because they don't remember that JSX is just a tree of nested React.createElement function calls, so they decide that they should mix looping logic into a block of JSX because that's what they'd do in PHP even though you'd obviously not do that when looking at raw code.
const MyComponent = (props) => {
const itemList = props.itemData.map((itemData) => {
return <Item data={itemData}/>;
}
return <div><h1>List of items</h1><br/>{itemList}</div>;
}
It's as simple as that. There is never a reason to mix logic into the "template" part of the component.Basically what I'm saying is, if you were just writing React.createElement function calls, it'd be more obvious that the items.map should kept out of the rendering code, e.g.
const MyComponent = function MyComponent(props) {
return React.createElement(
"div",
null,
React.createElement(
"h1",
null,
"List of items"
),
React.createElement("br", null),
props.itemData.map(function (itemData) {
return React.createElement(Item, { data: itemData });
});
);
};
Of course, this is a simplified example, but the more complex the template (i.e. the deeper the nesting) the more the code benefits from having loops and other control structures extracted from the final template.JSX makes expressing dynamic, declarative DOM markup concise enough that a short expression such as: `items.map(item => <FooItem item={item}/>` is no longer overly obtuse/obfuscating.
If the `map` expression becomes much larger, it might make sense to refactor it out in some way. But I would argue that the important guiding principle here is readability and modularity. Drawing a hard line between flow/control structures and "template code" is not useful, in my mind.
As others have stated in this thread, the more useful distinction is between business logic and presentation. Loops rightfully exist in both of those domains.
Which part of what I wrote makes you think I think JSX is an HTML template? The part where I specifically called it "not-html" and the react.createElement code it's translated to "still-not-html"?
That it's kind-of-HTML-but-not, turned into Javascript, turned into shadow-DOM transformations, turned into HTML, is Rube-Goldbergian enough to warrant skepticism. No need to misunderstand it to feel that it's an indication that something somewhere has gone deeply, fundamentally wrong.
And actually I think it'd be fair and consistent to call it a template language, were I inclined to press that point. That it becomes Javascript doesn't change the form it takes when you're writing it. Looks and quacks enough like a duck that insisting it's totally not a duck at all is untenable. Sure, it's translated into shadow-DOM-transforming JS. So? It's not like HTML itself doesn't go through some intermediary representations before becoming different colored glowing pixels on your screen.
If you code in TypeScript and extensively use plain objects and "any" types then you don't get a point of TypeScript and so you better don't use it at all.
> It makes more sense to group code based on function.
The idea of code layers and separation of concern comes form the improving code maintainability and testability ideas. Generally if you code has no layers, then it won't be convenient to unit test it. So it makes sense to group the files based on the function, so you can for example switch the entire function easily, but not putting all the function related sources code to the single file.
> In fact Vue.js allows single file components that mix HTML, CSS and JS in a way that would violate the author's definition of separation of concern.
Single file components is a term, it's more like junction point for the component's parts, as it allows to reference separate/external files into the component file instead of putting everything inside a single file.
"We were unable to learn how to use TypeScript properly, so let's abandon gradual typing and suffer a net loss in productivity over the longer term."
Angular.2 has been in beta for years. And when it went out of beta it basically became something else. This is not a good thing. It's normal for teams to be excepting at least some level of stability in the library they are using. And now that Angular.X pretends to be using semver, it's going to be even worse.
The Angular team doesn't care about stability or lacked vision when they started 2, but a stable API is a valid expectation for a developer team.
But it's not surprising as frameworks with huge API surfaces like ExtJS have pulled the same trick for years, with the same results. Their downfall is more the consequence of API breaking than anything else.
It's very easy to blame vendors when it's your own poor decision making that got you in the mess to begin with.
If i rely on a beta product, i don't expect a complete rewrite of the API when a stable version is released. That's exactly what happened, several times with Angular. Now you can't have it both ways as a vendor. You can't expect people to try out your product and test it in a professional setting then change everything at the last moment either. Or you're saying developers shouldn't even checkout Angular until it is out of beta. If that's what you're saying then the vendor shouldn't expect broad adoption.
Although I get what people are saying about Beta products, the truth is that different vendors use the term "Beta" with different levels of precision, and thus should not typically be trusted not to pull the rug out from under you in some way if they haven't firmly committed to stability.
But seriously, take a bet on a hip framework and it comes good (like react), good for you . But you can't cry when frameworks change API wildly when they clearly have a beta label on them.
Yes, using a small lib will get you initially there, but then there will be a full rewrite of that too, or it'll become completely abandoned, etc.
Angular at least has some idea of upgrade path.
It really makes me question the validity of the rest of the points.
They could all be valid points, but I wouldn't take any of them purely at face value.
If you read the linked article, it's using a graph of the number of GitHub issues labelled "bug" to justify that languages with strong static types don't reduce the number of bugs which isn't meaningful or convincing...
> The main thing we didn’t like and we still don’t like about Angular 2 is Typescript. I know Angular 2 can be used with Javascript but again, the decision to use Typescript was already taken and from what I understand, using pure Javascript with Angular 2 is not the ideal way you should be using Angular 2. In any case, getting rid of Typescript meant a full rewrite of the project. ... > I still remember how easy to work with Angular 1 was, it certainly had it’s own problems, but it was nice to work with it compared to other frameworks, something that Angular 2 lost somewhere on the way.
I recently moved from Angular 1 because it didn't work well with TypeScript. The rest of my project was in TypeScript and all the bugs were coming from the Angular 1 layer because there was no static checking there.
TypeScript is an enormous improvement over plain JavaScript in my opinion in terms of productivity (better refactoring, better autocomplete) and making your code more robust (no unexpected null/undefined variables, no more mixing up strings and arrays). Ignoring TypeScript for large projects is a big mistake.
Angular 2 felt too verbose and overly complex so I switched to Vue which has decent add ons to work with TypeScript. If you use JSX for Vue templates as well, you get type checking for your templates.
Sure defining a simple JS object has no overhead as opposed to maybe the 15-30 seconds of overhead that creating the Typescript interface entails. But that few additional seconds of overhead gives you this for rest of the (weeks, months and years) of the systems lifetime:
1. Instant IDE/editor code completion and error checking
2. Compile time checked contracts when that object is passed to another function
3. Compile time checks for misspelled or non-existent members of the object.
4. Instant refactoring of member names across files with any number of editors and IDEs
5. A chance to take a little higher level look at the design of your system.
After using Typescript for a couple of years now I've found that when I design my types well the overall design and flow of the system tends towards beauty. That is probably why the Haskell folks are always over on the sidelines smirking.Vue just renders components. There's no state management, built in routing, or any of the other things you get for free with Ember/Angular/etc.
By the time you slap all of that on top, you may have well just stuck with Angular. I noticed in React by the time you added the required add-ons (mobx or redux, polyfills, react router, styled components) it was extremely heavy. Furthermore, maintaining these addons, with their own release cycles and bugs is an additional burden on a team.
That's not really true anymore; there is now an official router[1] and state management library[2] for Vue. You don't have to use them, but I think the comparison is still completely fair.
Vuex and Vue Router are recommended from the official Vue website, used by most Vue users and work seamlessly together. What else are you missing?
The kind of things I want to build with Vue with Vuex and Vue Router are the same kinds of things I could build with Angular 1 and Angular 2 so the comparison makes sense to me.
React is more a just view library than Vue, Vue is a complete framework actually with built-in reactivity (no MobX thing needed). Redux state management (which is not always needed) and routing nowadays are separate modules in case of all the frameworks, including Vue.
But yeah, they're trying to be productive in the short term, so it's probably not worth overanalyzing whether a distaste of static typing isn't emblematic of other issues. Getting things rolling has a higher priority...
https://en.wikipedia.org/wiki/Setun
Knuth has also hypothesized that we may one day start producing ternary computers again due to their efficiency and elegance.
Sure, you shouldn't use them unless you really have to, but "really have to" is a line that is difficult to discern. Dijkstra himself noted, "The exercise to translate an arbitrary flow diagram more or less mechanically into a jump-less one, however, is not to be recommended. Then the resulting flow diagram cannot be expected to be more transparent than the original one."
There's many other mistakes, like not having access to component state for custom validators and the infamous change detection errors. Sometimes the error messages border on horrific, reminds me of debugging assembly. Some of these issues don't have any good solutions.
The needless complexity is true. Like every bad framework it makes easy things difficult while at the same time piling on "magic" that's often not useful.
The author is dead wrong on Typescript. Typescript is the best tool I've added to my web development stack in years. Shortly followed by tslint. Once you get used to it the type inference is so good that you only need to even specify the type maybe 1/5 the time.
Vue, on the other hand, has adopted many of the best features of React and responded well to user feedback. I think it's a strong competitor and I can totally understand someone picking Vue over React. I cannot say the same for NG2.
Form validation is a long-solved problem and doing custom validation is a huge pain. Accessing the raw DOM sets off warning bells but in Angular2 it needs to be done for simple things like form field focus. You need to implement FieldValueAccessor for custom fields and the documentation for that sucks.
There's two different form libraries that are largely incompatible. Underneath that several ways to instantiate and manipulate both types of forms. It's so hard to build practical components that Angular2 Material still isn't finished.
If my company wasn't using ng2 extensively I would jump ship for react asap
rather than focusing on "omg html in my js" you should focus on "omg presentation code in my business logic code" because that's when you realize where the real boundary is.
it's one of the reasons i love clojurescript's hiccup so much - i'm still clearly writing idiomatic clojure code but now the boundary is not some arbitrary "this file is named .html and this .js", but actual namespaces/functions, where it's obvious from scope and signature what data my templates depend on.
Mixing bits of different languages "inline" within the same file got a bad rap despite the fact it was often a sensible approach to organizing common logic together.
You write html inside js? or sql inside python? omg noob!
Ironically I think our tools have programmed us to think/operate in a specific fashion that was convenient for IDE .
Just no. many times presentation code is tightly coupled with some desired functionality that drives that presentation. HTML inside JS is just inherently weird. It's one level of counter-intuitiveness to have the HTML set to some variable and put away and referenced further by the var.
It's another level to have html in-line with JS method calls. The two languages just doesn't jive syntactically
that's because you can't escape the notion that DOM must always be represented as HTML and nothing else. [v]DOM is a very well structured entity, and it so happens that our programming languages love structured entities and manipulating them.
I'm not talking about the mental model of writing DOM manipulation code. React still has user write actual HTML syntax.
React has users write HTML-like syntax sugar that turns into createElement calls and i don't like that one bit. Hiccup[1] lets me write idiomatic Clojure code that represents DOM tree using convenient data literals and provides all necessary functions to manipulate it - and that i like.
I consider Angular 4 the first release to produce just about acceptable sized app bundle. On the whole though it's a very ambitious project and I think it will be increasingly hard to ignore, we've currently no intention of changing framework.
Having just upgraded a large AngularJS v1 project to Angular v4, I'm actually very happy with where it's ended up. It feels like a very good combination of power and flexibility. There are still some complex bits, but it feels more like the complexity is necessary and sanely designed, rather than the craziness of what AngularJS's directive stuff evolved into.
I feel purposefulness of Vue's design. There are no gigatons of features and behaviors which make you scratch your head and think "why it is there to begin with" like why Ang2 insists on using observer objects for HTTP responses, or why Ang1 had a such an extensive buildover around its component zoo to do just "new mySerice", or reasons for React's component rendering order peculiarities, or logic behind their choice of syntax.
Vue is very bare bones thing. It provides no reactive layer over complex object with non-primitive content. Lack of native support for maps or sets from ES6 is inconvenient a bit, but it is not hard to provide a function wrapper around any logic that uses them. I usually keep all business logic outside of Vue's instance and only wire though its inputs and outputs.
What I lack in all common frameworks is the ability to play smoothly with really complex DOM manipulations, like swapping prototypes of a DOM elements and mergings. Trying to do something like complex drag and drop logic usually means doing a lot of "do it within DOM element, or do it within framework's element" thinking
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
I'm actually hoping Vue.js builds everything needed for a Reactive minimalist framework and then development slows down similar to the speed of jQuery. I think people are sick of frameworks doing overhauls of their entire codebases every major version release.
I'm not saying that Vue is no good or that it was not a good choice for the author, but the way he described their process makes me think that they optimized the wrong thing.
Also angular-cli and create-react-app are both excellent tools that take a lot of the guess work out of the process, at the very least they show you how to do things right way and keep up to date with what's important.
Angular.X totally lacks of vision. For years it didn't know what it wanted to be, pilling up layers of layers of complexity with IoC containers (useless in a weakly and dynamically typed language such as javascript), Some custom HTML that even needs its own parser, Rx.JS (which is self sufficient if you use it, you literally do not need something on top of that). For what result? it's not faster, snappier in the client, lighter when it comes to the payload, not easier to learn or to test or to use. You don't need some ajax libs either, the fetch API already exists. Angular.X is trying to be the "JEE" of the front-end, except it miss the point of JEE which are a bunch of stable specs, which Angular isn't.
Angular CLI does the compilation, provides the boilerplate management (no need for IDE, if you don't want that), provides the language service (for static checking templates).
Google dogfoods it, they are on the latest rc always. Somehow they can manage the API changes/breaks. (And so far it wasn't much problem for us either.)
I don't know if rx is now a hard or optional dependency, but at least they haven't NIH-ed another Observable lib.
Thanks for sharing some of your learning and having the guts to put it out there, and congrats on shipping the results.
I have a couple of questions:
1) You had two people working on the project - how do you think it would scale out to 10? React's componentized / functional nature allows for that pretty easily which is a consideration for me.
2) Managing JavaScript in templates (html) with Angular 1.x was always weird because you couldn't necessarily tell if the execution was happening in the view or the controller. Does Vue make that any easier when it mixes templates and JS together? I also appreciate knowing that this file is where everything is contained for X element or function.
3) How are the test harnesses?
Not to mention the learning curve even for senior developers. Mithril took me maybe 30 minutes to understand. The entire source (https://github.com/MithrilJS/mithril.js) is easily read in a few hours. They have multiple committers and an active gitter chat room for any problems. Plus you can use JSX if you like it that much. And it has a nice license.
More folks need to try it out.
That being said, I use React more because of the larger community, (easier to find answers, and components) as well as more jobs for React vs Vue.
Also, Fiber introduces better animation performance, which i'll eventually use.
In my opinion Vue is ok for the one kind of projects, with smaller team, smaller project lifetime and Angular is ok for other types of projects. React is alien here, ie not really needed.
In his comparison matrix, why was Reactivity a criteria? Why did Angular score a "Kind-of"? Reactivity is just another word for the framework's underlying change detection logic. Obviously all of these frameworks have that. The fact that he put the term "reactivity" up on a pedestal and rated angular down tells me the lack of understanding on the author's side
The Angular CLI tool is a must! Without it, the friction to get dive into the Angular 2+ world is significantly more.
The main benefit of using React if you are considering using React Native is that you and your team won't need to learn another framework in order to build native mobile apps for iOS and Android - if they know React already, they'll be up to speed with React Native very quickly.
https://weex.incubator.apache.org/ https://github.com/alibaba/weex
I am enrolled in Udacity's React Nanodegree, but recently took a closer look at Vue. It seems to offer everything React does (VDOM, one-way data flow, centralized state management, support for JSX), but without the patent drama.
I previously took a nuanced approach to Facebook's unfair patent license, and will probably never need or want to sue them for patent infringement. But Vue is quite a viable alternative, so I see no reason to reward Facebook's unwillingness to play fair.
I plan to finish the Nanodegree, but will probably be skipping React and using Vue for my own real-world projects.
The speed at which these frameworks pop up is almost exhausting.
[0] https://medium.com/@ericclemmons/javascript-fatigue-48d4011b...
Can anybody share experience with nuxt.js ?
Who has source code in native HTML lying around?