Позвольте вам понять и попрактиковаться в monorepo и pnpm, это абсолютно полезная информация! Не ложитесь спать допоздна, чтобы подвести итоги!
Позвольте вам понять и попрактиковаться в monorepo и pnpm, это абсолютно полезная информация! Не ложитесь спать допоздна, чтобы подвести итоги!

Зачем использовать монорепо

что такое монорепо

Проще говоря, поместите несколько проектов или файлов пакетов в репозиторий git для управления. в настоящий момент Более широко используетсяyarn+lernaреализовано каким-то образомmonorepoуправление。 простойmonorepoСтруктура каталогов аналогична этой:

Язык кода:javascript
копировать
js
скопируйте код
├── пакеты
|   ├── упаковка1
|   |   ├── package.json
|   ├── упаковка2
|   |   ├── package.json
├── package.json
├── lerna.json

Причина подачи заявленияmonorepo,В основном для решения следующих задач:

  • Проблемы повторного использования кода
  • Единый процесс разработки
  • Эффективно управлять несколькими проектами/пакетами

Использование пнпм

Зачем использовать pnpm

О том, почему все больше и больше людей рекомендуют использовать pnpm,Можно обратиться кЭта статья[1] Вот краткий список преимуществ pnpm перед Yarn/npm:

  1. Самая быстрая установка(неплоская структура упаковки,Нетyarn/npmсложный алгоритм выравнивания,и обновлять только измененные файлы)
  2. Экономьте место на диске (единый Инсталляционный пакетв место на диске,проектвnode_modulesпроходитьhard-linkспособ ссылки на настоящий Установитьадрес)

В чем разница между установочными пакетами pnpm?

в настоящий момент,использоватьnpm/yarnИнсталляционный пакетдаплоская структура(дода Вложенная структура, изменена на плоскую после npm3 структура)

плоская структура Сразуда Установитьсумка,Так Пакеты, от которых зависит этот пакет, будут Установить Перейдите в каталог на том же уровне, что и этот пакет.。например УстановитьодинexpressСумка,Открыть каталогnode_modulesВы обнаружите, что помимоexpressснаружи,Есть много других пакетов. Как показано на рисунке:

image.png

Вложенная структура Сразудасумкаизполагаться Сумкавстреча Установитьв этом Сумкадокумент Внизизnode_modulesВниз,И зависимые зависимости будут Установитьприезжатьполагаться Сумкадокументизnode_modulesВниз。и так далее。Как показано ниже:

Язык кода:javascript
копировать
js
копировать код
node_modules
├─ фу
  ├─ node_modules
     ├─ бар
       ├─ index.js
       └─ package.json
  ├─ index.js
  └─ package.json

Проблема с Вложенной структурой заключается в следующем:

  • Каталог файлов пакета может быть очень длинным.
  • Повторить установку пакета
  • Экземпляры одного и того же пакета не могут быть общими.

И у плоской структуры тоже есть проблемы:

  • Неопределенность структуры зависимости(другой Сумкаполагаться某个Сумкаиздругой Версия Окончательная версия «Установить» не определена) Версию «Установить» можно определить через файл блокировки.
  • Алгоритм выравнивания сложен и требует много времени.
  • Незаконный доступ к незадекларированной посылке

Сейчас,насиспользоватьpnpmПриходить Установитьexpress,затем откройтеnode_modules

image.png

На картинке выше вы можете найти:

  1. node_modulesВнизтолькоexpressсумка,И это мягко связано с другими местами.
  2. .modlues.yamlСумка Содержит некоторыеpnpmСумкауправлятьиз Конфигурацияинформация。нравиться Внизкартина:

image.png

можно увидеть Фактический pnpm, на который указывает каталог .pnpm. путь к магазинуВерсия пакета pnpmждатьинформация

  1. .pnpmОглавлениеможно увидеть Все зависимости Установить. Как показано ниже:

image.png

После наблюдения мы обнаружили, что конструкция установки полностью соответствует официальной схеме:

