Giter Site home page Giter Site logo

zzy5785175 / typescript-clean-architecture Goto Github PK

View Code? Open in Web Editor NEW

This project forked from aziznal/typescript-clean-architecture

0.0 1.0 0.0 1.62 MB

A typescript project template using clean architecture

JavaScript 40.74% TypeScript 55.64% HTML 2.90% SCSS 0.72%

typescript-clean-architecture's Introduction

typescript-clean-architecture

A typescript project template using clean architecture.

You can use this template for any application you need, not just Web!

About

Setting Up

  1. Clone Repo
  2. Within root, run npm start. This will install dependencies and setup lerna.
  3. Done

How to use

You can read this article explaining my idea of how this article can be used.

Also, see the counter-example branch to see different layers in action together.

The project structure is split into three main layers (core, data, presentation), as well as one auxiliary layer (di).

A typical programming workflow for a new feature would look like this:

  • You start writing your app in core
  • You support core with a repository implemented in data that implements methods which use cases in core need
  • You create / update factories in di that create the core use cases / repos with their dependencies from data given to them
  • You setup the use of core use cases in presentation
  • You implement your feature in presentation

Remember that Presentation knows ONLY Use Cases and Entities, NOT Repos! That's Data's job, and it's hidden behind dependency injection.

Useful commands to know

  • For each package (core, data, and di), you might want to run npm run build:watch while you're modifying that package. This'll make it rebuild for every save you make and other packages will be able to see those changes
  • Within root, npx lerna run build will re-build all your packages (that have changed since last build, otherwise it'll use cached version)
  • Within root, npx lerna run build --scope=core will re-build only core. You can substitute core for data, di, or presentation.
  • Within root, npx lerna clean will remove all node_modules folders in all packages including root.

Extra

VS Code workspaces are a life saver. Open each package in its own workspace and you'll have zero tsconfig or prettier issues etc.

Sometimes, vs code (if that's what you're using) intellisense will not detect changes you made in another package. This is annoying as heck but closing and reopening vs code usually solves it. Sometimes, it just goes away on its own when a build command is ran.

Layers of the project

Core

Core is the layer where you can create your Entities, Use Cases, and Repo Interfaces.

  • An Entity is a model of an object in your application. It can be a User, a Course, or a Fruit. It's a Thing in your app that is core to how your app functions.

  • A Use Case is a way for you to use Entities to get something done. For example, a use case for a user would be login, sign up, add to favorites, send message to other user, etc..

    Use Cases typically require a data source to call on so they can retrieve data as well as save it. We cover this using a Repository interface defined in core and its implementation can then be defined in another layer such as data.

  • Repository Interfaces are what use cases call upon when they need their data. They define a few methods (such as create, get, update, delete, etc.. but it doesn't have to look like a REST api) and use cases call on these methods as they need them.

Data

Data is the layer that supports core with data. Use cases in core, through a repo interface, will call the data layer to request some data. The data layer manages whether that data is from an API or a cache, etc.

DI (dependency injection)

This is the layer where Core and Data are associated together and Data implementations are provided to instantiations of Core objects as they are needed. Typically, you'll be instantiating Core use case implementations and providing them with an implementation of a repository from Data.

Example:

/* in di/src/core.factory.ts */
import * as core from 'core';
import * as data from 'data';

class CoreFactory {
    userRepo: core.UserRepo;

    constructor(private otherDependencies: any[]) {
        this.userRepo = new data.UserRepoImpl(/* pass any required args here */);
    }

    createLoginUsecase(): core.LoginUsecase {
        return new core.LoginUsecaseImpl(this.userRepo)
    }

    createSignupUsecase(): core.SignupUsecase {
        return new core.LoginUsecaseImpl(this.userRepo)
    }
}

You can use this core factory in your presentation's dependency injection solution like this (Angular example provided):

/* in app.module.ts */
import * as di from 'di';

const coreFactory = new di.CoreFactory();

@NgModule({
    // ...
    providers: [
        {
            provide: core.LoginUsecase,
            useFactory: () => coreFactory.createLoginUsecase()
        },
        {
            provide: core.SignupUsecase,
            useFactory: () => coreFactory.createSignupUsecase()
        },
    ],
    //...
})
export class AppModule {}

Now you have access to your use cases through dependency injection!

Note that the di layer and something like you app.module.ts file can become rather messy. This is normal. It's to be expected since they are the single point where everything is introduced together. There are a few things to do to make them tidier, such as isolating your providers array in app.module into its own file where you then import it into app.module. See this example of a providers file and how it's used in the app.module file. It doesn't get easier!

Presentation

This is the layer where you write you UI code. You can do that using a web framework such as Angular or React, or using something else like Electron if you're making a desktop app. Heck, you can even make a console app if you wanted!

Other Layers

You can very easily add more layers to this architecture, depending on your need. For example, maybe you prefer to isolate caching into its own layer because you have a complicated caching mechanism, or perhaps you have multiple implementations of presentation such as one for web and one for desktop etc.

typescript-clean-architecture's People

Contributors

aziznal avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.