百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
J

javascript-todo-list-tutorial

> DevOps
开源

✅ 一个分步完整的初学者示例/教程,介绍如何在 JavaScript 中从零开始构建一个 Todo List 应用程序 (TodoMVC),遵循测试驱动开发 (TDD) 方法。

790 stars0 点赞2 次浏览
访问官网GitHub

工具介绍

✅ 一个分步完整的初学者示例/教程,介绍如何在 JavaScript 中从零开始构建一个 Todo List 应用程序 (TodoMVC),遵循测试驱动开发 (TDD) 方法。

Before you continue, try the demo: https://dwyl.github.io/javascript-todo-list-tutorial/

Add a few items to the list. Double-click/tap the item to edit it. Check-off your todos and navigate the footer to filter for Active/Completed. Try and "break" it! Refresh the page and notice how your todo items are "still there" (they were saved to localStorage!). Once you have had a "play" with the demo, come back and build it!!

Why?

The purpose of this Todo List mini project is to practice your "VanillaJS" skills and consolidate your understanding of The Elm Architecture (TEA) by creating a real world useable App following strict Documentation and Test Driven Development.

This will show you that it's not only possible to write docs and tests first, you will see first hand that code is more concise, well-documented and thus easier to maintain and you will get your work done much faster.

These are foundational skills that will pay immediate returns on the time invested, and will continue to return "interest" for as long as you write (and people use your) software!

It's impossible to "over-state" how vital writing tests first is to both your personal effectiveness and long-term sanity. Thankfully, by the end of this chapter, you will see how easy it is.

What?

Build a fully functional "Todo List" Application!

Along the way we will cover:

  • Building an App using a pre-made CSS Styles/Framework!
  • The Document Object Model (DOM) + JSDOM
  • Browser Routing/Navigation
  • Local Storage for Offline Support
  • Keyboard event listeners for rapid todo list creation and editing!

We will be abstracting all "architecture" related ("generic") code into a "mini frontend framework" called "elmish". (elmish is inspired by Elm but only meant for educational purposes!)

The journey to creating elmish is captured in elmish.md and fully documented code is in elmish.js. This means our Todo List App can be as concise and "declarative" as possible.

Todo List?

If you are unfamiliar with Todo lists, simply put: they are a way of keeping a list of the tasks that need to be done.

see: https://en.wikipedia.org/wiki/Time_management#Setting_priorities_and_goals

Todo Lists or "Checklists" are the best way of tracking tasks.

Atul Gawande wrote a superb book on this subject:

https://www.amazon.com/Checklist-Manifesto-How-Things-Right/dp/0312430000

Or if you don't have time to read, watch: https://www.youtube.com/results?search_query=checklist+manifesto

TodoMVC?

If you have not come across TodoMVC before, it's a website that showcases various "frontend" frameworks using a common user interface (UI): a Todo List Application.

We highly recommend checking out the following links:

  • Website: https://todomvc.com
  • GitHub project: https://github.com/tastejs/todomvc

For our purposes we will simply be re-using the TodoMVC CSS to make our TEA Todo List look good (not have to "worry" about styles so we can focus on functionality). All the JavaScript code will be written "from scratch" to ensure that everything is clear.

Who?

This tutorial is for anyone/everyone who wants to develop their "core" JavaScript skills (without using a framework/library) while building a "real world" (fully functional) Todo List Application.

As always, if you get "stuck", please open an issue: https://github.com/dwyl/javascript-todo-list-tutorial/issues by opening a question you help everyone learn more effectively!

Prerequisites

Most beginners with basic JavaScript and HTML knowledge should be able to follow this example without any prior experience. The code is commented and the most "complex" function is an event listener. With that said, if you feel "stuck" at any point, please consult the recommend reading (and Google) and if you cannot find an answer, please open an issue!

Recommended reading:

  • Test Driven Developement: https://github.com/dwyl/learn-tdd
  • Tape-specific syntax: https://github.com/dwyl/learn-tape
  • Elm Architecture: https://github.com/dwyl/learn-elm-architecture-in-javascript

How?

Start by cloning this repository to your localhost so that you can follow the example/tutorial offline:

git clone https://github.com/dwyl/javascript-todo-list-tutorial.git

Install the devDependencies so you can run the tests:

cd javascript-todo-list-tutorial && npm install

Now you have everything you need to build a Todo List from scratch!

Elm(ish) ?

In order to simplify the code for our Todo List App, we abstracted much of the "generic" code into a "front-end micro framework" called Elm(ish). The functions & functionality of Elm(ish) should be familiar to you so you should be able to build the Todo List using the Elm(ish) helper functions e.g: mount, div, input and route.

You can opt to either:

a) read the Elm(ish) docs/tutorial elmish.md before building the Todo List App - this will give you both TDD practice and a deeper understanding of building a micro framework. i.e. "prospective learning"

b) refer the Elm(ish) docs/tutorial elmish.md while building the Todo List App when you "need to know" how one of the helper functions works. i.e. "contextual learning"