Из официальных фотографий мы можем узнать:

  • когда мы УстановитьbarСумкачас,корень Оглавление Вниз Только Сумка Содержит Установитьиз Сумкаbar
  • иnode_modulesОглавление ВнизизbarСумкавстречамягкая ссылкаприезжать.pnpm/bar/node_modules/bar@*.*.*
  • пакет зависимостей bar foo будет перемещен в корневой каталог .pnpm.,другой СумкаполагатьсяfooИногдамягкая ссылкаприезжатьздесь
  • иbarиfooдействительныйпроходитьжесткая ссылкаприезжать.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

1. Создайте новый склад и инициализируйте его.

Новый Оглавлениеpnpm-workspace-demo,осуществлятьnpm init / pnpm initинициализацияпроект,генерировать package.json

2. Укажите версию Node и pnpm, на которой работает проект.

Чтобы уменьшитьnodeилиpnpmиз Версияизразницаи Возникает ошибка среды разработки,мыpackage.jsonсерединаувеличиватьдобавлятьenginesПоле Приходить限制Версия。

Язык кода:javascript
копировать
js
копироватькод
{    "engines": {
        "node": ">=16",
        "pnpm": ">=7"
    }
}

3. Настройки безопасности

Чтобы предотвратить публикацию нашего корневого каталога как пакета, нам нужно ввести следующие настройки в package.jsonдобавлять:

Язык кода:javascript
копировать
js
копироватькод
{    "private": true
}

pnpmПоддержи себяmonorepo,Без лишнего пакет, это здорово! нодакаждыйmonorepoизкорень Оглавление Вниздолжен Сумка Содержитpnpm-workspace.yamlдокумент。 Оглавление Вниз Новыйpnpm-workspace.yamlдокумент,Содержание следующее:

Язык кода:javascript
копировать
ямл
копировать код
пакеты:  
# все пакеты в прямых подкаталогах packages/  
- 'пакеты/*'

4. Инсталляционный пакет

4.1 Установите пакеты глобальных зависимостей

Некоторые зависимые пакеты требуют глобальной установки.,То есть Установить в корневой каталог,напримернас常用изкомпилироватьполагаться Сумкаrollup、execa、chalk、enquirer、fs-extra、minimist、npm-run-all、typescriptждать Выполните следующую команду:

-w Указывает установку в корневом каталоге рабочей области вместо текущего каталога.

Язык кода:javascript
копировать
sql
копироватькод
pnpm add rollup chalk minimist npm-run-all typescript -Dw

и Установить Заказpnpm add pkgnameпротивоположныйудалитьполагаться Сумкаpnpm rm/remove pkgnameилиpnpm un/uninstall pkgname

4.2 Установка зависимостей подпакета

Помимо входа в саб Сумка Оглавлениепрямой Установитьpnpm add pkgnameснаружи,Достаточно хорошопроходить Проходитьпараметры фильтра --filterили-Fобозначение Заказ Объем。格式нравиться Вниз:

pnpm --filter/-F имя каталога конкретного пакета/имя пакета/имя обычного пакета/команда каталога соответствия

например: я создал два новых подпакета в каталоге пакетов.,соответственноtoolsиmini-cli,если я хочу бытьmin-cliСумка Вниз Установитьreact,Так,Мы можем выполнить следующую команду:

Язык кода:javascript
копировать
js
копироватькод
pnpm --filter mini-cli add react

Больше фильтрации Конфигурация Можно ссылаться:www.pnpm.cn/filtering[4]

4.3 Пакет и содержимое выходного пакета

Выберите здесьrollup[5]как Пакетинструмент,из-за его ПакетиметьМеньший размериtree-shakingХарактеристики,Можно сказать, что это лучший выбор в качестве библиотеки инструментов.

Сначала установите некоторые часто используемые плагины для упаковки:

Язык кода:javascript
копировать
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
Язык кода:javascript
копировать
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Внизиз Все дети Сумка

Язык кода:javascript
копировать
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Заказ。коднравиться Вниз:

Язык кода:javascript
копировать
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,Вход в компилировать выглядит так:

Язык кода:javascript
копировать
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 в корневом каталоге.

Язык кода:javascript
копировать
json
копироватькод
{    "scripts": {
    "build": "node scripts/build.js"
  },
}

