Story
So, you and your partner have a great business idea. Right? You are constantly adding new and new features to your mind. You regularly ask potential customers for their opinions, and they are all crazy about your idea.
Okay, so people need it. You can even make money on it. And the only reason why people still do not use it: you have not implemented your idea. Not yet implemented.
And finally, one day you decided: “Let's do it!”. And now you are already trying to figure out how to implement the business logic of your application, the killer feature that will move the product forward. You have an idea how to do it, and you know what you can do. And you say: “Done! Works! ”You have a successful prototype! It remains only to pack it into a web application.
')
“OK, let's make a website,” you say.
And only then you understand that for this you need to choose a programming language; need to choose a (modern) platform; you need to select some (modern) frameworks; you need to set up (and buy) storage, databases and hosting; need to provide an interface for administration; need to provide access control and content management system.
Here are dozens and dozens of architectural decisions to be made. And you don’t want to be mistaken: we need technologies that will enable rapid development, support constant iterations, maximum efficiency, speed, stability and much more. You want to be lean and agile. You want to use technologies that will help you be successful in both the short and long term. And choosing them is not always so easy.
“I'm overwhelmed,” you say, and feel overwhelmed. Energy is not what it was at the beginning. You are trying to collect thoughts, but there is too much work. The prototype slowly fades and dies.
Sentence
After I gave up a bunch of ideas for similar reasons, I decided to design a solution for this problem. I called this project '
Init ' (or init.js).
The basic idea is to use one project to start any project, give the developer or technical manager the opportunity to make all the main decisions at once and get a suitable initial template based on them. I know many will say “One solution cannot be applied to all problems” (haters gonna hate). And they may be right. But we can try to create a solution that is generally suitable, and, in my opinion, Init coped with this task.
To achieve this goal, it is necessary to take into account several important points. When developing Init, I focused on the following:
ComponentsComponent representation is one of the key characteristics of any system, since it allows you to reuse software components in several projects, which is the main goal of Init. But the component view contains a side effect - substitutability, which will become our main ally in the fight against various problems, the solution of which is “almost” the same.
Ease of developmentSome problem somewhere has a solution that is best implemented on
Brainf * ck . will be virtually impossible to write, let alone read. It will cost you time and tremendous effort. In general, you should use languages ​​and platforms that simplify, and not complicate, the development for you (and those who will do it later).
CommunityWhatever platform you choose, make sure that there is a large community around it. One that can help you with most standard and non-standard problems. Remember: jQuery may not be the
fastest ,
cleanest , and most elegant library, but it is a winner, thanks to its
community .
I will show how I made decisions when creating Init, without forgetting about these goals.
At the heart of Init is the
“full-stack JavaScript” paradigm — the full set of JavaScript (some people call her or her part the
MEAN Stack ). Working with such a set, Init allows you to use only one language to create amazingly flexible and full-featured environments for developing web applications. In short, Init allows using JavaScript not only for developing client and server solutions, but also for building, testing, templating, and so on.

