What is Monorepo?

Monorepo is a way of managing project code by managing multiple modules/packages in a repository

Advantages:

  • A repository can maintain multiple modules at the same time without splitting multiple repositories
  • Convenient version management and dependency management, modules reference each other, easy to call

Disadvantages:

  • Because multiple modules/packages coexist, the warehouse volume can be large

Copy the code structure of Vue3 and write a set by hand

Build the project structure

  1. Create a project directory
mkdir vue3-monorepo && cd vue3-monorepo
yarn init -y
​
mkdir packages && cd packages
​
mkdir reactivity
mkdir shared
Copy the code
  1. Modify thepackage.json
{" name ":" vue3 - monorepo ", "version" : "1.0.0", "main" : "index. Js", "license" : "MIT" + "private" : true, + "workspaces":[ + "packages/*" + ] }Copy the code
  1. init reactivity shared
cd reactivity && yarn init -y
cd shared && yarn init -y
Copy the code
  1. createreactivity sharedThe directory where the
vue3-monorepo
|---package.json
---packages
     ---reactivity
     |   |   package.json
     |   |   
+    |   ---src
+    |           index.ts           
     ---shared
         |   package.json
+        ---src
+                index.ts
Copy the code
  1. toreactivity sharedEntry file ofindex.tsAdd point code
// reactivity/src/index.ts
+ const Reactivity = {}
+ export { Reactivity }
Copy the code
// shared/src/index.ts
+ const Shared = {}
+ export { Shared }
Copy the code

Build the Build environment

  1. Install dependencies
The package name describe
typescript Support for ts
rollup Packaging tools
rollup-plugin-typescript2 Bridge between Rollup and TS
@rollup/plugin-node-resolve Parse node’s third-party modules
@rollup/plugin-json Support for importing JSON files
execa Start child process
# -- ignore-workflow-root-check or -w Allows installation of dependencies yarn add typescript rollup rollup-plugin-typescript2 in the root directory @rollup/plugin-node-resolve @rollup/plugin-json execa --ignore-workspace-root-checkCopy the code
  1. Initialize thetypescriptconfiguration
We already have typescript installed in the root directory (vue3-monorepo), so we have TSC in the node_modules/.bin directory of the project. Json file NPX TSC --initCopy the code
vue3-monorepo
  |---node_modules
  |---packages
  |---package.json
+ ---tsconfig.json
Copy the code
// tsconfig.json

{
"target": "ESNext"."module": "ESNext"."baseUrl": ". /"."moduleResolution": "node"."paths": {
      "@vue/*": ["packages/*/src"]}}Copy the code
  1. Modify thereactivity sharedIn the directorypackage.jsonConfigure module/package names and packaging options
# reactivity/package.json {+ "name": "@vue/reactivity", "version": "1.0.0", "main": "index.js", "license": "MIT", + "module": "dist/reactivity.esm-bundler.js", // ESModule entry + "buildOptions": {// Custom field used to build configuration + "name": "VueReactivity", + "formats": [ + "esm-bundler", + "cjs", + "global" + ] + } }Copy the code
# Shared/package. Json {+ "name" : "@ vue/Shared", "version" : "1.0.0", "main" : "index. Js", "license" : "MIT" + "module" : "Dist /reactivity.esm-bundler.js", // ESModule entry + "buildOptions": {// Custom field used to build configuration + "name": "VueShared", + "formats": [ + "esm-bundler", + "cjs", + ] + } }Copy the code

After the modification is complete, run yarn install in the root directory, and check whether there is a @vue directory under node_modules, and there are two soft chains under reactivity shared. If not, refresh the file directory

  1. Increase the order
# vue3-monorepo/package.json {"name": "vue3-monorepo", "version": "1.0.0", "main": "index. "MIT", "private": true, "workspaces": [ "packages/*" ], + "scripts": { + "dev": "node scripts/dev.js", + "build": "node scripts/build.js" + }, "dependencies": {} }Copy the code
  1. Creating a script File
/ / vue3 - monorepo/scripts/build js / / wrapped packages directory of all package const fs = the require (' fs) / / the node file module const execa = Require ('execa') // start child thread // read packages directory, Const targets = fs.readDirSync ('packages').filter(f => fs.statsync ('packages /${f} ').isDirectory()) async function build(targets) { await execa('rollup', ['-c', '--environment', `TARGET:${targets}`], { stdio: 'inherit'})} And execute build function runParallel(targets, iteratorFn) { const res = [] for (const iterator of targets) { const p = iteratorFn(iterator) res.push(p) } return Promise.all(res) } runParallel(targets, build)Copy the code
// vue3-monorepo/scripts/dev.js // only for a specific package const fs = require('fs') const execa = require('execa') const target = Async function build(target) {await execa('rollup', [' -CW ', '--environment', `TARGET:${target}`], { stdio: 'inherit' }) } build(target)Copy the code
  1. createrollupThe configuration file
// vue3-monorepo/rollup.config.js import path from 'path' import json from '@rollup/plugin-json' import ts from 'rollup-plugin-typescript2' import resolvePlugin from '@rollup/plugin-node-resolve' const packageName = Const packagesPath = path.resolve(__dirname, 'packages') // packages path const packageDirPath = path.resolve(packagesPath, PackageName) / / packages each packet path const resolve = p = > path. The resolve (packageDirPath, p) const packageJSON = require(resolve('package.json')) const outputConfig = { 'esm-bundler': { file: resolve(`dist/${packageName}.esm-bundler.js`), format: 'es' }, cjs: { file: resolve(`dist/${packageName}.cjs.js`), format: 'cjs' }, global: { file: resolve(`dist/${packageName}.global.js`), format: 'iife' } } const buildOptions = packageJSON.buildOptions function createConfig(format, output) { output.name = buildOptions.name output.sourcemap = buildOptions.sourcemap return { input: resolve(`src/index.ts`), output, plugins: [ json(), ts({ tsconfig: path.resolve(__dirname, 'tsconfig.json') }), resolvePlugin() ] } } export default buildOptions.formats.map(format => createConfig(format, outputConfig[format]))Copy the code
  1. Perform a packaged build
Yarn Run Dev # Build the specified module separatelyCopy the code