Сейчас Мы просто бежимpnpm run buildПрямо сейчас Можно завершить все Сумкаизкомпилировать Работа。(Примечание:Еще нужно добавитьдобавлятьпозжеизTSВозможность подключения Работа)。

в это время,существоватькаждый Сумка Вниз面встречагенерироватьdistОглавление,потому чтодлянаспо умолчаниюиздаesm-bundlerиcjsДва видаformat,Итак, файлы, созданные в каталоге, выглядят следующим образом

image.png

Итак, что нам делать, если мы хотим настроить формат создаваемого файла?

Выходной формат пользовательской компиляции подпакета

Самый простой способ — выполнить Конфигурацию в package.json.,Когда мы находимся в Пакете, мы можем просто взять Конфигурацию здесь.,напримермы Сумкаtools里做нравиться Вниз Конфигурация:

Язык кода:javascript
копировать
json
копироватькод
{"buildOptions": {
    "name": "tools", // имя глобальных переменных при определении глобальных
    "filename": "tools", // Определите имя выходного файла Например, tools.esm-browser.js. Сгенерированный файл: [имя файла].[формат].js.
    "formats": [ // Определить вывод
      "esm-bundler",
      "esm-browser",
      "cjs",
      "global"
    ]
  },
}

здесьнас Просто нужно быть внутри База Конфигурациядокументrollup.config.mjsвнести некоторые изменения Прямо сейчас Может:

Язык кода:javascript
копировать
js
копироватькод
const defaultFormats = ['esm-bundler', 'cjs']
const packageFormats = packageOptions.formats || defaultFormats // Расставьте приоритеты в использовании пользовательских форматов в каждом пакете.
const packageConfigs = packageFormats.map(format => createConfig(format, outputConfigs[format]))
Пользовательская упаковка в командной строке и укажите ее формат.

например Я хочу побыть одна Пакетtoolsиобозначение输出издокументдляglobalтип,Вероятно, это можно записать так:

Язык кода:javascript
копировать
ардуино
копировать доступно
pnpm запустить инструменты сборки --глобальные форматы

На самом деле это всего лишь вопрос подключения параметров командной строки к сценарию упаковки. Условно его можно разделить на следующие этапы:

  1. использоватьminimist[7]получать Заказпараметры строки
Язык кода:javascript
копировать
js
копировать доступно
const args = require('минимист')(process.argv.slice(2))
константные цели = args._.length? args._ : allTargets
константные форматы = args.formats || args.f
  1. Воляполучатьиз Передача параметровприезжатьrollupизпеременные средысередина,Исправлятьexecaчасть
Язык кода:javascript
копировать
js
копироватькод
await execa(
        'rollup',
        [
          '-c',
          '--environment', // Передача переменных среды  Файл конфигурации доступен через proccess.env.
          [
            `TARGET:${target}`,
            formats ? `FORMATS:${formats}` : `` // Продолжать передавать параметры 
          ]
            .filter(Boolean)
            .join(',')
        ],
        { stdio: 'inherit' }
    )
  1. существоватьrollup.config.mjsсерединаполучатьпеременные средыиприложение
Язык кода:javascript
копировать
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:

Язык кода:javascript
копировать
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]Приходитьсделай это Работа。этотинструмент Есть три основных Функция,Мы хотим использовать красную рамку функции.,Как показано на рисунке:

Ключевые этапы реализации:

  1. корень Оглавление Внизгенерироватьapi-extractor.jsonи ВоляdtsRollupнастраиватьдля开启
  2. 子Сумка Вниздобавлятьдобавлятьapi-extractor.jsonи定义заявлениедокумент Входи Экспортировать элементы,Как показано ниже:
Язык кода:javascript
копировать
json
копироватькод
{  "extends": "../../api-extractor.json",
  "mainEntryPointFilePath": "./dist/packages/<unscopedPackageName>/src/index.d.ts", // Файл декларации, созданный путем объединения
  "dtsRollup": {
    "publicTrimmedFilePath": "./dist/<unscopedPackageName>.d.ts" // Извлеките его как файл декларации в каталог dist.
  }
}
  1. существоватьrollupосуществлять Триггер после завершенияAPI Extractorдействовать,Добавьте в метод сборки следующие операции:
Язык кода:javascript
копировать
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 })
      }
}
  1. удалитьrollupгенерироватьиззаявлениедокумент

