Coder Social home page Coder Social logo

esbuild-typescript-turborepo's Introduction

ESBuild TypeScript Turborepo Monorepo starter/example

Update December 2022:

  • The way of exporting/sharing packages has changed. Check the updated section.

Update November 2022:

  • Added support for React with an example app in apps/react.

Details:

This is an example monorepository using ESBuild for it's near-instantaneous build times and Turborepo for it's caching capabilities. It's pre-configured for TypeScript (2 different configurations for browser and for node) and ESLint for linting.

Additionally it's using NPM Workspaces, most examples I could find online were using YARN.

Installation:

git clone https://github.com/barca-reddit/typescript-vscode-esbuild.git

cd typescript-vscode-esbuild

npm run watch

Tech stack:

Exporting/sharing packages:

NB: I don't know if this is the best or the accepted way to do this, neither I consider myself an expert, so PR/issues/feedback of any kind is welcome.

Previously we were making use of typeVersions in package.json to share code within the monorepository, but that caused some issues. Now, we're making use of "moduleResolution": "NodeNext" in tsconfig.json, so that makes things easier.

To create a shared package and import it somewhere else in your monorepo, edit the contents of package.json of the package you want to export and add the following fields:

"exports": {
    ".": {
        "types": "./src/main.ts",
        "import": "./out/main.js"
    }
}

The first part of the export object is the path you want to import (details below).

The types key should point out to an index file where all your exports live. For example:

// src/main.ts
export const foo = "foo";
export const bar = "foo";

The import key should point out to an index (main) file in your compiled out directory and it's there to server plain javascript imports.

All of this allows you to do the following:

// inside some other package
import { foo, bar } from "@repo/shared";

Don't forget to add the package you're exporting as a dependency to the package you're importing it to:

// package.json
{
    // ...
    "dependencies": { "@repo/shared": "*" }
}

You can also have multiple import paths.

"exports": {
    ".": {
        "types": "./src/main.ts",
        "import": "./out/main.js"
    },
    "./server": {
        "types": "./src/server/index.ts",
        "import": "./out/server/index.js"
    },
    "./web": {
        "types": "./src/web/index.ts",
        "import": "./out/web/index.js"
    }
}
// inside some other package
import { foo } from "@repo/shared/server";
import { bar } from "@repo/shared/web";

It is also possible to have wildcard exports like this:

"exports": {
    "./*": {
        "types": "./src/*.ts",
        "import": "./out/*.js"
    }
}

But unfortunately TypeScript is unable to find type declarations this way. If you have a solution or tips about this, issues and PRs are welcome!

Notes:

Turborepo

For Turborepo caching to work, it's essential that all .cache directories it creates are git-ignored.

If build order isn't important for your setup, add the --parallel flag to the npm build script to speed up compiling. You can probably get away with this if you don't bundle any code via bundle: true setting passed to esbuild.

TSC

The TypeScript compiler is used only for type checking, everything else is handled by ESBuild.

Typescript/Eslint

TypeScript and ESLint configurations are matter of personal preference and can easily be adjusted to one's requirements. The same applies for ESBuild, you can also pass additional parameters to buildBrowser or buildNode which will override the default ones.

VSCode

If the .cache directories become annoying, you can just hide them in VSCode, create/edit this file under .vscode/settings.json.

{
    "files.exclude": {
        "cache/": true,
        "**/.turbo": true
    }
}

Version mismatches

You can quickly check whether your package dependencies are in sync, e.g, @repo/a and @repo/b are different versions of the same library.

// package.json (repo a)
{
    "name": "repo/a",
    "dependencies": {
        "foo": "^1.0.0"
    }
}
// package.json (repo b)
{
    "name": "repo/b",
    "dependencies": {
        "foo": "^2.0.0"
    }
}
npm run mismatch

Error: Found version mismatch for the following package:

foo - versions: ^1.0.0, ^2.0.0
- apps/package-a/package.json (@repo/a) - ^1.0.0
- apps/package-b/package.json (@repo/b) - ^2.0.0

This is just a quick and dirty solution that will only report mismatches but won't fix them for you. For more advanced solutions, check out syncpack.

Useful resources:

esbuild-typescript-turborepo's People

Contributors

barca-reddit 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.