В этом руководстве мы создадим монорепозиторий (используя рабочие области пряжи и lerna) с тремя пакетами:

  • monorepo / core: пакет, который содержит только функции машинописного текста и имеет только машинописный текст и jest в качестве зависимостей.
  • monorepo / components: пакет с компонентами React, которые будут использоваться другими пакетами.
  • monorepo / webapp: веб-приложение, которое будет использовать пакеты core и components и будет создавать оптимизированный пакет с webpack.

Чтобы не делать это руководство слишком многословным, я не буду описывать все необходимые шаги для создания этого монорепозитория. Я опишу здесь только те шаги, в которых я сомневался, когда впервые настраивал подобное монорепо.

Я также создал репозиторий Github для этого руководства, вы можете проверить его здесь.



Настройка рабочих пространств пряжи

Yarn docs содержит отличную (и не слишком обширную) документацию о том, почему вы хотели бы использовать рабочие пространства Yarn, как их использовать и т. Д. Итак, исходя из этого:

Создайте каталог и добавьте в него следующие package.json:

{
  "name": "monorepo",
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}

Поле "workspaces" - это массив, содержащий путь к каждой рабочей области. Поскольку он также принимает шаблоны глобусов, вы можете просто назначить ему packages/* и создать каждое рабочее пространство внутри каталога packages.

Создание пакета monorepo-example / core:

Создайте каталог: mkdir packages/core и добавьте в него package.json со следующим содержимым:

{
  "name": "@monorepo-example/core",
  "version": "1.0.0",
  "main": "lib/index.js", // generated in the build step,
  "typings": "lib/index.d.ts" // generated by typescript compiler
}

Настройка машинописного текста:

Поскольку этот пакет не будет использоваться клиентом напрямую, его не нужно преобразовывать в супероптимизированный пакет. Таким образом, здесь нет необходимости использовать webpack или babel. Я буду использовать только машинописный компилятор.

Файл tsconfig.json используется для настройки компилятора машинописного текста. Вы можете создать его, просто запустив tsc --init. Эта команда создает для вас tsconfig.json файл с основными параметрами и описанием того, что делает каждый из них (чтобы было легче увидеть, что вы хотите установить).

# Install it
core$ yarn add --dev typescript
# Create a tsconfig.json file
core$ ./node_modules/.bin/tsc --init

Чтобы скомпилировать файлы машинописного текста и сгенерировать файл javascript в качестве вывода, необходимо указать каталоги ввода (файлы .ts) и вывода (.js). Итак, отредактируйте файл tsconfig.json и установите параметры rootDir и outDir.

Кроме того, установите параметр declaration, чтобы разрешить создание файлов *.d.ts в каталоге lib. Это сделает определения типов доступными при использовании этого пакета в другом пакете Typescript.

После этого вы сможете компилировать файлы Typescript с помощью tsc. При запуске этой команды скомпилированные файлы javascript будут созданы в каталоге lib.

Установка шутки:

Добавьте следующие пакеты:

yarn add --dev jest ts-jest @types/jest

Хотя Jest имеет отличную поддержку Typescript, он не распознает его "из коробки". Итак, вам нужно добавить jest.config.js файл, чтобы указать, где jest должен искать файлы, каково регулярное выражение тестового файла, какое преобразование он должен применять при обнаружении файла .ts и т. Д. Итак…:

// monorepo/packages/core/jest.config.js
module.exports = {
  "roots": [
    "<rootDir>/src",
  ],
  "transform": {
    "^.+\\.ts$": "ts-jest",
  },
  "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.ts$",
  "moduleFileExtensions": [ "ts", "js" ],
};

Использование Jest с Typescript - отличный учебник по этому поводу.

Создание пакета monorepo-example / components:

Создайте каталог components внутри packages и создайте в нем следующийpackage.json:

// monorepo/packages/components/package.json
{
  "name": "@monorepo-example/components",
  "version": "1.0.0",
  "main": "lib/index.js",
  "typings": "lib/index.d.ts" // generated by typescript compiler
}

Очень похоже на то, что мы делали при создании monorepo-example/core, добавляем пакет typescript, создаем tsconfig.json файл, устанавливаем его входной каталог на src и выходной каталог на lib и заставляем его генерировать .d.ts files.

Поскольку в этом пакете мы будем использовать React, вам необходимо:

  • Установите параметр "jsx": "react" в вашем tsconfig.json файле.
  • Установите react и react-dom
  • Установите необходимые типы: yarn add --dev @types/react @types/react-dom. (Отличное место для поиска типов популярных пакетов - это веб-сайт.)

Теперь вы можете создавать свои компоненты React в Typescript:

Важно: вы должны использовать .tsx расширение, если вы используете .jsx нотацию внутри файла. (Обычно я не использую расширение .jsx, когда работаю с проектами, предназначенными только для js. Поэтому я подумал, что могу сделать то же самое с Typescript, и потратил некоторое время, пытаясь понять, почему мой проект не компилируется…).

Создание пакета monorepo-example / webapp:

Пакет webpack будет использовать как пакеты core, так и components. Кроме того, поскольку это веб-приложение, я буду использовать веб-пакет для создания оптимизированного пакета.

Для настройки babel + Typescript я использовал это руководство. Это отличный учебник, и автор также объясняет плюсы и минусы настройки машинописного текста с использованием @babel/preset-typescript вместо загрузчиков веб-пакетов (ts-loader или awesome-typescript-loader).

Создайте каталог webapp внутри каталога packages и добавьте следующий файл package.json:

// monorepo/packages/webapp/package.json
{
  "name": "webapp",
  "version": "1.0.0"
}

Добавьте следующие зависимости:

react
react-dom

Добавьте следующие devDependencies:

@babel/core
@babel/preset-typescrip
@babel/plugin-proposal-class-properties
@babel/plugin-proposal-object-rest-spread
babel-loader
webpack
webpack-cli
typescript
@types/react
@types/react-dom

Чтобы настроить babel, создайте следующий babel.config.js:

Настройка Webpack:

В отличие от пакетов core и components, в этом пакете мы будем использовать webpack. Почему? Потому что это упрощает создание оптимизированного пакета (что-то необходимое, поскольку этот пакет мы будем отправлять клиентам). Другие пакеты не обслуживаются напрямую клиенту, поэтому нет необходимости оптимизировать их выходные данные.

Вот минимальный webpack.config.js, который позволил мне настроить Typescript + webpack. Обратите внимание только на то, что даже если ваш проект предназначен только для Typescript, вам, вероятно, потребуется добавить .js и .jsx в массив resolve.extensions. Если вы не установите это значение, веб-пакет, вероятно, не сможет разрешить некоторый импорт из вашего node_modules, который находится в js.

Использование локальных пакетов:

Чтобы использовать локальные пакеты, просто добавьте их как зависимости в свой package.json файл. Обратите внимание на версию, иначе зависимость будет установлена ​​из Github, а не из вашей локальной файловой системы.

// monorepo/packages/webapp/package.json
{
  ...,
  "dependencies": {
    ...,
    "@monorepo/core": "1.0.0",
    "@monorepo/components": "1.0.0"
  },
  ...,
}

Благодаря этому вы сможете импортировать материалы (и их типы) из ваших локальных пакетов с помощью простого:

import { AwesomeComponent } from '@monorepo/components';

Настройка Лерны

Из lerna readme: Lerna - это инструмент, оптимизирующий рабочий процесс управления репозиториями с несколькими пакетами с помощью git и npm.

Из документации по рабочим пространствам пряжи: рабочие области пряжи - это низкоуровневые примитивы, которые могут (и делать!) Инструменты вроде Lerna.

Итак, Lerna - это функциональный слой, который работает над рабочими пространствами пряжи.

Чтобы настроить Lerna, вы можете установить lerna глобально с помощью npm install -g lerna и запустить lerna init в корне вашего монорепозитория. Это создаст lerna.json файл с конфигурацией lerna.

Измените файл lerna.json, чтобы указать lerna использовать рабочие пространства Yarn:

// monorepo/lerna.json
{
  "packages": [
    "packages/*"
  ],
  "version": "0.0.0",
  "npmClient": "yarn",
  "useWorkspaces": true
}

Что я могу делать с lerna?

С lerna можно делать много всего. Я описал здесь только те функции, которые использую. Я рекомендую проверить полный список команд в документации.

  1. Вы можете запускать команды, общие для ваших пакетов, с помощью одной команды:
# Run `yarn run test` in every package that has this script
$ lerna run test --stream
# Build all packages
$ lerna run build

2. Вы можете удалить все node_modules/ с помощью lerna clean.

3. Вы можете использовать lerna exec ... для запуска произвольной команды в каждом пакете.

Могу ли я запустить команду в нескольких рабочих областях без Lerna?

да. В рабочих областях пряжи есть команда yarn workspaces run <cmd>, которая запускает выбранную команду пряжи в каждой рабочей области. Документы здесь.

Проблема в том, что он пытается запустить команду во всех пакетах, не проверяя, может ли пакет ее запустить. У Lerna этой проблемы нет, поскольку он запускает команду только в тех пакетах, в которых она есть. Итак, Lerna, вероятно, лучше масштабируется, если у вас много рабочих мест.

Хотите увидеть полный код?



Надеюсь, вам понравилось! Не стесняйтесь обращаться ко мне, если у вас есть вопросы!

Найди меня в Твиттере: @miltontakamura
Найди меня на Github: miltoneiji