My aim in writing this article is simple: I'm going to loosely describe what I am calling the "hard'ish dependencies" (I'll define what I mean by "hard'ish dependencies" momentarily) for the following JavaScript tools:
Now, when I say "hard'ish dependencies," what I mean is anything third-party that is required for the most basic usage and grokking of the tool as a production solution. And, yes, I realize these are not the same types of tools and that comparing their dependencies isn't exactly comparing apples to apples. Still, one should be aware of these details when picking tools of this nature.
So why do this? Well, two reasons. First, believe it or not, gathering all of this information into one spot for quick consumption isn't trivial. I've found myself wanting to mentally compare these dependencies in the past and couldn't easily Google my way to an immediate answer. So, I am scratching my own itch here, to some degree, by writing all this down.
Second, I want to inform and educate developers about the hard'ish dependencies they'll have to learn when choosing a solution (some up-front, though others down the road). This will allow them to make an educated decision pertaining to the potential overhead of learning a tool in-depth. Yes, yes, I know not all these dependences will will have to be learned right away, but walk long with any solution and the dependences will more than likely require mastery.
I am not going to spend much time discussing commonly used "soft dependencies." While many soft dependencies, pragmatically, are hard dependencies, I'll refrain from clouding the issue with too much of a semantical debate about what might not be technically required but pragmatically required (e.g. Angular 2 and TypeScript or React and Babel).
Let's begin with jQuery, since it was the first mainstream JS tool. And, even today, remains the most used JS tool on the web.
Depends on: Nothing
Poor jQuery. Today, it is slighted for not being what it never was: a tool to build complex applications. jQuery, by design, was a tool to script simple web pages and simple applications residing in simple web pages.
This is why I mention it in this article. Because, the truth is, a lot of simple apps (little or no state) could be built as simple web pages (rather than as a single page app aka SPA) and some light DOM scripting with something like Kendo UI (i.e. a jQuery plugin).
Include jQuery in a web page and boom, you're jQuery'ing.
<!doctype html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.1.0.js" integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk=" crossorigin="anonymous"></script>
</head>
<body>
<script>jQuery.fn.jquery || $.fn.jquery</script>
</body>
</html>
I can't seem to take my mind off of the simplicity of one script file, with a single purpose, in a simple HTML page.
Depends on: Nothing
Angular has no hard dependencies. Nope, not even on jQuery. Angular 1 implemented its own lite version of jQuery (aka jqLite) which removed the need for jQuery. However, a lot of developers still use jQuery, which Angular 1 will use over jqLite if jQuery is included before Angular 1.
So as it stands today, to use Angular 1, a developer must only include and minimally learn Angular 1.
<!doctype html>
<html ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
</head>
<body>
<div>
<label>Name:</label>
<input type="text" ng-model="yourName" placeholder="Enter a name here">
<hr>
<h1>Hello {{yourName}}!</h1>
</div>
</body>
</html>
But, don't underestimate learning this one thing. Getting started with Angular 1 is trivial. Learning it is hard.
Depends on: Zone.js, reflect-metadata, and RxJS
To make Angular 2 work you'll need three (maybe four, more on that in a sec) things. Allow me to describe each of these things because chances are these dependencies will be new to you.
A potential fourth dependency, more than likely a hard dependency, will be core-js. Core-js polyfills ES5, ES6, and ES* features.
If you are going to reach for Angular 2, prepare yourself to not only learn Angular 2, but also some of the details around these dependencies.
Below is an example of an Angular 2 app that is not using a module loader or TypeScript (i.e. uses UMD versions of NG2 code).
<!DOCTYPE html>
<html>
<head>
<title>Angular 2 QuickStart JS</title>
<!-- 1.0 Load dependencies -->
<script src="https://npmcdn.com/core-js/client/shim.min.js"></script>
<script src="https://npmcdn.com/zone.js@0.6.12?main=browser"></script>
<script src="https://npmcdn.com/reflect-metadata@0.1.3"></script>
<script src="https://npmcdn.com/rxjs@5.0.0-beta.6/bundles/Rx.umd.js"></script>
<!-- 1.1 Load NG2 dependencies -->
<script src="https://npmcdn.com/@angular/core/bundles/core.umd.js"></script>
<script src="https://npmcdn.com/@angular/common/bundles/common.umd.js"></script>
<script src="https://npmcdn.com/@angular/compiler/bundles/compiler.umd.js"></script>
<script src="https://npmcdn.com/@angular/platform-browser/bundles/platform-browser.umd.js"></script>
<script src="https://npmcdn.com/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js"></script>
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
</body>
<!-- 2. Bootstrap and load NG2 component into app -->
<script>
window.app || (window.app = {})
app.AppComponent =
ng.core.Component({
selector: 'my-app',
template: '<h1>My First Angular 2 App</h1>'
})
.Class({
constructor: function() {}
});
document.addEventListener('DOMContentLoaded', function() {
ng.platformBrowserDynamic.bootstrap(app.AppComponent);
});
</script>
</html>
Depends on: Technically, nothing, but in practice a rendering adapter (e.g. ReactDOM)
It could be said that React doesn't technically have any hard dependencies. No, not even JSX or Babel are absolutely required. However, to render React code, one will have to choose where to render it and this will require an additional hard dependency (React calls it an adapter e.g. react-native, react-art, react-canvas, and react-three).
For example, to render React code to the DOM, potentially in a web browser, you'll have to include the react-dom-15.2.1.js file alongside React. This file provides the DOM-specific methods required to render React components to a DOM tree.
Below is an example of using React in a simple web page.
<!DOCTYPE html>
<html>
<head>
<script data-require="react@*" data-semver="15.2.0" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.2.0/react.min.js"></script>
<script data-require="react@*" data-semver="15.2.0" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.2.0/react-dom.min.js"></script>
</head>
<body>
<div id="example"></div>
<script>
ReactDOM.render(React.createElement(
'h1',
null,
'Hello World'
), document.getElementById('example'));
</script>
</body>
</html>
Note that most people use React with JSX and Babel. But neither of these tools should stop a developer from learning and using React. Simply include react-15.2.1.js and react-dom-15.2.1.js (i.e. an adaptor) in a web page and start writing React code.
Depends on: Node, npm, Bower, jQuery, and QUnit
As far as I can tell, Ember requires the use of the ember-cli Node package to build an Ember application. There's no choice, you have to learn it and use it. Other than Node and friends needed to build Ember applications, Ember also requires jQuery to run in a browser.
I have to say, if you are going to provide such an opinionated tool, I think its great that you go all the way and provide everything, as Ember does with the CLI tool. The ember-cli even doubles as a package installer (under the hood it uses npm and Bower).
Eventually I imagine the hard dependencies on jQuery will change.
Depends on: A module loader (supported options: SystemJS, RequireJS, Dojo, or Webpack), but it's safe to assume you'll also need some knowledge about Node, npm, gulp, and Babel/Typescript
Aurelia, technically, only requires one of the support module loaders to run an Aurelia application. However, a production-worthy solution will involve several JavaScript tools. Just consider the descriptions for the official production skeletons (an Aurelia skeleton is a basic starting point for the structure for you app):
I'm told that in the near future, a simpler script only version of Aurelia will be available. When this happens, Aurelia won't have any hard dependencies on third-party anything.
Depends on: Nothing
Include vue.js, learn Vue.js, and your off to the races. Similar to jQuery, Angular 1, and React, Vue.js offers a simplistic start. Below I show a simple webpage using Vue.js.
<!DOCTYPE html>
<html>
<head>
<script src="https://npmcdn.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{ message }}</p>
<input v-model="message">
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
</script>
</body>
</html>
A very attractive feature of Vue.js is how it scales with the developer (e.g. Vue Components) with no additional dependencies. In other words, a lot can be done with Vue.js alone. Sprinkle it in existing web pages, or use front to back to compose the UI of a complex application from Vue components.
After considering the "hard'ish dependencies" for each tool, I hope it is obvious that tools like Ember, Angular 2, and Aurelia are in a class of their own when compared to tools like jQuery, Angular 1, React, and Vue.js. One group is simple (i.e. one script, no hard third-party dependencies to go to production) while the rest require a more advanced understanding of application development, app architecture, and task/build tools.
Some of these tools can be used interchangeably to solve similar problems. However, when you go to use Ember, Angular 2, or Aurelia be aware that these solutions initially require more cognitive overhead (Node, npm, module loaders, components, command line tools, compilers, builds, tests etc.). Of course, they also offer more. I'll let you decide if less is more or more is more.
For me, in my many years of playing the web development game, less has always been more until which point less just won't do. But instead of adding heaps of more, I just add a little more to the less.
Header image courtesy of INTVGene
Cody Lindley is a front-end developer working as a developer advocate for Telerik focused on the Kendo UI tools. He lives in Boise, ID with his wife and three children. You can read more about Cody on his site or follow him on Twitter at @codylindley.