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
- Create a project directory
mkdir vue3-monorepo && cd vue3-monorepo
yarn init -y
mkdir packages && cd packages
mkdir reactivity
mkdir shared
Copy the code
- Modify the
package.json
{" name ":" vue3 - monorepo ", "version" : "1.0.0", "main" : "index. Js", "license" : "MIT" + "private" : true, + "workspaces":[ + "packages/*" + ] }Copy the code
- init reactivity shared
cd reactivity && yarn init -y
cd shared && yarn init -y
Copy the code
- create
reactivity
shared
The directory where the
vue3-monorepo
|---package.json
---packages
---reactivity
| | package.json
| |
+ | ---src
+ | index.ts
---shared
| package.json
+ ---src
+ index.ts
Copy the code
- to
reactivity
shared
Entry file ofindex.ts
Add 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
- 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
- Initialize the
typescript
configuration
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
- Modify the
reactivity
shared
In the directorypackage.json
Configure 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
- 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
- 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
- create
rollup
The 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
- Perform a packaged build
Yarn Run Dev # Build the specified module separatelyCopy the code