c) only consult the Elm(ish) docs/tutorial elmish.md if you are "stuck" while building the Todo List App. i.e. "debug learning"

The choice is yours; there is no "right" way to learn.

Testing & Documentation?

Before diving into building the Todo List App, we need to consider how we are going to test it. By ensuring that we follow TDD from the start of an App, we will have "no surprises" and avoid having to "correct" any "bad habits".

We will be using Tape and JSDOM for testing both our functions and the final application. If you are new to either of these tools, please see: github.com/dwyl/learn-tape and front-end-with-tape.md

We will be using JSDOC for documentation. Please see our tutorial if this is new to you.

Create Files

Create a new directory e.g: /todo-app So that you can build the Todo List from scratch!

In your editor/terminal create the following files:

  • test/todo-app.test.js
  • lib/todo-app.js
  • index.html

These file names should be self-explanatory, but if unclear, todo-app.test.js is where we will write the tests for our Todo List App. todo-app.js is where all the JSDOCs and functions for our Todo List App will be written.

Test Setup

In order to run our test(s), we need some "setup" code that "requires" the libraries/files so we can execute the functions.

In the test/todo-app.test.js file, type the following code:

const test = require('tape');       // https://github.com/dwyl/learn-tape
const fs = require('fs');           // to read html files (see below)
const path = require('path');       // so we can open files cross-platform
const html = fs.readFileSync(path.resolve(__dirname, '../index.html'));
require('jsdom-global')(html);      // https://github.com/rstacruz/jsdom-global
const app = require('../lib/todo-app.js'); // functions to test
const id = 'test-app';              // all tests use 'test-app' as root element

Most of this code should be familiar to you if you have followed previous tutorials. If anything is unclear please revisit https://github.com/dwyl/learn-tape and front-end-with-tape.md

If you attempt to run the test file: node test/todo-app.test.js you should see no output.

(this is expected as we haven't written any tests yet!)

model

The model for our Todo List App is boringly simple. All we need is an Object with a todos key which has an Array of Objects as it's value:

{
  todos: [
    { id: 1, title: "Learn Elm Architecture", done: true },
    { id: 2, title: "Build Todo List App",    done: false },
    { id: 3, title: "Win the Internet!",      done: false }
  ]
}

todos is an Array of Objects and each Todo (Array) item has 3 keys:

  • id: the index in the list.
  • title: the title/description of the todo item.
  • done: a boolean indicating if the item is complete or still "todo".

What about the count of items ?

The TodoMVC Specification requires us to display a counter of the items in the Todo list: https://github.com/tastejs/todomvc/blob/main/app-spec.md#counter

In order to display the count of items in the Todo list, we could store 3 values in the model:

  • total_items - the total number of items, in this case 3.
  • completed_items - the number of completed items. in this case 1.
  • incomplete_items - the number of items still to be done; 2.

Each time a new item is added to the list we would need to update both the total_items and the incomplete_items values in the model. And each time an item gets checked off as "done", we would need to update both the incomplete_items and the completed_items. This is unnecessary effort we can avoid. We can simply compute these values based on the data in the todos Array and display them for the user without storing any additional data.

Instead of storing any additional data for a counter in the model (the count of active and completed Todo items), we will compute the count and display the count at "runtime". We don't need to store any additional data in the model. This may use a few CPU cycles computing the count each time the view is rendered but that's "OK"! Even on an ancient Android device this will only take a millisecond to compute and won't "slow down" the app or affect UX.

See below for how the three counts are computed.

e.g: in the model above there are 3 todo items in the todos Array; 2 items which are "active" (done=false) and 1 which is "done" (done=true).

model Test

Given that the model is "just data" ( it has no "methods" because Elm(ish) is "Functional" not "Object Oriented" ), there is no functionality to test. We are merely going to test for the "shape" of the data.

In the test/todo-app.test.js file, append following test code:

test('todo `model` (Object) has desired keys', function (t) {
  const keys = Object.keys(app.model);
  t.deepEqual(keys, ['todos', 'hash'], "`todos` and `hash` keys are present.");
  t.true(Array.isArray(app.model.todos), "model.todos is an Array")
  t.end();
});

If you run this test in your terminal:

node test/todo-app.test.js

You should see both assertions fail:

model Implementation

Write the minimum code required to pass this test in todo-app.js. e.g:

/**
 * initial_model is a simple JavaScript Object with two keys and no methods.
 * it is used both as the "initial" model when mounting the Todo List App
 * and as the "reset" state when all todos are deleted at once.
 */
var initial_model = {
  todos: [], // empty array whic

Issues· 6 开放

查看全部 Issues在 GitHub 打开

暂无开放 Issues,或尚未同步最近议题。

> 标签

JavaScriptbeginnerbeginners-guidebest-practiceselm-architecture

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月17日
分类DevOps
定价开源

> 相关工具

D
Docker
容器化平台,标准化应用交付
G
GitHub Actions
GitHub 原生 CI/CD 工作流
N
Nginx
高性能 Web 服务器与反向代理