简体   繁体   中英

TypeScript: Reuse of interfaces and classes for frontend (Angular) and backend

I have a monorepo for a current project based on a Frontend (Angular) and a Backend (developed with NestJS - so it's NodeJS). I want to use custom interfaces and classes for both - frontend and backend. For example, creating DTOs so my frontend knows the parameter of my backend.

I thought about a common folder like the following project structure shows, but this is not working, because the common folder is outside the scope of Angular (tsconfig) and so auto completition isn't working

project
├── client (Angular)
├── server (NestJS)
└── common (client and server share specific interfaces and classes)

Does anyone has experience for this? At the moment I add my interfaces to both folders, but this is is evil because if I update one interface, I have to replace the other, too.

In TypeScript 3.0 "Project references" were introduced. This could help you achieve what you want (I was using it to share models between angular and cloud function)

https://www.typescriptlang.org/docs/handbook/project-references.html

What you need to do is add an external project reference to the tsconfig.json of the project that should reuse files from somewhere else

{
  "compilerOptions": {
    // The usual config
  },
  "references": [
    { "path": "../my-other-project" }
  ]
}

A tool like Lerna helps with this sort of setup, from experience this is the easiest way to go about things without creating any private npm repos (which is another alternative).

Essentially, you setup your angular and server packages to install the common package just like any other npm package and run lerna to create virtual links for each package. This way when you need them for intellisense the editor will go thru the virtual file links lerna creates during the bootstrap phase, thus allowing you to create any number of common packages without doing any heavy lifting to connect all the consumer packages.

In your tsconfig.json add common to paths property:

     "paths": {
       "@angular/*": ["node_modules/@angular/*"],
       "rxjs/*": ["node_modules/rxjs/*"],
       "common/*": ["../common/*"]
     }

Then: import myInterface from 'exported interface in common folder';

The best is to have an index.ts which exports all services, interfaces whatever: export * from './myFile'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM