benawad / fullstack-graphql-airbnb-clone

A Fullstack GraphQL Airbnb Clone with React and React Native
MIT License
1.68k stars 445 forks source link

Upgrade to use Typescript 3 project references #15

Open kristianmandrup opened 6 years ago

kristianmandrup commented 6 years ago

Typescript project references

SD Times article

"references were one of the biggest improvements of the release, making it easier for developers to share dependencies between multiple TypeScript projects by allowing tsconfig.json files to reference each other.

“Specifying these dependencies makes it easier to split your code into smaller projects, since it gives TypeScript (and tools around it) a way to understand build ordering and output structure,” Rosenwasser wrote. “That means things like faster builds that work incrementally, and support for transparently navigating, editing, and refactoring across projects. Since 3.0 lays the foundation and exposes the APIs, any build tool should be able to provide this.”

Perfect for a Mono repo :)

kristianmandrup commented 6 years ago

controlling output structure

One subtle but incredibly useful benefit of project references is logically being able to map your input source to its outputs.

If you’ve ever tried to share TypeScript code between the client and server of your application, you might have run into problems controlling the output structure.

Notice that we ended up with a copy of shared in both client and server. We unnecessarily spent time building shared twice and introduced an undesirable level of nesting in lib/client/client and lib/server/server

The problem is that TypeScript greedily looks for .ts files and tries to include them in a given compilation. Ideally, TypeScript would understand that these files don’t need to be built in the same compilation, and would instead jump to the .d.ts files for type information.

Creating a tsconfig.json for shared and using project references does exactly that. It signals to TypeScript that shared should be built independently, and that when importing from ../shared, we should look for the .d.ts files in its output directory. This avoids triggering a double-build, and also avoids accidentally absorbing all the contents of shared.

kristianmandrup commented 6 years ago

So I think your common and controller packages should be referenced instead using project refs, something like this:

// ./packages/web/tsconfig.json
{
    "compilerOptions": {
        // Needed for project references.
        "composite": true,
        "declaration": true,

        // Other options...
        "outDir": "../../dist/web",
        "strict": true, 
        "module": "esnext", 
        "moduleResolution": "node",
    },
    "references": [
        { "path": "../common" }
    ]
}
benawad commented 6 years ago

So the advantage of setting this up is I can run build once and it will build each project?

kristianmandrup commented 6 years ago

It's a feature specifically geared towards mono repos, where a main project contains multiple projects and some projects share code from common modules.

Speeds up build time, incremental builds (diffs), shared code and control over output for shared code... Super awesome!!