Home  >  Article  >  Development Tools  >  Play with Lerna to help you easily build Monorepo

Play with Lerna to help you easily build Monorepo

DDD
DDDOriginal
2023-09-11 10:13:021044browse

What is Monorepo?

monorepo is a single repository with multiple related services, projects and components that can be used by different teams It to store code for related or unrelated projects. The word monorepo is derived from mono, which means single, and repo, which is the abbreviation of repository.

Benefits of Monorepo

Here are some of the major benefits of using monorepo :

  • Code Sharing: Projects share standard code, libraries or utilities.
  • Reusability: Components need to be reused in different projects.
  • Easier Code Reviews: Code reviews are more efficient in monorepo because reviewers can easily see the context of changes between related projects, which can improve code quality and detect potential problems earlier.
  • Simplified CI/CD process: It’s easier to publish multiple projects simultaneously using a single repository.
  • Consistent dependency management: Projects share similar or overlapping dependencies, and you want to centrally manage dependencies.
  • Team Collaboration: Teams working on related projects can collaborate more effectively and share knowledge, insights, and resources in a single repository.
  • Microservices Architecture: When dealing with a set of closely related microservices, a single repository can simplify code sharing, dependency management, and testing across services.
  • Version consistency: All projects can share a standard version control architecture, simplifying communication and understanding.

Libraries and tools specifically designed for managing Monorepos using Node.js

  • Lerna: A widely used tool for managing JavaScript projects with multiple packages.
  • Nx: Focused on Angular but applicable to other frameworks, Nx provides powerful development tools for monorepos with an emphasis on efficient workflows, code reuse and testing.
  • Yarn Workspace: Yarn’s built-in monorepo functionality allows multiple packages to be managed within a single repository.
  • Rush: A scalable monorepo manager developed by Microsoft, suitable for large code bases.
  • Bolt: A single repository management tool focused on performance that can be faster than Lerna for some operations.
  • Monorepo Manager: This tool simplifies the creation and maintenance of monorepo, providing a user-friendly interface to manage packages, dependencies and scripts.
  • pnpm: Like Yarn, pnpm also supports monorepo setups through its workspace feature, which reduces duplication and improves disk space utilization through shared dependencies.

Each tool offers specific benefits and features, so the choice depends on your project's requirements and preferences.

Why Lerna?

Lerna is a tool designed for managing repositories containing multiple npm packages. It simplifies the process of handling dependencies, publishing and publishing packages across multiple package repositories within a single git repository. Lerna is particularly useful for monorepo as it enables efficient code sharing and collaboration between developers working on different npm packages in the same repository. It improves development lifecycle management by allowing developers to treat projects with multiple packages as a single entity.

Prerequisites before installing Lerna

  • #Git: Download and install Git
  • Git Bash (Terminal) : If you are using Windows, Git Bash is included with the Git installation; For macOS and Linux, use your system's terminal.
  • Node.js: Download and install Node.js
  • npm : npm is included with Node.js, so once Node.js is installed, npm is available in your terminal. Verify by opening a terminal and typing. npm -v.

#We are creating a single repository that includes the payment services used by the backend server. In addition, the backend server and payment service will share the log service.

  • Log Service: Designed for efficient logging across various services.
  • Payment Service: is responsible for processing payment-related functions.
  • Backend Server: Performs payment processing and integrates logging services for seamless operation.

Play with Lerna to help you easily build Monorepo

Now let’s dive into implementing Monorepo using Lerna.

Step 1: Create Directory and Initialize Lerna

Navigate to the root directory of the project and initialize Lerna:

mkdir monorepo # create a repo directory of the monorepo 
cd monorepo
npx lerna@latest init # initalize the repo

The npx command above will create a new Lerna-managed repository.
lerna.json: The configuration file contains settings for Lerna behavior, such as version control mode, package location, etc.

package.json : The root package.json file for the entire repository.

Play with Lerna to help you easily build Monorepo

