The best yarn workspaces commands and practices in a single file
- A workspace is just an
npm
package, aka a folder with apackage.json
. - With Yarn workspaces any of these local workspaces/packages can be used as regular npm package without having to publish it
Command | Goal | Api | Examples |
---|---|---|---|
yarn workspace | Run a Yarn command in a specific workspace | yarn workspace <workspace_name> | - yarn workspace package-a add react react-dom - yarn workspace package-a build |
yarn workspaces run | Run a Yarn command in all existing project workspaces | yarn workspaces run | - yarn workspaces run add react react-dom - yarn workspaces run build |
yarn workspaces info | See which workspace uses which workspace | yarn workspaces run | - yarn workspaces run add react react-dom - yarn workspaces run build |
// Root package.json
{
"name": "my-repo",
+ "private": true, // Do not allow publishing of workspace on NPM
+ "workspaces": [
+ "someofolder/somesubfolder", // This specific folder is a workspace
+ "somefolder/*" // Any folder under somefolder is a workspace
+ ],
"scripts": {}
}
$ cd somefolder && mkdir my-package # "somefolder/my-package" matches "somefolder/*" in root package.json "workspaces"
$ cd my-package && npm init -y # Generate package definition
// somefolder/my-package.json
{
+ "name": "my-repo", // Name is how you reference a package in the workspaces, just as any regular npm package
+ "main": "dist/index.js" // The entry file for your package, can be whatever file you want
}
// somefolder/a/package.json
{
dependencies: [
+ "package-b": "*" // "*" Matches any available version of package-b
]
}
$ yarn workspace package-a add package-b@* // "package-a" and "package-b" matche the package's package.json "name" key
$ yarn workspaces info # Displays the workspaces dependeny tree of your project
// Logs
yarn workspaces vx.x.x
{
"package-a": {
"location": "packages/package-a",
"workspaceDependencies": [
"package-b" // π package-a uses package-b workspace/package
],
"mismatchedWorkspaceDependencies": []
},
"package-b": {
"location": "packages/package-b",
"workspaceDependencies": [], // π package-b uses no workspace/package
"mismatchedWorkspaceDependencies": []
}, ... }
Chances are one day you'll end up with an error of this kind: Module not found
or A different version of {package_name} was detected higher up in the tree
.
That means the sharing of {package_name} isn't working out.
Use nohoist
to prevent sharing of specific packages between workspaces.
# root package.json
{
...
"workspaces": {
"packages": [
...
],
+ "nohoist": [
+ "**/jest", // For any package, don't hoist jest
+ "**/jest*", // For any package, don't hoist any package starting with "jest" Ex: jest-then, jest-when, ...
+ "**/jest/**", // For any package, don't hoist any jest sub package Ex: jest/core
+ "my-package-a/jest", // For package "my-package-a", don't hoist jest
+ ]
},
...
}
@todo
- https://github.com/isthatcentered/unicorn/ (disclaimer, this is mine)