Skip to content

Commit

Permalink
added the last chapter
Browse files Browse the repository at this point in the history
  • Loading branch information
Mordechai Dror committed Dec 23, 2023
1 parent 1a913a5 commit d26663d
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 17 deletions.
13 changes: 12 additions & 1 deletion packages/blog/src/components/organisms/PostFrontmatter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function PostFrontmatter({
post,
minutesRead,
}: PostFrontmatterProps): ReactElement {
const { title, tags, coverImage, description } = post.data;
const { title, tags, coverImage, description, code } = post.data;

return (
<>
Expand Down Expand Up @@ -47,6 +47,17 @@ export function PostFrontmatter({
<p>
<em>{description}</em>
</p>

{code && (
<p>
All the code mentioned in the post can be found in my{' '}
<a

Check warning

Code scanning / CodeQL

Potentially unsafe external link Medium

External links without noopener/noreferrer are a potential security risk.
href={code}
target="_blank">
GitHub
</a>
</p>
)}
</>
);
}
92 changes: 76 additions & 16 deletions packages/blog/src/content/posts/typescript-monorepos-are-a-mess.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ tags:
- typescript
- node
- infra
publishedAt: 2023-12-22
publishedAt: 2023-12-23
coverImage:
related:
isPinned:
Expand Down Expand Up @@ -91,11 +91,12 @@ Since we have a support for monorepo on package manager level it won't be a prob
// app package.json
{
name: 'app',
packageManager: 'yarn@4.0.2',
// ...
scripts: {
start: 'node src/main.js',
},
dependencies: {
// ...
lib: 'workspace:^',
// ...
},
// ...
}
Expand All @@ -105,7 +106,6 @@ Since we have a support for monorepo on package manager level it won't be a prob
// lib package.json
{
name: 'lib',
packageManager: 'yarn@4.0.2',
main: 'src/index.js',
// ...
}
Expand All @@ -122,23 +122,74 @@ Compiling a monorepo is also relatively easy task: `tsc`, built-in compiler of T

```json5
// app package.json
{
name: 'app',
scripts: {
start: 'node dist/main.js',
clean: 'shx rm -rf dist',
build: 'yarn clean && tsc --build',
},
dependencies: {
lib: 'workspace:^',
// ...
},
devDependencies: {
shx: '^0.3.4',
typescript: '^5.3.3',
// ...
},
// ...
}
```

```json5
// app tsconfig.json
{
compilerOptions: {
// ...
},
references: [{ path: '../lib' }],
// ...
}
```

```json5
// lib package.json
{
name: 'lib',
main: 'dist/index.js',
types: 'dist/index.d.ts',
scripts: {
clean: 'shx rm -rf dist && shx rm -f tsconfig.tsbuildinfo',
build: 'yarn clean && tsc --build',
},
devDependencies: {
shx: '^0.3.4',
typescript: '^5.3.3',
},
// ...
}
```

```json5
// lib tsconfig.json
{
compilerOptions: {
declaration: true,
composite: true,
// ...
},
// ...
}
```

A couple of notes here:

-
- `shx rm -rf dist` - is a quick way to clean stuff from previous build since `tsc` in some cases doesn't do it by itself
- `tsc --build` - is a flag that tells `tsc` to traverse the dependency tree and build them as well if needed
- `references: [{ path: '../lib' }]` - list of all dependencies that needs to be handled by `tsc`, e.g. all the packages linked by `workspace:^` protocol need to be duplicated in this list
- `composite: true` - `tsc` flag that tell it to not only generate the JS output, but `tsconfig.tsbuildinfo` file as well, that is used to determine whether lib JS code is in sync with latest TS code
- `shx rm -rf dist && shx rm -f tsconfig.tsbuildinfo` - since `tsconfig.tsbuildinfo` is essentially a part of build it also needs to be cleaned upon re-builds

###### Live-reload dev server

Expand Down Expand Up @@ -166,27 +217,36 @@ There is a good comment in [the issue on GitHub](https://github.com/privatenumbe

The final solution that I found working for me is actually avoiding all 3-party tooling. You see `tsc` itself has built-in watch mode, the only last part there is to restart the server on each re-build. And recently NodeJS introduced its own watch mode (it's still experimental, but I'm OK to use experimental stuff for dev-only purposes). As simple as that: run `tsc` in watch mode, it will rebuild code on changes resolving project references, run `node` in watch mode, it will restart process on changes resolving changes in monorepo dependencies as well.

```json
```json5
// app package.json
{
"name": "app",
"packageManager": "yarn@4.0.2",
name: 'app',
packageManager: 'yarn@4.0.2',
// ...
"scripts": {
// ..
"start:watch": "node --watch dist/main.js",
"build:watch": "tsc --build --watch"
scripts: {
start: 'node dist/main.js',
'start:watch': 'node --watch dist/main.js',
clean: 'shx rm -rf dist',
build: 'yarn clean && tsc --build',
'build:watch': 'tsc --build --watch',
},
dependencies: {
lib: 'workspace:^',
// ...
}
// ...
},
devDependencies: {
shx: '^0.3.4',
typescript: '^5.3.3',
// ...
},
}
```

It does mean running two processes instead of one like we are used in polyrepo projects, but as long as it is constant amount of processes per any amount of monorepo projects its fine by me.

Also as a small semantic sugar: we can run both those processes with a single command by using `concurrently`

```json
```json5§§
// root package.json
{
"name": "typescript-monorepo",
Expand Down

0 comments on commit d26663d

Please sign in to comment.