Mastering Monorepos: A Guide to npm/yarn Workspaces for Frontend, Backend, and Mobile Apps
Varghese C.
Director of Technology | Driving Innovation & Digital Transformation with a Purpose | Leading Multi-Million Dollar Projects | Doctoral Studies in AI & Business Administration | Published Author & Thought Leader
In software development, a monorepo (short for "monolithic repository") is a version control strategy where multiple projects or codebases are stored in a single, shared repository. This approach contrasts with the more traditional multi-repo strategy, where each project or component is housed in its own separate repository.
Key characteristics of a Monorepo
1. Single Repository: All code for different projects, components, or services is stored in one repository.
2. Shared Dependencies: Common libraries and dependencies are stored and managed centrally.
3. Unified Versioning: Since all projects are in one place, versioning and dependency management can be more straightforward.
4. Consistent Tooling: Development tools, build scripts, and configurations can be standardized across projects.
5. Code Visibility: Developers have access to all parts of the codebase, which can enhance collaboration and code reuse.
Benefits of a Monorepo
- Simplified Dependency Management: Shared dependencies can be updated and managed in one place.
- Improved Code Reuse: Code can be easily shared across projects, reducing duplication.
- Enhanced Collaboration: Developers can see and work on different parts of the system more easily.
- Consistent Development Practices: Standardizing tools and practices is easier when all projects reside in the same repository.
- Atomic Changes: Changes that span multiple projects can be made atomically, ensuring consistency.
Challenges of a Monorepo
- Scalability: As the codebase grows, the repository can become large and unwieldy, requiring sophisticated tooling to manage.
- Tooling and Infrastructure: Requires tools and infrastructure that can handle large repositories and complex dependency trees.
- Build Times: Larger codebases can lead to longer build times, though incremental build systems can mitigate this.
- Access Control: Managing permissions and access control can be more complex when all code is in one place.
A monorepo can offer significant benefits in terms of collaboration, code reuse, and dependency management, but it also introduces challenges in terms of scalability and tooling. Whether to use a monorepo or a multi-repo approach depends on the specific needs and context of the organization.
Maintaining Front-end, Back-end and Mobile application in a monorepo
You can use the same monorepo to manage your frontend in React, backend in Node.js, and mobile app in React Native. This setup can offer several benefits, including consistent development practices, easier dependency management, and improved collaboration among teams. Here’s how you can effectively manage this setup:
Here is a comprehensive guide for managing a monorepo using npm and yarn.
Workflow for npm
1. Initialize the monorepo
mkdir my-monorepo
cd my-monorepo
npm init -y
2. Configure npm workspaces
Modify the root package.json to define your workspaces.
{
"private": true,
"workspaces": [
"frontend",
"backend",
"mobile",
"shared"
]
}
3. Create project directories
mkdir frontend backend mobile shared
4. Initialize each project
Navigate to each directory and initialize npm projects.
cd frontend
npm init -y
cd ../backend
npm init -y
cd ../mobile
npm init -y
cd ../shared
npm init -y
cd ..
5. Install npm-run-all in the root directory
npm install npm-run-all --save-dev
6. Add scripts and dependencies in each workspace
Example frontend/package.json:
{
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "jest"
},
"devDependencies": {
"react-scripts": "^4.0.3",
"jest": "^26.6.0"
}
}
Repeat similar steps for backend, mobile, and shared directories.
7. Define scripts in the root package.json
{
"private": true,
"workspaces": [
"frontend",
"backend",
"mobile",
"shared"
],
"scripts": {
"start:all": "npm-run-all -p start:*",
"build:all": "npm-run-all -p build:*",
"test:all": "npm-run-all -p test:*",
"start:frontend": "npm --workspace frontend start",
"build:frontend": "npm --workspace frontend build",
"test:frontend": "npm --workspace frontend test",
"start:backend": "npm --workspace backend start",
"build:backend": "npm --workspace backend build",
"test:backend": "npm --workspace backend test",
"start:mobile": "npm --workspace mobile start",
"build:mobile": "npm --workspace mobile build",
"test:mobile": "npm --workspace mobile test",
"start:shared": "npm --workspace shared start",
"build:shared": "npm --workspace shared build",
"test:shared": "npm --workspace shared test"
},
"devDependencies": {
"npm-run-all": "^4.1.5"
}
}
8. Add, update, and remove dependencies
npm install axios --workspace=frontend
npm update axios --workspace=frontend
npm uninstall axios --workspace=frontend
9. Run scripts for all workspaces
npm run start:all
npm run build:all
npm run test:all
10. Run scripts separately
npm run start:frontend
领英推荐
npm run build:backend
npm run test:mobile
11. CI setup for Azure
Create a azure-pipelines.yml file in the root directory:
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '16.x'
displayName: 'Install Node.js'
- script: npm install
displayName: 'Install Dependencies'
- script: npm run build:all
displayName: 'Build All Workspaces'
- script: npm run test:all
displayName: 'Test All Workspaces'
Workflow for yarn
1. Initialize the monorepo
mkdir my-monorepo
cd my-monorepo
npm init -y
2. Configure yarn workspaces
Modify the root package.json to define your workspaces.
{
"private": true,
"workspaces": [
"frontend",
"backend",
"mobile",
"shared"
]
}
3. Create project directories
mkdir frontend backend mobile shared
4. Initialize each project
Navigate to each directory and initialize npm projects.
cd frontend
npm init -y
cd ../backend
npm init -y
cd ../mobile
npm init -y
cd ../shared
npm init -y
cd ..
5. Add scripts and dependencies in each workspace
Example frontend/package.json:
{
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "jest"
},
"devDependencies": {
"react-scripts": "^4.0.3",
"jest": "^26.6.0"
}
}
Repeat similar steps for backend, mobile, and shared directories.
6. Define Scripts in the Root package.json
{
"private": true,
"workspaces": [
"frontend",
"backend",
"mobile",
"shared"
],
"scripts": {
"start:all": "yarn workspaces foreach run start",
"build:all": "yarn workspaces foreach run build",
"test:all": "yarn workspaces foreach run test",
"start:frontend": "yarn workspace frontend run start",
"build:frontend": "yarn workspace frontend run build",
"test:frontend": "yarn workspace frontend run test",
"start:backend": "yarn workspace backend run start",
"build:backend": "yarn workspace backend run build",
"test:backend": "yarn workspace backend run test",
"start:mobile": "yarn workspace mobile run start",
"build:mobile": "yarn workspace mobile run build",
"test:mobile": "yarn workspace mobile run test",
"start:shared": "yarn workspace shared run start",
"build:shared": "yarn workspace shared run build",
"test:shared": "yarn workspace shared run test"
}
}
To run scripts in parallel, add the flag '-pt' to yarn's foreach as below
{
"scripts": {
"start:all": "yarn workspaces foreach -pt run start",
"build:all": "yarn workspaces foreach -pt run build",
"test:all": "yarn workspaces foreach -pt run test"
}
}
7. Add, update, and remove dependencies
yarn workspace frontend add axios
yarn workspace frontend upgrade axios
yarn workspace frontend remove axios
8. Run scripts for all workspaces
yarn start:all
yarn build:all
yarn test:all
9. Run scripts separately
yarn start:frontend
yarn build:backend
yarn test:mobile
10. CI setup for Azure
Create a azure-pipelines.yml file in the root directory:
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '16.x'
displayName: 'Install Node.js'
- script: yarn install
displayName: 'Install Dependencies'
- script: yarn build:all
displayName: 'Build All Workspaces'
- script: yarn test:all
displayName: 'Test All Workspaces'
This guide provides a detailed workflow for managing a monorepo using both npm and Yarn, covering:
By following these steps, you can efficiently manage your monorepo, ensuring a smooth and streamlined development process.
Managing a monorepo with npm and Yarn workspaces can significantly streamline your development process, making it easier to handle dependencies, run scripts, and set up continuous integration. By following this comprehensive guide, you can ensure that your frontend, backend, mobile, and shared projects are efficiently managed, tested, and deployed.
If you found this article helpful, consider subscribing to our newsletter for more in-depth tutorials, tips, and best practices on modern software development. Stay updated with the latest trends and enhance your development skills with our expert insights.
#JotLore #Monorepo #NxDevTools #JavaScript #TypeScript #npm #Yarn #Frontend #Backend #MobileDevelopment #DevOps #CodeQuality #SoftwareDevelopment #Programming #TechGuide #WebDevelopment #ContinuousIntegration #SoftwareEngineering #TechTips #CodingLife #DevCommunity