git config user.name ${username}
git config user.email ${email}

Step 2: Generate Backend Package

Make sure you are in the root folder of your project middle.

Lerna command for creating package: npx lerna create #{packageName} #{directory}

here , the directory is the default: packages

npx lerna create back-end 
//or
//this will skip the questionnaire related to package
npx lerna create back-end -y

上面的命令,不带-y  会提示你各种问题,比如覆盖包名、添加描述等等。但是,这些详细信息对于本示例来说并不重要,因此请按“Enter”键。

运行后,包后端将如下所示:

Play with Lerna to help you easily build Monorepo

步骤3:生成支付和日志服务包

再次执行相同的过程,但指定要创建的服务的目录,因为我们希望包位于该"services/"目录中。

In the root package.json file you must also tell Lerna about the package in the directory services/. Editpackage.jsonWorkspace configuration and add"services/*" into it. The configuration should look similar to the following:

Main package.json## at the root level # file, you must tell Lerna about the packages in the services/ directory. Modify workspace configurationpackage.json and include "services/*" . The configuration should look like this:

Play with Lerna to help you easily build Monorepo##

npx lerna create payment services -y
npx lerna create logging services -y

第 4 步:设置日志服务

在该目录中,通过简单的配置使用 Bunyan 库services/logging设置日志记录服务。

  • 在日志服务中安装 Buyan 库,并将 Mocha 作为开发依赖项安装在根目录中,以测试所有服务。

// root folder install test dependencies
npm install mocha --save-dev 
//inside logging
cd services/logging
npm install bunyan
  • 替换日志功能文件的内容services/logging/lib/logging.js

const bunyan = require('bunyan');
const logger = bunyan.createLogger({
  name: 'my-logging-service',
  level: 'info',
});
module.exports = logger;
  • 日志记录测试用例(测试记录器):
  • 替换测试文件的内容services/logging/__tests__/logging.test.js

const loggingService = require('../lib/logging'); // Import the logging service
describe('Logging Service', () => {
  it('should log messages', () => {
    loggingService.info('Test log message');
  });
});
  • 更新 services/logging 的 package.json 中的测试脚本。
"test": "mocha ./__tests__/logging.test.js"
  • package.json 应如所附图像所示。

Play with Lerna to help you easily build Monorepo

  • It’s time to run the test using lernanpx lerna run test --scope="logging"

Play with Lerna to help you easily build Monorepo

  • The log service implementation is now in place, let's develop the payment service.

Step 5: Set up the payment service

The payment service has a function called makePayment, which accepts a single parameter as an amount and utilizes a logger service to log the activity.

In the services/payment directory, and set up payment services through simple functions.

  • 将现有脚本替换为 mocha,提供用于测试目的的代码片段。
  • 要在支付服务中使用日志记录服务,请将其依赖项添加到支付服务的 package.json 中,如下所述。然后,npm iservices/payment目录中运行进行安装。
"scripts": {
    "test": "mocha ./__tests__/payment.test.js"
  },
  "dependencies": {
    "logging": "file:../logging"
  }
  • package.json应该如图片所示
    Play with Lerna to help you easily build Monorepo
  • 替换支付文件的内容。services/payment/lib/payment.js

const loggingService = require('logging');
const paymentService = {
  makePayment: (amount) => {
    loggingService.info('Payment processing initiated');
    // Implement payment logic here
    loggingService.info('Payment processed successfully');
    return `Payment of ${amount} processed successfully`;
  },
};
module.exports = paymentService;
  • makePayment支付服务功能测试用例。
  • 替换测试文件的内容services/payment/__tests__/payment.test.js

const chai = require('chai');
const paymentService = require('../lib/payment'); // Import the payment service
const expect = chai.expect;
describe('Payment Service', () => {
  it('should make a payment successfully', () => {
    const paymentResult = paymentService.makePayment(100);
    expect(paymentResult).to.equal('Payment of 100 processed successfully');
  });
});
  • 是时候使用 lerna 运行测试了npx lerna run test --scope="payment"使用 lerna 运行测试
  • 我们已经完成了支付服务的实施。现在,让我们继续创建后端服务。