But let's stop for a moment and ask ourselves: is it such a good idea to use JavaScript?
Why I chose javascript
I have been working as a web developer since 1998. At that time,
we mostly used Perl for server development, but even then we had JavaScript for the client side. Web server technologies have changed a lot since then: we've been through several waves of languages ​​and technologies, such as PHP, AP, JSP, .NET, Ruby, Python. Developers began to realize that using two different languages ​​in the server and client parts complicates the work. Initially, attempts to combine the two parts under one language resulted in the creation of client components on the server and compiling them into JavaScript. The results fell short of expectations, and most of these projects failed (for example, ASP MVC, replacing the
ASP.NET web forms , and
GWT, which, apparently, will be replaced by
Polymer in the near future). But, in fact, it was a great idea: one language for the client and the server, allowing you to reuse components and resources (this keyword:
resources ).
The answer was simple: transfer JavaScript to the server.
In fact,
JavaScript was born with the server side in Netscape Enterprise Server, but the language was simply not ready at that time. After years of attempts and failures,
Node.js appeared, which not only transferred JavaScript to the server, but also advanced the idea of
non-blocking programming , forever changing the way we write “fread” (I / O) (read more about it
here ).
But these ideas were not new, why did they become so popular with the advent of Node.js? Simple non-blocking programming is achieved in several ways. Perhaps the easiest is to use callbacks and the
event loop . In most languages, this is not an easy task: if callbacks are a fairly common function, then the event loop is not, and at some point you find yourself in a fight with external libraries (for example: Python, with
Tornado ). But in JavaScript,
callbacks are part of the language, like the event loop, and every programmer who at least tried JavaScript knew them (or at least used them, even if he
didn’t fully understand what an event loop was ).
Suddenly, any startup on Earth can reuse developers (read: resources) on both the client and server side, solving the
personnel problem , “We need a Python guru”.
So now we have
an incredibly fast platform (thanks to non-blocking programming) with a language that is very easy to use (thanks to JavaScript). But is that enough? Will this work? I am sure that JavaScript will take an important place in the future. Let me explain why:
Functional programmingJavaScript was the first programming language to
bring the functional programming
paradigm to the masses (of course, the first was Lisp, but most programmers never created a fully completed Lisp product). Lisp and Self, the main languages ​​that
influenced JavaScript , are full of innovative ideas. These ideas can free our minds to learn new techniques, design patterns, and paradigms. They all moved to javascript. Take a look at
monads ,
Church numbers , or even (a more practical example)
functions of Underscore.js collections that can save you from a lot of lines of extra code.
Dynamic programming and prototype inheritanceObject-oriented programming without classes (and without an infinite hierarchy of classes) allows you to speed up development (create objects, add methods and use them) but, more importantly, reduces refactoring time for subsequent support, allowing the programmer to modify the finished objects instead of changing classes. This speed and flexibility creates the conditions for rapid development.
Javascript is the internetJavaScript was
designed for the Internet , it’s here from the very beginning, and it’s
not going to go anywhere . All attempts to destroy it failed: look, for example, at the fall of
Java applets , replacing VBScript
with Microsoft's TypeScript (which is compiled into JavaScript), Flash death at the hands of the
mobile market and HTML5 . You cannot replace JavaScript without destroying millions of web pages, so our goal should be to improve the language. And no one is better suited for this task than
Technical Committee 39 of ECMA.
Yes, alternatives to JavaScript are born every day, for example,
CoffeeScript ,
TypeScript, and
millions of languages ​​that are compiled into JavaScript . These alternatives can be useful during development (
thanks to source maps ), but they will not succeed in replacing JavaScript in the long run for two reasons: their communities will never be larger, and their best features will be implemented in ECMA Script (read: JavaScript). JavaScript is not an assembly language, it is a high-level programming language with source code that you can understand, so you must understand it.
Start-to-End JavaScript: Node.js and MongoDB
So these were the reasons for choosing JavaScript. Now I will try to convince you to use Node.js and MongoDB.
Node.jsNode.js is a platform for creating fast, scalable network applications - this is how the official website describes it. But Node.js is more than just a platform. This is the preferred environment for running JavaScript applications with access to I / O devices. Even if you do not plan to write the main server application on Node.js, you can use tools created on the basis of Node.js to improve the development process. For example,
Mocha.js for unit tests,
Grunt.js for automatic assembly, or even
Brackets for full-text code editing.
So if you plan to write applications for a server or client in JavaScript, you should get acquainted with Node.js, because you will need it every day. There are some interesting
alternatives , but none of them have 10% of the Node.js community.
MongoDBMongoDB is a document-oriented
NoSQL database that uses JavaScript as the query language, allowing you to complete the cycle of working with the JavaScript platform. But this is not the main reason to use MongoDB.
MongoDB
does not require a description of the table schemas, so you can easily save objects, and thus adapt more quickly to changes in requirements. In addition, MongoDB
scales well and
uses map-reduce , making it a good choice for applications with big data. MongoDB is so flexible that it can be used as a document database without a schema, relational storage (but without
transactions ), or even key-value storage for caching.
Server Component View with Express.js
Server component view is a complex task. But with
Express.js (and
Connect.js ), the idea of ​​an “intermediate layer” (middleware) emerged. In my opinion, the intermediate layer is the best definition of server components. If you want to compare it with a well-known design pattern, then this is something like conveyors and filters.
The basic idea is that your component is part of a pipeline. The pipeline handles the request (input) and generates a response (output), but your component is not responsible for the entire answer. On the contrary, it only modifies what is needed, and then passes the task to the next element of the pipeline. When the last pipeline item finishes processing, the response is sent back to the client.
We call these “conveyor elements” “intermediate layer”. Obviously, you can create two types of intermediate layers:
Mediators : elements that process the request and response, but they are not fully responsible for the request itself, so they delegate the request to the next layer.
Finite elements : elements completely responsible for the final answer. They process and modify the request and response, but should not delegate them to the next layers. In practice, the ability to delegate to the next layer is still preferable for architectural flexibility (for example, to add another layer), even if this layer does not exist (in which case the answer is sent directly to the client).