Итак, здесь весь процесс упаковки относительно завершен.

Использование наборов изменений

Для монорепозитория, реализованного в рабочей области pnpm, если вы хотите управлять версиями пакетов и публиковать их, вам необходимо использовать некоторые инструменты. Официально рекомендуются следующие инструменты:

  • changesets[9]
  • rush[10]

насздесь主要学习一Внизchangesetsизиспользовать,Он имеет две основные функции:

  • Версия пакета управления
  • Создать журнал изменений

дляmonorepoпроектиспользовать它встреча更добавлятьудобный,Конечно Сумкатакже Может以использовать。主要区别существовать Впроект Внизиметь Нетpnpm-workspace.yaml,Если не указана мультипосылка,Таквстреча当作普通Сумка Процесс。 Итак, давайте рассмотрим конкретные шаги:

1. Установка

Язык кода:javascript
копировать
sql
копироватькод
pnpm add @changesets/cli -Dw

2. Инициализируйте конфигурацию набора изменений.

Язык кода:javascript
копировать
csharp
копировать код
инициализация набора изменений npx

этот Заказбудет внутрикорень Оглавление Внизгенерировать.changesetдокументпапка,В папке находится файл конфигурации и файл readme. Сгенерированный файл конфигурации выглядит следующим образом:

Язык кода:javascript
копировать
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**[12] и **linked**[13] Разница
  • fixedиlinkedизценитьдлядвумерный массив,Элемент представляет собой определенное имя пакета или соответствующее выражение.,нода Эти Сумкадолженсуществоватьpnpm-workspace.yamlдобавлятьдобавлять Проходить

3. Создайте информацию о версии пакета выпуска.

бегатьnpx changeset,Появится ряд вопросов подтверждения.,включать:

  • Какие пакеты необходимо обновить?
  • Какие пакеты обновляются до основных версий
  • Какие пакеты обновляются до минорных версий
  • Изменить информацию (добавлять будет добавлено в окончательный сгенерированный файл Changelog.md) После ответа на все вопросы,будет внутри.changesetВнизгенерироватьодинMarkdownдокумент,Содержимое этого файла представляет собой набор ответов на вопрос, заданный только что.,Вероятно, это выглядит так:
Язык кода:javascript
копировать
ямл
копировать доступно
---
'@scope/mini-cli': основной
'@scope/tools': незначительное
---

обновить пакеты

—-- В середине находится список пакетов, которые необходимо обновить. И обновленная версия, соответствующая упаковке, внизу находится информация о модификации.

4. Обновите версию пакета и создайте журнал изменений.

бегатьnpx changeset version Эта команда сделает следующее

  • Обновите соответствующую версию пакета на основе файла md, созданного на предыдущем шаге, и файла конфигурации набора изменений.
  • для Версия更新из СумкагенерироватьCHANGELOG.mdдокумент Заполните информацию об изменении, заполненную на предыдущем шаге.
  • удалить Предыдущий шаггенерироватьизMarkdownдокумент,Гарантированно используется только один раз

После этого рекомендуется,pulishДо Воля改动合иприезжатьглавная ветка

5. Выпуск версии

Об этом нечего сказать,прямойвыполнить командуnpx changeset publishПрямо сейчас Может

Чтобы обеспечить выпуск функции, добавьте следующий скрипт для контроллера:

Язык кода:javascript
копировать
json
копироватькод
{    "scripts": {
        "release": "run-s build releaseOnly",
        "releaseOnly": "changeset publish"
    }
}

предварительная версия

Набор изменений обеспечивает режим предварительной версии с тегами. При использовании этого режима необходимо обратить внимание:

  • проходитьpre enter/exitВходитьили Выход довыпускатьмодель,Все команды обычного режима могут быть выполнены в этом режиме.,напримерversionpublish
  • Чтобы не влиять на официальную версию,Предварительный режим лучше всегоРабота в отдельной ветке,Чтобы избежать проблем, которые трудно устранить
  • В предварительном режиме,Версия Числодля正常модель Вниздолженгенерироватьиз Версия Числодобавлять-<tag>.<num>окончание。tagдляpreЗаказловитьизtagимя,numкаждый развыпускать都встреча递увеличивать Начать с 0
  • Предварительные версии не соответствуют требованиям семантического управления версиями.,Например, моя зависимая версия пакета — «^1.0.0».,Так,предварительная версия не удовлетворена этой версией,Таким образом, зависимая версия пакета останется неизменной.

