Слишком много уроков по экспресс. Давайте сначала создадим базовый машинописный текст.

Вместо того, чтобы запускать весь код в машинописном тексте, мы преобразуем простое приложение Todo из javascript в машинописный текст. Начните с новой папки, скажем todo-app.

Это сгенерирует package.json.

package.json - это gradle.build или composer.json нашего проекта.

npm init -y

Мы собираемся установить yargs только , чтобы упростить аргументы.

npm install --save yargs

Добавьте app.j s и Todo.js в корень папки.

// app.js
// Own Library Imports
const Todo = require('./Todo.js');
// Import yargs
const argv = require('yargs')
    .command('add', "Add TODO to database",{
        title: {
            describe: 'Title of TODO',
            demand: true,
            alias: 't'
        },
        body: {
            describe: 'Body of TODO',
            demand: false,
            alias: 'b'
        }
    })
    .command('all', "List add TODOS")
    .command('remove', "Remove an existing TODO", {
        title: {
            describe: 'Title of TODO',
            demand: true,
            alias: 't'
        }
    })
    .command('view', "View a single TODO", {
        title: {
            describe: 'Title of TODO',
            demand: true,
            alias: 't'
        }
    })
    .help('h')
    .argv;
// Some old school logic
if(argv._[0] === 'add'){
    const todo = Todo.appendTodo({'title': argv.title, 'body': argv.body});
    if(todo && todo.title) Todo.prittyPrint(todo);
} else if(argv._[0] === 'remove') {
    Todo.deleteTodo(Todo.deleteTodo(argv.title));
    console.log("Todo has been deleted");
} else if(argv._[0] === 'view') {
    const todo = Todo.getTodo(argv.title);
    Todo.prittyPrint(todo);
} else if(argv._[0] === 'all') {
    const todos = Todo.getTodos();
    todos.forEach(singleTodo => {
        Todo.prittyPrint(singleTodo);
    });
} else {
    console.log("Invalid Option. Use -h for help");
}

todo.js

// Todo.js
const fs = require('fs');
// Write all todos at once to data.json
// This function is blocking so we dont have to take care
// about the call back
const writeTodos = (todos) => {
    fs.writeFileSync("data.json", JSON.stringify(todos));
    return todos;
};
// Try to read Add todos at once.
// If failed create a new file and return empty
const getTodos = () => {
    var todos = [];
    try {
        todos = fs.readFileSync("data.json").toString();
        todos = JSON.parse(todos);
    } catch (e) {
        fs.writeFileSync("data.json", "[]");
        todos = [];
    }
    return todos;
};
// Read all todos and append new todo to it
// Then write alll of them again
const appendTodo = (todo) => {
    debugger;
    var todos = getTodos();
    const isPreset = (todos.filter(interator => interator.title === todo.title)).length > 0;
    if(isPreset)
        console.log("Already Present");
    else{
        todos.push(todo);
        todos = writeTodos(todos);        
    }
    return todos;
};
// Read all todos and save only those which 
// don't have the current title
const deleteTodo = (title) => {
    var todos = getTodos();
    var filteredTodos = todos.filter(singleTodo => title !== singleTodo.title);
    writeTodos(filteredTodos);
    return filteredTodos;
};
// Read all of the todos.
// Check the one which is having the name and return it.
// filter will return as an array but we will take only first one
const getTodo = (title) => {
    const todos = getTodos();
    var filteredTodos = todos.filter(singleTodo => title == singleTodo.title);
    return filteredTodos[0];
}
// Function will print todo in human readable format
const prittyPrint = todo => {
    if(todo){
        console.log(`\nTitle: ${todo.title}\nBody: ${todo.body}`);        
    }
}
// Export the function is common object
module.exports = {
    getTodos,
    appendTodo,
    deleteTodo,
    getTodo,
    prittyPrint
};

Теперь давайте разберем код. Начиная с app.js

const argv = require('yargs')
    .command('add', "Add TODO to database",{
        title: {
            describe: 'Title of TODO',
            demand: true,
            alias: 't'
        },
        body: {
            describe: 'Body of TODO',
            demand: false,
            alias: 'b'
        }
    })

Мы используем yargs для анализа аргументов. Это также создает страницу справки, когда передается флаг -v, подобный этому

$ node app.js -h add
 add
Add TODO to database
Options:
  --version    Show version number  [boolean]
  -h           Show help            [boolean]
  --title, -t  Title of TODO        [required]
  --body, -b   Body of TODO

