Skip to content

🧶 Yarn Configuration

Sasha Boginsky edited this page May 8, 2023 · 15 revisions

Yarn Workspaces

How this project's workspaces were configured and how to work with them during development.

Initialize Yarn

Switch to the latest Yarn version for the fastest way to configure workspaces:

yarn set version berry

Yarn installs on .yarn/releases and can be safely checked in the repo.

Add a .yarnrc.yml:

nodeLinker: pnp

pnpMode: loose
checksumBehavior: update
# Currently preferred way to install Yarn within a project - ensures using the exact same Yarn version
yarnPath: .yarn/releases/yarn-3.5.1.cjs

# allows `eslint` to resolve "react-app" on the frontend: see https://github.com/facebook/create-react-app/issues/10463
packageExtensions:
  react-scripts@*:
    peerDependencies:
      eslint-config-react-app: "*"
  • You can find additional documentation on yarnrc configuration here

Package Architecture

Workspaces root

The workspaces root will have it's own package.json with a workspaces field and private set to true.

The below command initializes it for you by creating the package.json, an empty packages directory, a yarn.lock, .gitignore, .editorconfig, and README.md.

yarn init -w

Workspaces packages

Each directory in packages should be a workspace. These will contain their own package.json, but they all share a single yarn.lock from the root.

We initialize two packages, one used to compile and deploy smart contracts and the other to build and ship a web UI to interact with them:


Hardhat (Compile and deploy smart contracts)

  1. Setup the package:

    yarn packages/hardhat init && rm packages/hardhat/README.md  # remove conflicting files Hardhat setup will create
  2. Initialize a Hardhat project:

    yarn workspace hardhat add -D hardhat && yarn workspace hardhat hardhat  # init a Hardhat project
  3. When prompted, select the "Create a TypeScript project" option from the dropdown and "n" for installing dependencies

    888    888                      888 888               888
    888    888                      888 888               888
    888    888                      888 888               888
    8888888888  8888b.  888d888 .d88888 88888b.   8888b.  888888
    888    888     "88b 888P"  d88" 888 888 "88b     "88b 888
    888    888 .d888888 888    888  888 888  888 .d888888 888
    888    888 888  888 888    Y88b 888 888  888 888  888 Y88b.
    888    888 "Y888888 888     "Y88888 888  888 "Y888888  "Y888
    
    👷 Welcome to Hardhat v2.11.1 👷‍
    
    ✔ What do you want to do? · Create a TypeScript project
    ✔ Do you want to install this sample project's dependencies with npm (@nomicfoundation/hardhat-toolbox)? (Y/n) · n
    

React (Build and ship a web UI)

yarn create react-app --template typescript packages/frontend  # init a React project using the react-app TS template

Workspaces are referenced by the name field set in their respective package.json, not their folder name. You can change the workspace names there manually.

In this project, the hardhat workspace is renamed -> rps-hardhat and the frontend workspace -> rps-frontend after initializing them. So the workspace command becomes $ yarn workspace <rps-hardhat | rps-frontend> <command>


Development

To install dependencies for all packages

yarn install

To reference nested package scripts

yarn workspace <workspace-name> <command_name>

Yarn Plug'n'Play


Editor Setup - VSCode

To support features like go-to-definition a plugin like ZipFS is needed. Add this extension.

TypeScript + PnP

Smart IDEs (such as VSCode or IntelliJ) require special configuration for TypeScript to work when using Plug'n'Play installs.

  1. We need to install TypeScript and setup our IDE to support it.

    yarn add -D typescript
    yarn dlx @yarnpkg/sdks vscode # enable VSCode integration
  2. For safety reasons VSCode requires you to explicitly activate the custom TS settings: press ctrl+shift+p in a TypeScript file

  3. Choose "Select TypeScript Version"

  4. Pick "Use Workspace Version"

Other common editor tools

Besides Typescript, we also want our project to support Prettier

To enable this, we just have to add them as dependencies:

yarn add prettier

Plugins


Going back to TypeScript, ---

You can optionally enable Yarn's TypeScript plugin, which helps manage @types/* dependencies automatically.

yarn plugin import typescript

Besides this, I have added two more plugins for convenience:

yarn plugin import interactive-tools  # adds support for various interactive commands.
yarn plugin import workspace-tools  # adds support for various workspace-related commands.

You can find all the plugins in the API Section