Полный предварительный пакет, вероятно, будет выполнять следующие операции:

  1. changeset pre enter <tag> Войти в предварительный режим
  2. changeset Подтвердите информацию о версии пакета выпуска
  3. changeset version генерироватьпредварительная версия Числоиchangelog
  4. changeset publish выпускатьпредварительная версия

здесьизtagМожет以данас常用из Несколькотипформа:

имя

Функция

alpha

Это внутренняя тестовая версия, которая обычно не выпускается для внешнего мира. Она содержит множество ошибок и обычно используется только тестировщиками.

beta

Также бета-версия,Версия на этом этапе всегда будет включать новые обновления. Запущен после альфа-версии

rc

(Release Candidate) Кандидат на освобождение. Версия RC больше не будет добавлять новые дополнения, она в основном ориентирована на отладку.

Каждый раз, когда вам нужно обновить версию, просто выполните это снова, начиная с шага 2.

Если вам нужно выпустить официальную версию,Выход довыпускатьмодельchangeset pre exit,Затем переключитесь на основную ветку для работы.

Проверка формата кода

Здесь мы в основном проверяем стиль кода. проверятьинструментдляeslint (В основном для js, ts и других языковых файлов js) и prettier(js、css и другие типы файлов)

Вспомогательные инструменты есть

  • **lint-stage**[14] Проверьте файлы промежуточной области
  • **simple-git-hooks**[15] одинgit钩子управлятьинструмент,Преимущество в том, что он прост в использовании,Недостатком является то, что каждый хук может выполнить только одну команду.,нравиться果需要осуществлятьнесколько Заказ Может以选择husky

Конфигурация следующая:

Язык кода:javascript
копировать
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Приходитьвыполнить,Регистрация перехватчика запускается после установки зависимостей проекта. Вы можете добавить следующий скрипт. (Если операция перехвата изменится,Вам необходимо повторно выполнить операцию «Установить зависимости» для обновления)

Язык кода:javascript
копировать
json
копироватькод
"scripts": {
    "postinstall": "simple-git-hooks",
  },

Представление спецификации кода

Здесь в основном используются следующие три инструмента:

  • **Commitizen**[16]Это инструмент командной строки, который в основном используется для того, чтобы помочь нам быстрее писать стандартизированные сообщения о фиксации.
  • **Commitlint**[17]Используется для проверки того, соответствует ли заполненное сообщение фиксации установленным спецификациям.
  • **simple-git-hooks**[18]

1. Использование Commitizen

  1. УстановитьCommitizen
Язык кода:javascript
копировать
копироватькод
npm install -g commitizen
  1. УстановитьCommitizenизадаптер,Определите характеристики для использования,здесьиспользоватьcz-conventional-changelog[19],Вы также можете выбрать другие адаптеры
Язык кода:javascript
копировать
копироватькод
npm install -g cz-conventional-changelog
  1. Глобально указанный адаптер
Язык кода:javascript
копировать
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]

  1. Сначала установите эти два пакета:
Язык кода:javascript
копировать
sql
копироватькод
pnpm add @commitlint/config-conventional @commitlint/cli -Dw
  1. корень Оглавление ВнизписатьcommitlintКонфигурация,Укажите пакет правил
Язык кода:javascript
копировать
arduino
копироватькод
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
  1. Конфигурация git перехватчик выполняет операции проверки (осуществлятьpnpm installобновить крючок)
Язык кода:javascript
копировать
json
копироватькод
"simple-git-hooks": {
    "commit-msg": "npx --no -- commitlint --edit ${1}"
  },

Если вы отправите еще раз в это время, сообщение о фиксации будет проверено. Если оно не соответствует спецификациям, появится следующее приглашение:

image.png

Рекомендовано в прошлом

Онлайн-ОШИБКА заставляет задуматься: следует ли сохранить ^~ в package.json?

