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