Переходим к Todo.js.

const fs = require('fs');

С точки зрения выполнения, мы копируем все задачи из файловой системы в память, а затем сохраняем их за один раз. Это снизит сложность приложения.

Для пудры на сахаре. Здесь мы раскрываем то, что должно быть представлено как API.

module.exports = {
    getTodos,
    appendTodo,
    deleteTodo,
    getTodo,
    prittyPrint
};

Попробуйте запустить приложение, и оно должно работать должным образом.

npm app.js — title=greeting — body=”Hello World”

or

npm app.js -t greeting -b "Hello World"

Теперь преобразовываем этот код в машинописный текст.

Давайте сначала установим некоторые зависимости для машинописного текста.

npm install -g typescript

Установите набор текста. Это поможет в intellisense.

npm install --save-dev @types/node @types/yargs

Давайте создадим нашу первую модель Typescipt todo.ts

export default class Todo {
constructor(public title: String, public description?: String){}
}

Это покажется интригующим, но поверьте мне, это сработает довольно аккуратно.

Вместо объявления общедоступных переменных мы объявляем и определяем их в самом конструкторе. Далее идет tods.ts, он будет содержать массив задач.

Простое определение функции в машинописном тексте

public functionName(parameter1: Type, parameter2: Type): returnType{
// Do your stuff
}

Вы спросили, зачем нам это нужно? Что ж, это будет работать как DAO для нашего класса.

import Todo from './todo';
import * as fs from "fs";
export default class Todos {
  constructor(public todos: Todo[]){}
private static writeAllTodos(todos: Todo[]): void {
    fs.writeFileSync('data.json', todos.toString());
  }
public static readAllTodos(): Todo[]{
    // Define an empty object
    let todos: Todo[] = [];
    try{
      // try to read the todos
      let todosAsBuffer: Buffer = fs.readFileSync('data.json');
      // Using buffer this time.
      // You can use the old code too.
      todos = todosAsBuffer.toJSON().data;
    } catch(e){
      // If failed create a write an empty object
      this.writeAllTodos([]);
    }
    return todos;
  }
public static getTodoByTitle(title: String): Todo{
    let todos: Todo[] = this.readAllTodos();
    let todo = todos.filter((singleTodo: Todo) => singleTodo.title === title);
    return todo[0];
  }
public static removeTodoByTitle(title: String): void{
    let todos: Todo[] = this.readAllTodos();
    let todo = todos.filter((singleTodo: Todo) => singleTodo.title !== title);
  }
public static addNewTodo(todo: Todo): Todo{
    let todos: Todo[] = this.readAllTodos();
    todos.push(todo);
    this.writeAllTodos(todos);
    return todo;
  }
}

Наконец, app.ts

// Import our DAO object
import Todos from './todos';
import Todo from './todo';
import * as yargs from 'yargs';
// We will take advantage of typings and intellsence.
let todoTitleOptions : yargs.Options = {
  describe: 'Title of TODO',
  demand: true,
  alias: 't',
};
let todoBodyOptions : yargs.Options = {
  describe: 'Body of TODO',
  demand: false,
  alias: 'b'
};
let argv = yargs.command('add',"Add TODO to database", {
    title: todoTitleOptions,
    body: todoBodyOptions
  }).command('remove', "Remove an existing TODO",{
    title: todoTitleOptions,
  }).command('view', "View a single TODO",{
    title: todoTitleOptions,
  }).command('all', "List add TODOS")
  .help('h').argv;
if(argv._[0] === 'add'){
  let todo = Todos.addNewTodo(new Todo(argv.title, argv.body));
  todo.prittyPrint();
} else if(argv._[0] === 'remove') {
  Todos.removeTodoByTitle(argv.title);
  console.log("Todo has been deleted");
} else if(argv._[0] === 'view') {
  let todo = Todos.getTodoByTitle(argv.title);
  todo.prittyPrint();
} else if(argv._[0] === 'all') {
  let todos: Todo[] = Todos.readAllTodos();
  todos.forEach((singleTodo: Todo) => {
    singleTodo.prittyPrint();
  });
} else {
  console.log("Invalid Option. Use -h for help");
}

Готово 😃. Теперь скомпилируем компилятор кода tyepscript.

tsc app.ts

Запустите код так же, как и раньше.

Если что-то не учтено, оставьте комментарий ниже.