Оптимизация производительности упаковки Vite и заполнение ям

Практика разработки интерфейсов ByteDance

boy illustration
RasaGpt — платформа чат-ботов на основе Rasa и LLM.
boy illustration
Nomic Embed: воспроизводимая модель внедрения SOTA с открытым исходным кодом.
boy illustration
Улучшение YOLOv8: EMA основана на эффективном многомасштабном внимании, основанном на межпространственном обучении, и эффект лучше, чем у ECA, CBAM и CA. Малые цели имеют очевидные преимущества | ICASSP2023
boy illustration
Урок 1 серии Libtorch: Тензорная библиотека Silky C++
boy illustration
Руководство по локальному развертыванию Stable Diffusion: подробные шаги и анализ распространенных проблем
boy illustration
Полностью автоматический инструмент для работы с видео в один клик: VideoLingo
boy illustration
Улучшения оптимизации RT-DETR: облегченные улучшения магистрали | Support Paddle облегченный rtdetr-r18, rtdetr-r34, rtdetr-r50, rtdet
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | Деформируемое внимание с большим ядром (D-LKA Attention), большое ядро ​​​​свертки улучшает механизм внимания восприимчивых полей с различными функциями
boy illustration
Создано Datawhale: выпущено «Руководство по тонкой настройке развертывания большой модели GLM-4»!
boy illustration
7B превышает десятки миллиардов, aiXcoder-7B с открытым исходным кодом Пекинского университета — это самая мощная модель большого кода, лучший выбор для корпоративного развертывания.
boy illustration
Используйте модель Huggingface, чтобы заменить интерфейс внедрения OpenAI в китайской среде.
boy illustration
Оригинальные улучшения YOLOv8: несколько новых улучшений | Сохранение исходной информации — алгоритм отделяемой по глубине свертки (MDSConv) |
boy illustration
Второй пилот облачной разработки | Быстро поиграйте со средствами разработки на базе искусственного интеллекта
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция с нулевым кодированием и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
Решенная Ошибка | Загрузка PyTorch медленная: TimeoutError: [Errno 110] При загрузке факела истекло время ожидания — Cat Head Tiger
boy illustration
Brother OCR, библиотека с открытым исходным кодом для Python, которая распознает коды проверки.
boy illustration
Новейшее подробное руководство по загрузке и использованию последней демонстрационной версии набора данных COCO.
boy illustration
Выпущен отчет о крупной модели финансовой отрасли за 2023 год | Полный текст включен в загрузку |
boy illustration
Обычные компьютеры также могут работать с большими моделями, и вы можете получить личного помощника с искусственным интеллектом за три шага | Руководство для начинающих по локальному развертыванию LLaMA-3
boy illustration
Одной статьи достаточно для анализа фактора транскрипции SCENIC на Python (4)
boy illustration
Бросая вызов ограничениям производительности небольших видеокарт, он научит вас запускать большие модели глубокого обучения с ограниченными ресурсами, а также предоставит полное руководство по оценке и эффективному использованию памяти графического процессора!
boy illustration
Команда Fudan NLP опубликовала 80-страничный обзор крупномасштабных модельных агентов, в котором в одной статье представлен обзор текущего состояния и будущего агентов ИИ.
boy illustration
[Эксклюзив] Вы должны знать о новой функции JetBrains 2024.1 «Полнострочное завершение кода», чтобы решить вашу путаницу!
boy illustration
Краткое изложение базовых знаний о регистрации изображений 1.0
boy illustration
Новейшее подробное руководство по установке и использованию библиотеки cv2 (OpenCV, opencv-python) в Python.
boy illustration
Легко создайте локальную базу знаний для крупных моделей на основе Ollama+AnythingLLM.
boy illustration
[Решено] ошибка установки conda. Среда решения: не удалось выполнить первоначальное зависание решения. Повторная попытка с помощью файла (графическое руководство).
boy illustration
Одна статья поможет вам понять RAG (Retrival Enhanced Generation) | Введение в концепцию и теорию + практику работы с кодом (включая исходный код).
boy illustration
Эволюция архитектуры шлюза облачной разработки
boy illustration
Docker и Kubernetes [Разработка контейнерных приложений с помощью Python]