(he/him)

@AtilaFassina

What are Monorepos?

a single repository containing multiple distinct projects, with well-defined relationships.

--

@AtilaFassina

🧠

Brain as Monorepo

🇪🇸

@AtilaFassina

🧠

Missing Packages

🥊

🍺

🥱

@AtilaFassina

🧭 Module Resolution

🏗 Build Orchestration

⏱ CI Times

🪥Chores, Chores, Chores...

🐑 Versioning

@AtilaFassina

Module Resolution

🧠

🇪🇸

🇧🇷

@AtilaFassina

Latin

Same dependency

🇪🇸

🇧🇷

🧠

@AtilaFassina

Tapas

Different Versions

🇪🇸

🇧🇷

🧠

@AtilaFassina

🇪🇸

🇧🇷

Tapas

@AtilaFassina

🇪🇸

🇧🇷

🧠

tapa
vAggressive
tapa
vFood

Versions

@AtilaFassina

🧠

tapas
vAggressive

¿Quieres uns                  ?

tapas

🙂

🇪🇸

Bad Module Resolution

¡Noooo!

@AtilaFassina

Package Pipeline

🔍 Statical Analysis

🧱 Build

📐 Tests

👾 Integration Tests

⛴ Ship

@AtilaFassina

Interdependencies

@AtilaFassina

All Tests

All Builds

All Linters

@AtilaFassina

depends on
time

@AtilaFassina

MAKE

PARALLEL

THINGS

@AtilaFassina

depends
time
on
build
build

@AtilaFassina

time

🏁

🏁

CI Times

@AtilaFassina

Hygiene Tasks

🪥 Changelogs

🪥 Dependency Updates

🪥 Version Bumps

🪥 Releases and Publishing

@AtilaFassina

GOOD

NEWS

TIME

@AtilaFassina

🧭 Module Resolution

🏗 Build Orchestration

🪥Hygiene Tasks

🧭

setup

once

for

every

project

🤗

@AtilaFassina

START

SHARING

@AtilaFassina

How?

@AtilaFassina

🤝 Peer Dependency Management

🍱 Hard Disk Efficiency

📦 Fast Installs

👻 Reliable Module Resolution

@AtilaFassina

🎻 Pipeline Orchestration

☁️ Remote Caching

🏃 Task Runner

@AtilaFassina

📠 Changelog Generation

🤖 Automated

🤐 Versioning without Opinions

@AtilaFassina

🧼 Pull Request Maintenance

🤖 Automated

⏫ Dependency Update

@AtilaFassina

@AtilaFassina

Release, Changelog, Publishing, Dependency Updates

Fast-Refresh and Hot-Reloading for Remix and Next.js

🧼

ESM and CJS export for packages

⚛️

🎁

Ready to go:  

🥡

@AtilaFassina

const withTM = require("next-transpile-modules")()

/**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
}

module.exports = withTM(nextConfig)

@AtilaFassina

const INTERNAL_ESM_PACKAGES = ["ui"]
const PACKAGES_PATHS = ["../../packages/ui"]

/** @type {import('@remix-run/dev').AppConfig} */
module.exports = {
  serverBuildTarget: "vercel",
  server: process.env.NODE_ENV === "development" ? undefined : "./server.js",

  watchPaths: PACKAGES_PATHS,

  serverDependenciesToBundle:
    process.env.NODE_ENV === "development" ? [...INTERNAL_ESM_PACKAGES] : [],
}

@AtilaFassina

{
  "main": "./dist/index.js",
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "require": "./dist/index.js",
      "import": "./dist/index.mjs",
      "types": "./dist/index.d.ts"
    }
  },
  "scripts": {
    "build": "tsup src/index.tsx --format cjs,esm --dts"
  }
 }

@AtilaFassina

{
  "dependencies": {
    "ui": "workspace:^"
  },
  "devDependencies": {
    "eslint-config-custom": "workspace:*"
  }
 }

Consuming

@AtilaFassina

{
  $schema: "https://docs.renovatebot.com/renovate-schema.json",
  labels: ["dependencies"],
  extends: ["config:base"],
  packageRules: [
    {
      matchUpdateTypes: ["minor", "patch", "pin", "digest"],
      labels: ["automerge", "dependencies"],
    },
  ],
}

Renovate

@AtilaFassina

version = 1

[merge]
automerge_label = "automerge"

[merge.automerge_dependencies]
versions = ["minor", "patch"]
usernames = ["renovate"]

[update]
ignored_usernames = ["renovate"]

Kodiak

@AtilaFassina

@AtilaFassina

¡Gracias!

Monorepos Today

By Atila

Monorepos Today

  • 178