Зачем использовать монорепо
Проще говоря, поместите несколько проектов или файлов пакетов в репозиторий git для управления. в настоящий момент Более широко используетсяyarn+lerna
реализовано каким-то образомmonorepo
управление。 простойmonorepo
Структура каталогов аналогична этой:
js
скопируйте код
├── пакеты
| ├── упаковка1
| | ├── package.json
| ├── упаковка2
| | ├── package.json
├── package.json
├── lerna.json
Причина подачи заявленияmonorepo
,В основном для решения следующих задач:
О том, почему все больше и больше людей рекомендуют использовать pnpm,Можно обратиться кЭта статья[1] Вот краткий список преимуществ pnpm перед Yarn/npm:
yarn/npm
сложный алгоритм выравнивания,и обновлять только измененные файлы)node_modules
проходитьhard-link
способ ссылки на настоящий Установитьадрес)в настоящий момент,использоватьnpm/yarn
Инсталляционный пакетдаплоская структура(дода Вложенная структура, изменена на плоскую после npm3 структура)
плоская структура Сразуда Установитьсумка,Так Пакеты, от которых зависит этот пакет, будут Установить Перейдите в каталог на том же уровне, что и этот пакет.。например Установитьодинexpress
Сумка,Открыть каталогnode_modules
Вы обнаружите, что помимоexpress
снаружи,Есть много других пакетов. Как показано на рисунке:
image.png
Вложенная структура Сразудасумкаизполагаться Сумкавстреча Установитьв этом Сумкадокумент Внизизnode_modules
Вниз,И зависимые зависимости будут Установитьприезжатьполагаться Сумкадокументизnode_modules
Вниз。и так далее。Как показано ниже:
js
копировать код
node_modules
├─ фу
├─ node_modules
├─ бар
├─ index.js
└─ package.json
├─ index.js
└─ package.json
Проблема с Вложенной структурой заключается в следующем:
И у плоской структуры тоже есть проблемы:
Сейчас,насиспользоватьpnpm
Приходить Установитьexpress
,затем откройтеnode_modules
:
image.png
На картинке выше вы можете найти:
node_modules
Внизтолькоexpress
сумка,И это мягко связано с другими местами.pnpm
Сумкауправлятьиз Конфигурацияинформация。нравиться Внизкартина:image.png
можно увидеть Фактический pnpm, на который указывает каталог .pnpm. путь к магазину、Версия пакета pnpmждатьинформация
image.png
После наблюдения мы обнаружили, что конструкция установки полностью соответствует официальной схеме:
Из официальных фотографий мы можем узнать:
bar
Сумкачас,корень Оглавление Вниз Только Сумка Содержит Установитьиз Сумкаbar
node_modules
Оглавление Внизизbar
Сумкавстречамягкая ссылка
приезжать.pnpm/bar/node_modules/bar@*.*.*
мягкая ссылка
приезжатьздесьжесткая ссылка
приезжать.pnpm store
серединаМягкие ссылки можно понимать как ярлыки. Он имеет ту же функцию, что и ярлык в Windows. жесткая ссылкаравный
cp -p
добавлятьСинхронные обновления
。то есть размер файлаи Создается одновременно с исходным файлом.,Модификация исходного файла,жесткая файл ссылки, синхронный обновления。приложение:Это может предотвратить случайное удаление исходных файлов другими людьми.
Мягкие ссылки решают проблему использования дискового пространства, а жесткие ссылки решают проблемы синхронизации обновлений и унифицированного управления пакетами. кромеодинумныйиз设计Сразуда:Поместите установочный пакет и пакеты зависимостей в один и тот же каталог, т. е. .pnpm/dependent packages/node_modules.。Эта конструкция также предотвращает **Незаконный доступ в зависимые комнаты
**,в соответствии сПравила разрешения пути к модулю узла[2]Это может быть известно,Не здесь Инсталляционный Зависимые пакеты на том же уровне, что и пакет, недоступны, то есть доступен только Инсталляционный. пакетно-зависимые пакеты.
Теперь не должно быть причин не обновить инструменты управления пакетами!
нравиться果你кромеиспользоватьnpm/yarn
сцена,Так,Могу порекомендоватьиспользовать **ni**[3] Этот инструмент может помочь вам автоматически определить инструмент управления пакетами, используемый в проекте. Вам нужно всего лишь назвать его в одной строке.
например: выполнить командуni
Установитьполагаться Сумка,нравиться果当前проект Сумка Содержитpnpm-lock.yaml
,Таквстречаиспользовать pnpm install
осуществлять Установить Заказ,В противном случае судитеданет Сумка Содержитpackage-lock.json
/yarn.lock
/bun.lockb
,Чтобы определить, какой инструмент управления пакетами использовать для выполнения команды Установить.
Новый Оглавлениеpnpm-workspace-demo
,осуществлятьnpm init / pnpm init
инициализацияпроект,генерировать package.json
Чтобы уменьшитьnode
илиpnpm
из Версияизразницаи Возникает ошибка среды разработки,мыpackage.jsonсерединаувеличиватьдобавлятьengines
Поле Приходить限制Версия。
js
копироватькод
{ "engines": {
"node": ">=16",
"pnpm": ">=7"
}
}
Чтобы предотвратить публикацию нашего корневого каталога как пакета, нам нужно ввести следующие настройки в package.jsonдобавлять:
js
копироватькод
{ "private": true
}
pnpm
Поддержи себяmonorepo,Без лишнего пакет, это здорово! нодакаждыйmonorepoизкорень Оглавление Вниздолжен Сумка Содержитpnpm-workspace.yaml
документ。 Оглавление Вниз Новыйpnpm-workspace.yaml
документ,Содержание следующее:
ямл
копировать код
пакеты:
# все пакеты в прямых подкаталогах packages/
- 'пакеты/*'
Некоторые зависимые пакеты требуют глобальной установки.,То есть Установить в корневой каталог,напримернас常用изкомпилироватьполагаться Сумкаrollup、execa、chalk、enquirer、fs-extra、minimist、npm-run-all、typescript
ждать Выполните следующую команду:
-w
Указывает установку в корневом каталоге рабочей области вместо текущего каталога.
sql
копироватькод
pnpm add rollup chalk minimist npm-run-all typescript -Dw
и Установить Заказpnpm add pkgname
противоположныйудалитьполагаться Сумкаpnpm rm/remove pkgname
илиpnpm un/uninstall pkgname
Помимо входа в саб Сумка Оглавлениепрямой Установитьpnpm add pkgname
снаружи,Достаточно хорошопроходить Проходитьпараметры фильтра --filter
или-F
обозначение Заказ Объем。格式нравиться Вниз:
pnpm --filter/-F имя каталога конкретного пакета/имя пакета/имя обычного пакета/команда каталога соответствия
например: я создал два новых подпакета в каталоге пакетов.,соответственноtools
иmini-cli
,если я хочу бытьmin-cli
Сумка Вниз Установитьreact
,Так,Мы можем выполнить следующую команду:
js
копироватькод
pnpm --filter mini-cli add react
Больше фильтрации Конфигурация Можно ссылаться:www.pnpm.cn/filtering[4]
Выберите здесьrollup[5]как Пакетинструмент,из-за его ПакетиметьМеньший размериtree-shakingХарактеристики,Можно сказать, что это лучший выбор в качестве библиотеки инструментов.
Сначала установите некоторые часто используемые плагины для упаковки:
sql
копироватькод
pnpm add rollup-plugin-typescript2 @rollup/plugin-json @rollup/plugin-terser -Dw
Оглавление Вниз Новыйrollupиз Конфигурациядокументrollup.config.mjs
,Принимая во внимание ситуацию, когда несколько посылок обрабатываются одновременно,сдержанныйinput
дляпроходитьrollup
проходить Параметры, переданные в。используется здесьprocess.env.TARGET
表示другой Сумка Оглавление。
Ниже приведена базовая конфигурация для компиляции, которая в основном включает в себя:
format
тип,Предопределенный вывод Конфигурация,Удобен для дальнейшего использованияrollup
Динамически передается Сумкаимяполучатьinput
rollup
Конфигурацияэкспортировать как массив,Каждый видformat
Есть группа Конфигурация,каждый Сумка Возможно, вам придется экспортировать несколькоformat
js
копировать код
импортировать { createRequire } из «модуля»
импортировать { fileURLToPath } из 'url'
импортировать путь из «path»
импортировать json из @rollup/plugin-json
импортировать терсер из @rollup/plugin-terser
const require = createRequire(import.meta.url)
const __dirname = fileURLToPath(новый URL('.', import.meta.url))
const packagesDir = path.resolve(__dirname, 'packages')
const packageDir = path.resolve(packagesDir, process.env.TARGET)
const resolve = p => path.resolve(packageDir, p)
const pkg = require(resolve(`package.json`))
const packageOptions = pkg.buildOptions || {}
const name = packageOptions.filename || path.basename(packageDir)
// Определите элемент компилирования, соответствующий типу вывода.
const outputConfigs = {
'esm-bundler': {
file: resolve(`dist/${name}.esm-bundler.js`),
format: `es`
},
'esm-browser': {
file: resolve(`dist/${name}.esm-browser.js`),
format: `es`
},
cjs: {
file: resolve(`dist/${name}.cjs.js`),
format: `cjs`
},
global: {
name: name,
file: resolve(`dist/${name}.global.js`),
format: `iife`
}
}
const packageFormats = ['esm-bundler', 'cjs']
const packageConfigs = packageFormats.map(format => createConfig(format, outputConfigs[format]))
export default packageConfigs
function createConfig(format, output, plugins = []) {
// Выводить ли файл декларации
const shouldEmitDeclarations = !!pkg.types
const minifyPlugin = format === 'global' && format === 'esm-browser' ? [terser()] : []
return {
input: resolve('src/index.ts'),
// Global and Browser ESM builds inlines everything so that they can be
// used alone.
external: [
...['path', 'fs', 'os', 'http'],
...Object.keys(pkg.dependencies||{}),
...Object.keys(pkg.peerDependencies || {}),
...Object.keys(pkg.devDependencies||{}),
],
plugins: [
json({
namedExports: false
}),
...minifyPlugin,
...plugins
],
output,
onwarn: (msg, warn) => {
if (!/Circular/.test(msg)) {
warn(msg)
}
},
treeshake: {
moduleSideEffects: false
}
}
}
корень Оглавление Вниз Новыйscripts
Оглавление,и создавать новыеbuild.js
используется для Пакеткомпилироватьосуществлять。длячтобы достичь большего Сумка同час进行Пакетдействовать,Сначала нам нужно получитьpackages
Внизиз Все дети Сумка
js
копироватькод
const fs = require('fs')
const {rm} = require('fs/promises')
const path = require('path')
const allTargets = (fs.readdirSync('packages').filter(f => {
// Отфильтровать файлы, не относящиеся к каталогам
if (!fs.statSync(`packages/${f}`).isDirectory()) {
return false
}
const pkg = require(`../packages/${f}/package.json`)
// Отфильтровать приватные пакеты и пакеты без компилировать Конфигурация
if (pkg.private && !pkg.buildOptions) {
return false
}
return true
}))
После получения субпакета можно выполнить операцию сборки. Здесь используем. execa[6] Приходитьосуществлятьrollup
Заказ。коднравиться Вниз:
js
копироватькод
const build = async function (target) {
const pkgDir = path.resolve(`packages/${target}`)
const pkg = require(`${pkgDir}/package.json`)
// Удалите ранее созданные продукты перед компиляцией.
await rm(`${pkgDir}/dist`,{ recursive: true, force: true })
// -c Относится к использованию файлов конфигурации. По умолчанию —rollup.config.js.
// --environment Передача переменных среды в файл конфигурации. Файл конфигурации получается через процесс.env.
await execa(
'rollup',
[
'-c',
'--environment',
[
`TARGET:${target}`
]
.filter(Boolean)
.join(',')
],
{ stdio: 'inherit' }
)
}
При синхронизации нескольких пакетов компилировать,Чтобы не влиять на производительность компилировать,Нам нужно контролировать количество параллелизма,Здесь мы предварительно определяем количество параллелизма как4
,Вход в компилировать выглядит так:
js
копироватькод
const targets = allTargets // Подпакет, полученный выше
const maxConcurrency = 4 // Количество одновременных компиляций
const buildAll = async function () {
const ret = []
const executing = []
for (const item of targets) {
// Последовательное выполнение операций build() над подпакетами
const p = Promise.resolve().then(() => build(item))
ret.push(p)
if (maxConcurrency <= targets.length) {
const e = p.then(() => executing.splice(executing.indexOf(e), 1))
executing.push(e)
if (executing.length >= maxConcurrency) {
await Promise.race(executing)
}
}
}
return Promise.all(ret)
}
// Выполнить действие скомпилировать
построить Все()
Наконец, мы добавляем скрипт в package.json в корневом каталоге.
json
копироватькод
{ "scripts": {
"build": "node scripts/build.js"
},
}
Сейчас Мы просто бежимpnpm run build
Прямо сейчас Можно завершить все Сумкаизкомпилировать Работа。(Примечание:Еще нужно добавитьдобавлятьпозжеизTS
Возможность подключения Работа)。
в это время,существоватькаждый Сумка Вниз面встречагенерироватьdist
Оглавление,потому чтодлянаспо умолчаниюиздаesm-bundler
иcjs
Два видаformat,Итак, файлы, созданные в каталоге, выглядят следующим образом
image.png
Итак, что нам делать, если мы хотим настроить формат создаваемого файла?
Самый простой способ — выполнить Конфигурацию в package.json.,Когда мы находимся в Пакете, мы можем просто взять Конфигурацию здесь.,напримермы Сумкаtools
里做нравиться Вниз Конфигурация:
json
копироватькод
{"buildOptions": {
"name": "tools", // имя глобальных переменных при определении глобальных
"filename": "tools", // Определите имя выходного файла Например, tools.esm-browser.js. Сгенерированный файл: [имя файла].[формат].js.
"formats": [ // Определить вывод
"esm-bundler",
"esm-browser",
"cjs",
"global"
]
},
}
здесьнас Просто нужно быть внутри База Конфигурациядокументrollup.config.mjs
внести некоторые изменения Прямо сейчас Может:
js
копироватькод
const defaultFormats = ['esm-bundler', 'cjs']
const packageFormats = packageOptions.formats || defaultFormats // Расставьте приоритеты в использовании пользовательских форматов в каждом пакете.
const packageConfigs = packageFormats.map(format => createConfig(format, outputConfigs[format]))
например Я хочу побыть одна Пакетtools
иобозначение输出издокументдляglobal
тип,Вероятно, это можно записать так:
ардуино
копировать доступно
pnpm запустить инструменты сборки --глобальные форматы
На самом деле это всего лишь вопрос подключения параметров командной строки к сценарию упаковки. Условно его можно разделить на следующие этапы:
js
копировать доступно
const args = require('минимист')(process.argv.slice(2))
константные цели = args._.length? args._ : allTargets
константные форматы = args.formats || args.f
rollup
изпеременные средысередина,Исправлятьexeca
частьjs
копироватькод
await execa(
'rollup',
[
'-c',
'--environment', // Передача переменных среды Файл конфигурации доступен через proccess.env.
[
`TARGET:${target}`,
formats ? `FORMATS:${formats}` : `` // Продолжать передавать параметры
]
.filter(Boolean)
.join(',')
],
{ stdio: 'inherit' }
)
rollup.config.mjs
серединаполучатьпеременные средыиприложениеjs
копироватькод
const defaultFormats = ['esm-bundler', 'cjs']
const inlineFormats = process.env.FORMATS && process.env.FORMATS.split(',') // Получите переменную средыprocess.env.FORMATS, переданную при объединении.
const packageFormats = inlineFormats || packageOptions.formats || defaultFormats
Для проектов, написанных на ts, обычно также выпускаются файлы деклараций.,Просто нужно быть внутриpackage.json
добавлятьдобавлятьtypes
Поле Приходитьобозначениезаявлениедокумент Прямо сейчас Может。Так,Фактически мы можем использовать это поле, чтобы определить, создавать ли файл декларации при выполнении пакета. для свертывания,Используем его плагинrollup-plugin-typescript2
Приходитьанализироватьtsдокументигенерироватьзаявлениедокумент。 Добавьте следующую конфигурацию вrollup.config.mjs:
js
копироватькод
// Выводить ли файл декларации Получите поле типа package.json каждого пакета.
const shouldEmitDeclarations = !!pkg.types
const tsPlugin = ts({
tsconfig: path.resolve(__dirname, 'tsconfig.json'),
tsconfigOverride: {
compilerOptions: {
target: format === 'cjs' ? 'es2019' : 'es2015',
sourceMap: true,
declaration: shouldEmitDeclarations,
declarationMap: shouldEmitDeclarations
}
}
})
return {
...
plugins: [
json({
namedExports: false
}),
tsPlugin,
...minifyPlugin,
...plugins
],
}
После запуска вышеуказанной конфигурации файлы объявлений для всех пакетов будут созданы под каждым пакетом, как показано на рисунке:
image.png
Это не то, что мы хотим, мы ожидаем, что в каталоге dist будет создан только один .d.tsдокумент Сразу好了,использоватьрост Приходитьтакжеудобный。Здесь мы используемapi-extractor[8]Приходитьсделай это Работа。этотинструмент Есть три основных Функция,Мы хотим использовать красную рамку функции.,Как показано на рисунке:
Ключевые этапы реализации:
api-extractor.json
и ВоляdtsRollup
настраиватьдля开启api-extractor.json
и定义заявлениедокумент Входи Экспортировать элементы,Как показано ниже:json
копироватькод
{ "extends": "../../api-extractor.json",
"mainEntryPointFilePath": "./dist/packages/<unscopedPackageName>/src/index.d.ts", // Файл декларации, созданный путем объединения
"dtsRollup": {
"publicTrimmedFilePath": "./dist/<unscopedPackageName>.d.ts" // Извлеките его как файл декларации в каталог dist.
}
}
API Extractor
действовать,Добавьте в метод сборки следующие операции:js
копироватькод
build(target) {
await execa('rollup')
// После выполнения объединения для создания файла декларации
// Выполняется, когда это поле определено в package.json.
if (pkg.types) {
console.log(
chalk.bold(chalk.yellow(`Rolling up type definitions for ${target}...`))
)
// Выполнить API Операция экстрактора Восстановить файл декларации
const { Extractor, ExtractorConfig } = require('@microsoft/api-extractor')
const extractorConfigPath = path.resolve(pkgDir, `api-extractor.json`)
const extractorConfig =
ExtractorConfig.loadFileAndPrepare(extractorConfigPath)
const extractorResult = Extractor.invoke(extractorConfig, {
localBuild: true,
showVerboseMessages: true
})
if (extractorResult.succeeded) {
console.log(`API Extractor completed successfully`);
process.exitCode = 0;
} else {
console.error(`API Extractor completed with ${extractorResult.errorCount} errors`
+ ` and ${extractorResult.warningCount} warnings`);
process.exitCode = 1;
}
// Удалите файл декларации, созданный ts.
await rm(`${pkgDir}/dist/packages`,{ recursive: true, force: true })
}
}
rollup
генерироватьиззаявлениедокументИтак, здесь весь процесс упаковки относительно завершен.
Для монорепозитория, реализованного в рабочей области pnpm, если вы хотите управлять версиями пакетов и публиковать их, вам необходимо использовать некоторые инструменты. Официально рекомендуются следующие инструменты:
насздесь主要学习一Внизchangesets
изиспользовать,Он имеет две основные функции:
дляmonorepo
проектиспользовать它встреча更добавлятьудобный,Конечно Сумкатакже Может以использовать。主要区别существовать Впроект Внизиметь Нетpnpm-workspace.yaml
,Если не указана мультипосылка,Таквстреча当作普通Сумка Процесс。 Итак, давайте рассмотрим конкретные шаги:
sql
копироватькод
pnpm add @changesets/cli -Dw
csharp
копировать код
инициализация набора изменений npx
этот Заказбудет внутрикорень Оглавление Внизгенерировать.changeset
документпапка,В папке находится файл конфигурации и файл readme. Сгенерированный файл конфигурации выглядит следующим образом:
json
копироватькод
{ "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false, // Отправлять ли изменения в связи с набором изменений и набором изменений Изменение файла, вызванное версией
"fixed": [], // Настройка набора общих версий пакета Пакеты в группе будут изменены до одной и той же версии синхронно, независимо от того, были ли они изменены или имеют ли они зависимости.
"linked": [], // Настройте набор пакетов, которые необходимо связать с версиями. Пакеты, имеющие зависимости или модификации, будут обновлены до одной и той же версии одновременно. Пакеты, которые не были изменены и не имеют зависимостей, не будут иметь изменений версий.
"access": "public", // Опубликовать как частный пакет/публичный пакет
"baseBranch": "main",
"updateInternalDependencies": "patch", // Убедитесь, что зависимые пакеты обновляются, а также единицы измерения для обновленных версий.
"ignore": [] // Игнорируемые пакеты, которые не нуждаются в публикации
}
关Вкаждый Конфигурацияэлементиз详细Содержит义参考:config.json[11] Вот несколько вещей, на которые следует обратить внимание:
access
по умолчаниюrestricted
выпускатьдля私иметь Сумка,Нужно изменить наpublic
общественный Сумка,В противном случае при публикации будет сообщено об ошибке.fixed
иlinked
изценитьдлядвумерный массив,Элемент представляет собой определенное имя пакета или соответствующее выражение.,нода Эти Сумкадолженсуществоватьpnpm-workspace.yaml
добавлятьдобавлять Проходитьбегатьnpx changeset
,Появится ряд вопросов подтверждения.,включать:
.changeset
ВнизгенерироватьодинMarkdown
документ,Содержимое этого файла представляет собой набор ответов на вопрос, заданный только что.,Вероятно, это выглядит так:ямл
копировать доступно
---
'@scope/mini-cli': основной
'@scope/tools': незначительное
---
обновить пакеты
—--
В середине находится список пакетов, которые необходимо обновить. И обновленная версия, соответствующая упаковке, внизу находится информация о модификации.
бегатьnpx changeset version
Эта команда сделает следующее
CHANGELOG.md
документ Заполните информацию об изменении, заполненную на предыдущем шаге.Markdown
документ,Гарантированно используется только один разПосле этого рекомендуется,pulish
До Воля改动合иприезжатьглавная ветка
Об этом нечего сказать,прямойвыполнить командуnpx changeset publish
Прямо сейчас Может
Чтобы обеспечить выпуск функции, добавьте следующий скрипт для контроллера:
json
копироватькод
{ "scripts": {
"release": "run-s build releaseOnly",
"releaseOnly": "changeset publish"
}
}
Набор изменений обеспечивает режим предварительной версии с тегами. При использовании этого режима необходимо обратить внимание:
pre enter/exit
Входитьили Выход довыпускатьмодель,Все команды обычного режима могут быть выполнены в этом режиме.,напримерversion
、publish
-<tag>.<num>
окончание。tag
дляpreЗаказловитьизtagимя,num
каждый развыпускать都встреча递увеличивать Начать с 0Полный предварительный пакет, вероятно, будет выполнять следующие операции:
changeset pre enter <tag>
Войти в предварительный режимchangeset
Подтвердите информацию о версии пакета выпускаchangeset version
генерироватьпредварительная версия Числоиchangelogchangeset publish
выпускатьпредварительная версияздесьизtag
Может以данас常用из Несколькотипформа:
имя | Функция |
---|---|
alpha | Это внутренняя тестовая версия, которая обычно не выпускается для внешнего мира. Она содержит множество ошибок и обычно используется только тестировщиками. |
beta | Также бета-версия,Версия на этом этапе всегда будет включать новые обновления. Запущен после альфа-версии |
rc | (Release Candidate) Кандидат на освобождение. Версия RC больше не будет добавлять новые дополнения, она в основном ориентирована на отладку. |
Каждый раз, когда вам нужно обновить версию, просто выполните это снова, начиная с шага 2.
Если вам нужно выпустить официальную версию,Выход довыпускатьмодельchangeset pre exit
,Затем переключитесь на основную ветку для работы.
Здесь мы в основном проверяем стиль кода. проверятьинструментдляeslint
(В основном для js, ts и других языковых файлов js) и prettier
(js、css и другие типы файлов)
Вспомогательные инструменты есть
husky
Конфигурация следующая:
json
копироватькод
{ "simple-git-hooks": {
"pre-commit": "pnpm lint-staged" // Операция перед подачей заявки на регистрацию т. е. проверка формата кода
},
"lint-staged": {
"*.{js,json}": [
"prettier --write"
],
"*.ts?(x)": [
"eslint",
"prettier --parser=typescript --write"
]
},
}
дляфункция перехватаиз Примечаниекнигапроходитьsimple-git-hooks
Приходитьвыполнить,Регистрация перехватчика запускается после установки зависимостей проекта. Вы можете добавить следующий скрипт. (Если операция перехвата изменится,Вам необходимо повторно выполнить операцию «Установить зависимости» для обновления)
json
копироватькод
"scripts": {
"postinstall": "simple-git-hooks",
},
Здесь в основном используются следующие три инструмента:
Commitizen
копироватькод
npm install -g commitizen
Commitizen
изадаптер,Определите характеристики для использования,здесьиспользоватьcz-conventional-changelog[19],Вы также можете выбрать другие адаптерыкопироватькод
npm install -g cz-conventional-changelog
json
копироватькод
// пользователи Mac
echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc
этотчас候выполнить командуgit cz
встреча自动Входить交互式генерироватьcommit запрос сообщения, как показано на рисунке:
2. Как настроить Коммитлинт
нас Может以проходить Конфигурацияизgit cz
Заказ Стандартизироватьизкодпредставлять на рассмотрение,Так,нравиться果другой同事依然использоватьиздаgit commit
Приходитьпредставлять на рассмотрениекодизразговаривать,Так,представлять на рассмотрениеинформация Сразувстреча比较乱。В это время необходимоcommit mesaage
Проверено,нравиться果不проходитьносередина断представлять на рассмотрение。этотпроверять Сразу Может以проходитьCommitlint
Приходить Заканчивать。
По каким правилам проверять,Для проверки нам нужен отдельный пакет «Установить правила проверки».,например@commitlint/config-conventional[20]
нравиться果想定义自己из规но Можно обратиться кcz-customizable[21]
sql
копироватькод
pnpm add @commitlint/config-conventional @commitlint/cli -Dw
commitlint
Конфигурация,Укажите пакет правилarduino
копироватькод
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
pnpm install
обновить крючок)json
копироватькод
"simple-git-hooks": {
"commit-msg": "npx --no -- commitlint --edit ${1}"
},
Если вы отправите еще раз в это время, сообщение о фиксации будет проверено. Если оно не соответствует спецификациям, появится следующее приглашение:
image.png
Рекомендовано в прошлом
Онлайн-ОШИБКА заставляет задуматься: следует ли сохранить ^~ в package.json?
Оптимизация производительности упаковки Vite и заполнение ям