As an example, imagine a server component for managing users. In terms of intermediate layers, we have both finite elements and intermediaries. Finite elements should be able to create users and display a list of users. But first, we need intermediaries for authentication (since we do not want unauthenticated requests to create users). After we have created an intermediary for authentication, we can simply embed it in any place where we want to turn a previously open possibility into an authenticated one.
Single Page Applications
The Init project focuses on creating
single page applications ('single page applications' (SPAs) . Most web developers have often had the temptation to try creating one-page applications. I did a few (mostly for myself), and I can say with confidence that the future of web applications is with them. Have you ever compared a SPA with a regular web application on a mobile connection? The difference in the response is tens of seconds.
Single-page applications are the future of the Internet, so why create your product in an outdated format? A common argument I hear is SEO difficulties. But if you implement everything correctly, it will not be a problem: Google itself offers
very good instructions on how to do this, and
there are some good comments here.
Client MV * with Backbone.js, Marionette.js, and Twitter Bootstrap
Much has been said about
MVC * frameworks for one-page applications . This is a difficult choice, but I would say that the three favorites are
Backbone.js ,
Ember.js , and
Angular.js .
They are all considered very good.
But what will be the best for you?Unfortunately, I have to admit that I have very little experience with Angular.js, so I will exclude it from this discussion. So, Ember.js and Backbone.js are two different ways to solve one problem.
Backbone.js is minimal, simple and offers you the necessary minimum set for writing a simple SPA. Ember.js, on the other hand, is a full-fledged and professional framework for creating single-page applications. It has more features, but the learning curve is steeper.
Depending on the size of the application, the solution may be as simple as analyzing the “used functions / available functions” relationship. It will give you a good hint.
In the case of Init, I wanted to cover most of the scenarios, so I chose Backbone.js for the simple creation of the SPA, with Backbone.Marionette.View for componentarization. In such a scheme, each component is a simple application, and the final product can be as complex as I want.
Styling is also a big task, but once again we can count on frameworks. For CSS, there is nothing better than
Twitter Bootstrap , it has a complete set of styles that are ready out of the box not only ready for use, but also for
convenient modification .
Bootstrap was created using the
LESS language. Bootstrap is an open source project, so it can be modified if needed. Included with it are a bunch of user interface elements with
good documentation on the Bootstrap site . In addition, there is a
model for modifications that allows you to easily create your own elements. Undoubtedly, this is the best choice for our task.
Best practices: Grunt.js, Mocha.js, Chai.js, RequireJS, and CoverJS
Finally, we can identify the best techniques and find out how Init can help us with their implementation and subsequent support. Our solution is based on several tools, each of which in turn is based on Node.js
Mocha.js and
Chai.js :
These tools enable you to manage your development process using
TDD or
BDD , provide the infrastructure for organizing unit tests and allow you to automatically launch them.
There are
thousands of frameworks for unit tests in JavaScript. Why use Mocha.js? The short answer is: it is flexible and complete.
Long answer: it has two important features (interfaces, reporters), and it does not have a library of statements (assertions) Let me explain.
Interfaces : you may be accustomed to TDD concepts like unit tests and collections of scripts (suite), you might prefer BDD ideas with behavior specifications “descriptions” and “this should”. Mocha.js supports both approaches.
Reporters : running unit tests generates reports on the results, and you can format these reports with different reporters. For example, if you need to submit information to a continuous integration server, you can select a reporter specifically for this task.
Lack of a library of statements (assertion): Mocha.js was created so that you can use any library of statements with it, which improves flexibility. There are
many options , but it's worth considering Chai.js.
Chai.js is a flexible library of statements that allows you to use any of the three main styles:
Assert: A classic style of assertions from the old school TDD, for example:
assert.equal(variable, "value");
Expect: The style of chain statements, most often used in BDD. For example:
expect(variable).to.equal("value");
Must (should): Also used in BDD, but I prefer “waiting” because “should” sounds congruent with the behavior specification “it (“ should do something ”)”. For example:
variable.should.equal(“value”);
Chai.js goes well with Mocha.js. Using these two libraries, you can write unit tests in TDD, BDD or any other style that you can imagine.
Grunt.js :
Grunt.js allows you to automate the build, from simple copy-pasting and pasting files to precompiling templates, compiling metal languages ​​for styles (i.e., SASS and LESS), testing unit (with mocha.js), analyzing and minifying code ( for example, with
UglifyJS or
Closure Compiler ). You can add your own automated tasks in Grunt, or find the right solution among hundreds and hundreds of
existing plug-ins , (again, using tools that have a great community behind it plays into our hands). Grunt can also
monitor files and trigger actions when they change.
RequireJS :
RequireJS may seem just another way to load modules along with
AMD , but I assure you that RequireJS is capable of more. To understand why, first, you need to mention the idea of ​​the module scope (for example, demo.views.hello), which helps keep the global scope clean, hiding each module in its own area. The problem is that these modules cannot be reused: if you change the namespace of one of the instances, it will affect all instances. RequireJS, in turn, makes it possible to initially create modules for reuse. (In addition, it helps to use
dependency injection (Dependency Injection) so that
your modules do not access global variables .
CoverJS :
Code coverage is a measure of the test score. From the title it is clear that the library provides information about the code coverage of your current test collection. CoverJS evaluates code coverage by instrumentation tool tests (and not through lines of code, like
JSCoverage ) and by generating an instrumental version of your code. It can also generate reports for the
continuous integration server.
Using branches to switch features
I started working on Init and I needed a way to turn on and off the various features that might be needed in a project. I chose a radical approach: using git branches to accomplish this task.
Roughly speaking, each branch is a component or functionality that the user may wish to include. If you are creating a project from scratch, start with the minimum branch, and then add other technologies to merge with the necessary branches. Say, for example, that we need to start a project with Backbone.js and Marionette.js. You can start with the Backbone.js branch and merge it with the Marionette.js branch, adding in the future every opportunity you need.

While this idea of ​​merging to add functionality can be used for template technologies (like Backbone, Node, Express). But in the future you can switch between backends (for example, from MongoDB to Postgres) and client solutions.
Start a project with Init and deploy to Heroku today.
There has never been an easier way to start a project. Just go to
the GitHub repository , select the branch with the latest commits and then:
1. Create a directory for your project (or use an existing one).
2. Create a repository using git init (or use an existing repository).
3. Add a remote init repository
git remote add init git://github.com/picanteverde/init.git
4. Get the branch you want
git pull init usermanager
5. Get the process file for heroku
git pull init heroku
6. With the Heroku Toolbelt installed, create the Heroku application
heroku create
7. Send your master branch to Heroku
git push heroku master
8. Visit your already working app in Heroku!
Now you can start developing your killer feature with a few lines of code. In doing so, you will be developing with the help of the latest and most efficient technologies, automated as far as possible.
I hope you can use
Init to quickly implement your new big idea. Do not forget to check the Init repository for new features and bug fixes, as the project is under active development. Well, I look forward to your feedback.