Look ma, no framework!
I really like making web apps. So I thought I could write down how I do it. Maybe someone likes it.
Make an app with just a few libraries
So we are going to make a task list.
What I usually do is start with an index.html file and an index.js file:
1 |
|
I like jQuery. It made my life easier for many years, and it makes it really easy to change the dom and make ajax calls. So I include that in my html file. The latest browsers make jQuery almost useless, but it's still nice to have it around for a lot of things for now.
Usually I also add an app.css
stylesheet file, so I can add custom styles to my app if I need to. This file will be empty at the beginning, but since I know I will be using this I add it now already.
1 | (function($) { |
All right. Now we have our base. Let's add bootstrap for a quick styling and some html for our list of tasks and a form to add a task:
1 |
|
We have the first screen of our app inside the index.html
file. This is not that nice, because if we have to add more screens later we clutter our index.html
file with all the screens our app will have. So we will have to move this out later.
Let's add the add task functionality to our app:
1 | (function($) { |
Here we go. We can add tasks to our list. Let's make it a little bit nicer with some margin in out app.css
:
1 | #task-list { |
But there is one thing that really stands out in the code above: we mixed JavaScript with html, and that gets messy fast.
Let's split that out with a templating engine. I really like ejs, but anything will do. handlebars is also nice.
First we add a script tag to include ejs. Let's add it do a directory libs
, so it's a bit out of the way:1
<script type="text/javascript" src="libs/ejs.js"></script>
then we create a new file views/task-item.ejs
1 | <li class="list-group-item"><%= title %></li> |
and now let's change our JavaScript
from1
2var newTask = '<li class="list-group-item">' + $('#task').val() + '</li>';
$('#task-list').append(newTask);
to1
$('#task-list').append('views/task-item.ejs', {title: $('#task').val()});
we don't gain much in this example, but when the view grows and has more markup, the advantage becomes more obvious.
Let's do the same with the whole first screen we put in index.html
at the beginning:
and our index.html
becomes
1 |
|
and we move the main content out to it's own view file:
1 | <h1>Tasks</h1> |
and render it:1
2
3
4
5
6
7
8
9
10
11
12
13(function($) {
//events
$(document).on('submit', '#add-task-form', function(ev) {
ev.preventDefault();
$('#task-list').append('views/task-item.ejs', {title: $('#task').val()});
});
//initial page setup
$('.container').html('views/tasks.ejs', {});
})(jQuery)
Better.
Now we need some way for the user to delete a task. Let's add a delete button:1
2
3
4
5<li class="list-group-item"><%= title %>
<a href="javascript:///" class="remove-task">
<span class="glyphicon glyphicon-remove pull-right"></span>
</a>
</li>
and now we handle the event:1
2
3
4$(document).on('click', '.remove-task', function(ev) {
var task = $(ev.currentTarget).parent();
task.remove();
});
easy.
Alright. That's it.
There are of course a lot of things missing in this example, but I saw that I can go a long way with this simple setup. A really long way.
After a while index.js
becomes a few thousand lines, and the views
folder becomes cluttered up with a lot of views for different components and screens.
When and if the app becomes so big that that becomes an issue, we need to start to organize our code better.
At that point we need to refactor our directory structure and start using a dependency manager. But that's for the next post! ☺
The example we coded is up on github here.
The talk I made on this topic was recorded and put online here.