Step by step guide -
- Create the following dir structure
workspace
- packages
- app
- src
index.ts
- lib
- src
index.ts
- Run
tsc --init
andyarn init
inside the packages - Turn on
composite: true
,declarations: true
,declarationMapping: true
inside eachtsconfig.json
files. This ensures these packages can be referenced withtypescript references
- Set
rootDir: "src"
include: ["src"]
,outDir: "dist"
in bothtsconfig.json
files - add a typescript reference to
app/tsconfig.json
to reference the lib.
"references": [{ "path": "../lib" }],
- If typescript detects a package's sources
includes
a file outside it'srootDir
(e.g. an import tries to refer to it) it will start complianing with references enabled. Unless, a project reference has been added to the dependant project. - Now compile the project with
tsc -b packages/app
, clean the outputs withtsc -b --clean packages/app
- Typescript caches the output of referenced projects in
tsconfig.tsbuildinfo
files. - With typescript project references, the import path is still
import sayHi from ../../lib/src
this is whereyarn workspaces
come in handy. yarn workspaces help seperate out yourtypescript projects
to standalonenpm packages
and connect them viasymlinks
. - create a yarn workspace by running
yarn init
at the root (i.e. under the workspaces folder) - Add the following config in
workspaces\package.json
"workspaces": [
"packages/*"
],
- Now
yarn
should pick up these packages - These could now be linked with
yarn workspace app add lib
- Somehow this didn't work for me, instead i had to add the reference directly in
app
'spackage.json
"dependencies": {
"lib": "*"
}
"lib": "*"
means grabs the latest version, typically in the context of yarn workspaces this means grab whatever's on local.- Now run
yarn
at the root (to force runyarn --force
) - Verify the workspace dependencies have been create with
yarn workspace info
{
"app": {
"location": "packages/app",
"workspaceDependencies": [
"lib"
],
"mismatchedWorkspaceDependencies": []
},
"lib": {
"location": "packages/lib",
"workspaceDependencies": [],
"mismatchedWorkspaceDependencies": []
}
}```
- This output is quite useful, particularly
mismatchedWorkspaceDependencies
it tells if a given dependency cannot be satisfied with the local version. These will not generatesymlinks
. - I've found that yarn has issue with
pre-release identifiers
onsemver
e.g.1.1.837-alpha.0
is valid semver, however yarn refused to resolve this version till i removed the prerelease identifier. yarn
with hoist the dependencies to the rootnode_modules
folder. only package specific deps and executable commands will live in package specificnode_modules
folders.- Now the import can be simplified to
import sayHi from 'lib/src'
- Set the entrypoint in
lib/package.json
to simplify this further
"main": "dist/index.js",
- Now the import is simply
import sayHi from 'lib'
๐ - If
tsc
has trouble findings the types of thelib
package. Settypings
\types
todist\index.d.ts
- Compile again with `tsc -b packages\app
- Optional: pin
node
andyarn
versions withvolta
- Install
volta
globally - Run
volta pin node@18
andvolta pin yarn@1
- Voila! ๐๐