Monorepos introduction

Monorepos simply means that there are several independent submodules under a project. These submodules can be run, packaged, and distributed independently, but they are managed under the same Git repository, and they may depend on each other.

The benefit of managing projects in this way is that it is easy to unify the submodules while minimizing the coupling between modules.

Many large projects use this management style, such as Babel, React, Vue, etc.

Take a look at the create-react-app directory structure on Github

Create-react-app, react-dev-utils, react-scripts, etc. These modules can all be published independently to NPM

They are also maintained in the same Git repository, so create-React-app is a typical monorepos managed project.

Preparations before creation

To create a monorepos project, you need to use lerna, the multi-package management tool, and Yarn’s WrokSpaces feature, so you need to install both tools globally.

And then I’m going to create a project folder, whatever I want to call it, lerna-test

Start to create

Initialize the

Run the following command under lerna-test

lerna init
Copy the code

After success, the directory structure is as follows

Modify the configuration

  • Modify lerna. Json

    Add npmClient as follows

    {
      "packages": ["packages/*"]."npmClient": "yarn"."version": "0.0.0"
    }
    Copy the code
  • Modify the package. The json

    Add the workspaces configuration as follows

    {
      "name": "root"."private": true."workspaces": [
        "packages/*"]."devDependencies": {
        "lerna": "^ 3.20.2"}}Copy the code

Initialize the submodule

To illustrate, I initialized a normal project with Lerna and a React project with create-react-app

First go to the/Packages folder and create the following two subprojects

  • Creating a normal project

    lerna create aaawu
    Copy the code

    Aaawu is a program that can be arbitrarily named

  • Create the React project

    yarn create react-app test-react
    Copy the code

    The name of the test-React project is optional

With both subprojects created, the directory structure should look like this

Adding dependencies

In a normal Monorepos project, it is likely that each module will depend on each other. Next, we assume that test-ract needs to rely on AAAWU.

Open /packages/test-react/package.json and add a line of dependencies under Dependencies

"aaawu": "^ 0.1.0 from"
Copy the code

0.1.0 from the version number corresponding to the/packages/aaawu/package. The json version

Run the following command to view the dependency of each module

yarn workspaces info
Copy the code

The results are as follows

Yarn machine-specific v1.12.1 {"aaawu": {
    "location": "packages/aaawu"."workspaceDependencies": []."mismatchedWorkspaceDependencies": []},"test-react": {
    "location": "packages/test-react"."workspaceDependencies": [
      "aaawu"]."mismatchedWorkspaceDependencies": []}}Copy the code

You can already see that the dependency was added successfully.

associated

Now that you have the test-React dependencies with AAAWU, how do you make the test-React project import aaAWU code?

Unlike normal YARN Add ×××, local development needs to reference local AAAWU instead of online NPM projects.

This is where yarn’s workspaces come into play, which automatically manages all dependencies under the package specified by the workspaces field in /package.json. Because what we configured before was

"workspaces": [
    "packages/*"
  ]
Copy the code

So, it directly resolves dependencies for all subpackages under the Packages file.

Command line execution

yarn
Copy the code

All dependencies required by test-React and AAAWu are installed in node_modules in the root directory (except for packages that cannot be unified due to version conflicts). Packages that cannot be unified due to version conflicts will still be installed in node_modules under each module.

Check node_modules in the root directory

See that AAAWu is different from the others, with an arrow next to it. This does point to local /packages/ AAAWu, which is a mirror, meaning that any code changes in/Packages/AAAWu will also change.

Run the project

Now that the dependencies are installed, you can run the project directly

Switch to the/Packages /test-ract directory directly

npm start
Copy the code

Test-react will run properly

Modify the code

We want to test methods imported from AAAWU in the test-React project. Make minimal changes directly to the original code, and try it out

  • Modify the/packages/aaawu/lib/aaawu.js
"use strict";

module.exports = aaawu;

function aaawu() {
  // TODO
  return "this is aaawu";
}

Copy the code
  • Modify the/packages/test-react/src/App.js
import React from "react";
import logo from "./logo.svg";
import A from "aaawu";
import "./App.css";

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          {A()}
        </a>
      </header>
    </div>
  );
}
export default App;
Copy the code

Without refreshing the page, you can see that the content is displayed correctly on the page

Above, the monorepos project whose submodules are interdependent has been created successfully and can run successfully