第 6 步:设置后端服务器

我们将使用基本的 GET API 配置服务器,该 API 利用记录器和支付服务。此设置将有助于付款和记录相应的活动。

  • 安装 Express 服务器并实现使用这两种服务的功能。
//from root
cd packages/back-end
npm install express
  • 替换日志功能文件的内容packages/back-end/lib/back-end.js
  • 我们想在服务器中使用支付和日志服务,所以让我们在package.jsonof的依赖项中添加以下代码片段packages/back-end 
"logging": "file:../services/logging",
"payment": "file:../services/payment"
  • 替换脚本块来运行服务器并进行测试,如下所示:
"scripts": {
    "start": "node ./lib/back-end.js",
    "test": "mocha ./__tests__/back-end.test.js --exit"
}
  • package.json应该如所附图片所示

Play with Lerna to help you easily build Monorepo

  • 现在,通过执行更新依赖项npm update
  • 将 的内容替换packages/back-end/lib/back-end.js为以下代码:
    • 我们将创建一个带有get / API端口的服务器3000,并使用日志记录和支付服务。 

const express = require('express');
const loggingService = require('logging');
const paymentService = require('payment');
const app = express();
app.get('/', (req, res) => {
  // Use of logging service
  loggingService.info('Backend server received a request');
  
  // Use the payment service
  const paymentResult = paymentService.makePayment(100);
  loggingService.info('Payment result:', paymentResult);
  res.send('Backend Server: Running!');
});
app.listen(3000, () => {
  console.log('Backend server is running on port 3000');
});
  • 安装chai-http以对目录上的 API 进行单元测试packages/back-end
    •  npm i chai-http --save-dev 
  • 替换测试文件的内容,我们将在其中测试 API 是否按预期工作。

const chai = require('chai');
const chaiHttp = require('chai-http');
const app = require('../lib/back-end'); // Import the Express app
// using request server as chaiHttp;
chai.use(chaiHttp);
const expect = chai.expect;
describe('Backend Server', () => {
  it('should log a request and process payment', (done) => {
    chai.request(app)
      .get('/')
      .end((err, res) => {
        expect(res).to.have.status(200);
        expect(res.text).to.equal('Backend Server: Running!');
        done();
      });
  });
});
  • 恭喜!这样就完成了 monorepo 中三个微服务的简洁有效的实现。 

第 7 步:运行应用程序

  • 伟大的!现在,让我们启动服务器并观察所有服务如何组合在一起并工作。
  • lerna run start在根文件夹中执行。这将在端口 3000 上启动服务器。打开浏览器并导航至localhost:3000/您将观察到输出“后端服务器:正在运行!” 显示在浏览器中。
  • 检查终端中的日志,您将遇到类似于图中所示的Play with Lerna to help you easily build Monorepo。

检查终端中的日志,您将遇到类似于图中所示的Play with Lerna to help you easily build Monorepo。

  • Execute lerna run test, this will run all tests in all microservices because all microservicestestThere are commands in the script.

执行 lerna run test,这将运行所有微服务中的所有测试,因为所有微服务的脚本中都有 test 命令。

Conclusion

Create a backend server, payment service and logs The monorepo of logging services highlights the benefits of a unified development approach. This setup promotes efficient code management and sharing by consolidating related components into a single repository.

Integrating logging services into payment services and backend servers demonstrates the power of code reusability and consistent logging practices across services.

#Adopting a monorepo architecture will lead to an organized and collaborative development environment. Modularization simplifies development, improves efficiency and long-term maintenance. It provides a solid foundation for complex applications, with transparent communication, code reusability and effective testing.

The above is the detailed content of Play with Lerna to help you easily build Monorepo. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn