This is an alpha, sneak peek of Monorepo Maestros. For this iteration, I'm getting all of my thoughts down. In the future, we'll have better information architecture, graphics, and other awesomeness. Your feedback is welcome!

Prettier

Prettier is a great formatter for quickly taking care of simple, non-logic stuff in your codebase. You can quickly, automatically standardize your entire codebase to have the same stylistic qualities and never worry about it again.

Setting up Prettier

As we head into getting Prettier set up, let's remember our requirements for conducting a monorepo symphony:

Creating your configuration

We're going to create one root Prettier configuration that we share to all of our workspaces. Let's first create a workspace for our Prettier configuration in tooling/prettier-config.

  • tooling
    • prettier-config
      • index.js
      • package.json
  • Our package.json will be relatively simple, installing prettier and exporting the files where we'll keep our presets. We'll also install prettier-plugin-packagejson for formatting package.json files throughout our repository.

    tooling/prettier-config/package.json
    {
    "name": "@repo/prettier",
    "version": "0.0.0",
    "private": true,
    "files": ["index.js"],
    "devDependencies": {
    "prettier": "2.8.8",
    "prettier-plugin-packagejson": "^2.4.3"
    }
    }
    tooling/prettier-config/package.json
    {
    "name": "@repo/prettier",
    "version": "0.0.0",
    "private": true,
    "files": ["index.js"],
    "devDependencies": {
    "prettier": "2.8.8",
    "prettier-plugin-packagejson": "^2.4.3"
    }
    }

    And now we'll make an index.js file with your Prettier configuration in it:

    tooling/prettier-config/index.js
    // Purely for demonstration! Adjust to your liking.
    /** @type {import("prettier").Options} */
    const config = {
    tabWidth: 2,
    semi: false,
    singleQuote: true,
    };

    export default config;
    tooling/prettier-config/index.js
    // Purely for demonstration! Adjust to your liking.
    /** @type {import("prettier").Options} */
    const config = {
    tabWidth: 2,
    semi: false,
    singleQuote: true,
    };

    export default config;

    Add to your workspaces

    To put your workspace into your configuration, install your @repo/prettier package to your workspace and a format script:

    packages/ui/package.json
    {
    "name": "@repo/ui",
    "version": "0.0.0",
    "scripts": {
    "format": "prettier \"**/*.{ts,tsx,md,mdx,json}\" --check"
    },
    "devDependencies": {
    "@repo/prettier": "workspace:*"
    }
    }
    packages/ui/package.json
    {
    "name": "@repo/ui",
    "version": "0.0.0",
    "scripts": {
    "format": "prettier \"**/*.{ts,tsx,md,mdx,json}\" --check"
    },
    "devDependencies": {
    "@repo/prettier": "workspace:*"
    }
    }

    And add a .prettierrc.js at the top of your workspace:

    packages/ui/.prettierrc.js
    module.exports = '@repo/prettier';
    packages/ui/.prettierrc.js
    module.exports = '@repo/prettier';

    As you can see, this file is pretty simple. We're exporting the configuration that we made in @repo/prettier so that the Prettier CLI knows to use it in this workspace.

    Write a pipeline

    Once we've created our formatting scripts in any workspaces that we want to format, it's time to build up our Turborepo pipeline.

    turbo.json
    {
    "pipeline": {
    "format": {
    "outputs": ["node_modules/.cache/.prettiercache"],
    "outputMode": "new-only"
    }
    }
    }
    turbo.json
    {
    "pipeline": {
    "format": {
    "outputs": ["node_modules/.cache/.prettiercache"],
    "outputMode": "new-only"
    }
    }
    }

    Run your format tasks

    With all of that ready to go, we're now ready to run our tasks!

    In the root of our monorepo, we will create these scripts:

    package.json
    {
    "scripts": {
    "format": "turbo format --continue -- --cache --cache-location='node_modules/.cache/.prettiercache'",
    "format:fix": "turbo format --continue -- --write --cache --cache-location='node_modules/.cache/.prettiercache'"
    }
    }
    package.json
    {
    "scripts": {
    "format": "turbo format --continue -- --cache --cache-location='node_modules/.cache/.prettiercache'",
    "format:fix": "turbo format --continue -- --write --cache --cache-location='node_modules/.cache/.prettiercache'"
    }
    }

    Run pnpm format! On the first run, the command will create caches in each workspace both at the Prettier and Turborepo layers.

    Breaking down the script

    There are a few key parts to this script. Breaking it down piece by piece:

    With this all in place, you can run your linting tasks with incredible speed.