Frontline: Preparing Grounds
Hossomi
Posted on August 14, 2022
Hello everyone! A long time after the first post, it's time to roll up the sleeves and start coding.
Before anything else, I like to prepare the project structure and build. The logical first step is installing Yarn and Typescript and get it to build anything.
In this article | Repository | Changes | Final commit
Setting up Yarn
To install Yarn, it is recommended to use Corepack, bundled with Node starting in 16.10. It seems to be an all-in-one package manager, and it already includes Yarn out of the box. All you need to do is run corepack enable
(since it is experimental and disabled by default) and then yarn init -2
to initialize a new project.
ℹ
-2
ensures that it uses Yarn 2+ (modern), required to work with zero-installs. More on it later!
As I mentioned, I want to use Yarn workspaces to organize modules. Each module needs its own package.json
file, so let's start with the following structure:
📦tamiyo
┣ 📂client
┃ ┗ 📜package.json
┣ 📂server
┃ ┗ 📜package.json
┣ 📂shared
┃ ┗ 📜package.json
┗ 📜package.json
The package.json
content is mostly the usual, the difference being that the parent file contains a workspaces
field specifying where the workspaces are:
{
"name": "tamiyo",
"version": "1.0.0",
"packageManager": "yarn@3.2.0",
"workspaces": [
"server",
"client",
"shared"
]
}
For the modules, we are prefixing their package names with @tamiyo
for consistency. The client file for example is like this:
{
"name": "@tamiyo/client",
"version": "1.0.0",
"packageManager": "yarn@3.2.0"
}
Running yarn install
makes sure we've setup correctly, and you'll notice it creates some files. The yarn.lock
is well known, and the others are related to Yarn's zero-installs: .yarnrc.yml
, .pnp.cjs
and the .yarn
directory. With all these checked into the repository, you no longer need to run this command unless dependencies change (hence zero installs)! Read the documentation for more advantages of this mechanism.
Setting up Typescript
Let's get started with Typescript! The first thing to do is to install it with yarn add -D typescript
. It will install the tsc
CLI tool that we can run with yarn tsc
to compile Typescript code into Javascript, making it runnable in broswers, node and the like.
Typescript is organized in projects, indicated by a tsconfig.json
file along with various project settings. It can also be divided into smaller subprojects, which pairs well with the Yarn workspaces we are using! We just have to place a tsconfig.json
file in each workspace as well.
📦tamiyo
┣ 📂client
┃ ┣ 📜package.json
┃ ┗ 📜tsconfig.json
┣ 📂server
┃ ┣ 📜package.json
┃ ┗ 📜tsconfig.json
┣ 📂shared
┃ ┣ 📜package.json
┃ ┗ 📜tsconfig.json
┣ 📜package.json
┗ 📜tsconfig.json
The root tsconfig.json
is special: it has a references
property specifying the subprojects, which in our case are the workspaces. We also specify "include": []
so that the root project doesn't build anything, since it's not a module itself.
{
"references": [
{ "path": "./shared" },
{ "path": "./client" },
{ "path": "./server" }
],
"include": []
}
The workspaces are where actual code resides, so their tsconfig.json
contains compiler options:
{
"compilerOptions": {
"rootDir": "src",
"outDir": "build",
"target": "es6",
"strict": true,
"noFallthroughCasesInSwitch": true,
"module": "commonjs",
"moduleResolution": "node",
"resolveJsonModule": true,
"composite": true,
"esModuleInterop": true,
"isolatedModules": false,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
}
}
You can see their meaning in the TSConfig reference. It's important to note that composite: true
is required when using Typescript subprojects. To avoid repeating all those properties in each workspace, we can extract them to a common tsconfig.common.json
and make the workspaces extend them:
# ./tsconfig.common.json
{
"compilerOptions": {
"target": "es6",
"strict": true,
"noFallthroughCasesInSwitch": true,
"module": "commonjs",
"moduleResolution": "node",
"resolveJsonModule": true,
"composite": true,
"esModuleInterop": true,
"isolatedModules": false,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
}
}
# {module}/tsconfig.json
{
"extends": "../tsconfig.common.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "build"
}
}
With that, we should be able to build from the root directory. Let's put a simple file under the src
directory of each module to test it out:
// {module}/src/index.ts
console.log('Hello!')
Running yarn tsc --build --verbose
should compile all the Typescript files and generate .d.ts
and .js
files under {module}/build
directories, as we instructed in the configuration. These files are what will be actually run by either Node, browser and the like.
Next step
Our project can at least be compiled! Next, it is time to get something up and running. As I mentioned, I will use Create React App to build our client, providing us a quick lift. We'll also see how we can implement and integrate our server with it.
Posted on August 14, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.