Рука об руку создайте собственную библиотеку компонентов React 03 — Упаковка

внешний интерфейс React.js
Рука об руку создайте собственную библиотеку компонентов React 03 — Упаковка

Часть 3. Упаковка: упаковка проекта и публикация в NPM

Оригинальная ссылка

Библиотека компонентовТеперь поддерживается нашей командой, добро пожаловать на просмотр, Start ~

введение

В предыдущей части мы использовали React и другие связанные технологии для создания библиотек и их тестирования. Сейчас мы готовимся запаковать предыдущий код и опубликовать его в NPM, что удобно для других.

Учебный раздел

Эта статья, третья в этой серии: Упакуйте проект и опубликуйте его в NPM

Надежная (документация + упаковка) Инструмент: отец

Здесь разработана библиотека компонентов, и, наконец, самая важная часть решения (+ пакет документов) проблем.

Попробовав некоторые упаковочные библиотеки (такие какcreate-react-library) и Библиотека документации (React Styleguidist) не добился желаемого эффекта.

До видео на станции B:Используйте umi-библиотеку для упаковки компонентовответ становится простым и очевидным, это использоватьЮнцянь большойИнструмент для упаковки компонентов с открытым исходным кодом:umijs/father, чтобы выполнить последний шаг.

Поскольку в настоящее время весь инструмент упаковки будетsrcкак вход. Чтобы избежать предыдущей маршрутизации, код, такой как домашняя страница, упакован, и здесь были внесены серьезные изменения в структуру проекта, а также внесены новые дополнения.entryв качестве точки входа в маршрут иsrcв качестве точки входа компонента. Рекомендуется обратиться кdantdструктура каталогов в .

package.json и сведения о полях

После инициализации проекта откройте его в редакторе и изменитеpackage.jsonв следующих свойствах:

{
  "main": "lib/index.js",
  "module": "es/index.js",
  "typings": "lib/index.d.ts",c
  "files": [
      "dist",
      "lib",
      "es"
  ],
  "scripts": {
    "start": "father doc dev",
    "doc:build": "father doc build",
    "doc:deploy": "father doc deploy",
    "lib:build": "father build"
  },
  "peerDependencies": {
    "react": ">=16.8.0",
    "react-dom": ">=16.8.0",
    "antd": ">=3.21.0"
  },
  "devDependencies": {
    "babel-plugin-import": "^1.13.0",
    "father": "^2.29.2",
    "fs-extra": "^8.1.0",
    "klaw-sync": "^6.0.0"
  },
  "dependencies": {
    "antd": "^3.21.0",
    "classnames": "^2.2.6",
    "lodash": "^4.17.15"
  },
}

После добавления запустите:npm installЗависимость от установки. Пока ждем, давайте разберемся в конкретном значении вышеуказанных свойств:

  • "main": "lib/index.js": ОпределенныйnpmВходной файл пакета, можно использовать как среду браузера, так и среду узла.
  • "module": "es/index.js": ОпределениеnpmВходной файл спецификации ESM пакета, который можно использовать как в среде браузера, так и в среде узла.

Вышеупомянутые две являются точками входа в программу.Когда мы используем инструмент упаковки (webpack) для упаковки: 1. Если он уже поддерживает поле pkg.module, будет предпочтительно использоваться версия спецификации модуля ES6.import, который включает механизм встряхивания дерева. 2. Если он не распознает поле pkg.module, он будет использовать версию, которую мы скомпилировали в спецификацию CommonJS.require('package1')Не мешает процессу упаковки.

  • typings: файл объявления типа для пакета
  • files: описывает все элементы, которые будут содержаться в пакете при его установке в качестве зависимости.официальная документация
  • scripts/"start": "father doc dev"doczспособ разработки компонентов
  • scripts/"doc:build": "father doc build": сборка документации
  • scripts/"doc:deploy": "father doc deploy": опубликовать документ
  • scripts/"build": "father build": Упаковочные компоненты
  • peerDependencies: это особый тип зависимости, который появляется только при публикации собственного пакета. Если это свойство написано, это означает, что пакет зависимостей, который вы разрабатываете, должен точно соответствовать зависимости, заданной этим свойством. здесь, потому что некоторые компоненты основаны наAntdПростая инкапсуляция, поэтому при использовании этой библиотеки компонентов также необходимо установить соответствующую версиюAntdи т.д. зависимости.
  • dependencies: это ваши обычные зависимости или те, которые вам нужны при запуске вашего кода (например, React или ImmutableJS).
  • devDependencies: это ваши зависимости разработки. Зависимости, которые необходимы в определенные моменты рабочего процесса разработки, но не при выполнении кода (например, Babel или Flow).

Первый опыт отца: упаковка первого компонента

Вот давайте:EmptyLineПросто добавьте документацию. Для удобства чтения сюда помещается весь соответствующий код компонента.

src/index.tsx
export { default as EmptyLine } from './empty-line';
src/empty-line/index.tsx
import './style/index.less';
import EmptyLine from './EmptyLine';

export default EmptyLine;
src/empty-line/index.mdx
---
name: EmptyLine
route: /empty-line
menu: 组件
---

import { Playground } from 'docz';
import EmptyLine from './index';

## EmptyLine

> 组件名称:空行(EmptyLine),自定义组件 ,宽度 100%

### 代码演示

#### 复制信息

<Playground>
    <p>第一行文字</p>
    <EmptyLine />
    <p>第二行文字</p>
</Playground>

## API

|参数|说明|类型|默认值|
|:--|:--|:--|:--|
|height|空行的高度|number?|20|
src/empty-line/EmptyLine.tsx
import React from 'react';
import './style/index.less';

export interface IEmptyLineProps {
  height?: number;
}

const EmptyLine = ({ height = 20 }: IEmptyLineProps) => {
  return <div className="empty-line" style={{ height }} />;
};

export default EmptyLine;
src/empty-line/style/index.less
.empty-line {
    width: 100%;
    height: 20px;
}
.fatherrc.js
export default {
    // cssModules: true, // 默认是 .module.css 走 css modules,.css 不走 css modules。配置 cssModules 为 true 后,全部 css 文件都走 css modules。(less 文件同理)
    extractCSS: true,
    esm: 'babel',
    cjs: 'babel',
    umd: {
      name: 'dantd',
      sourcemap: true,
      globals: {
        react: 'React',
        antd: 'antd'
      },
    },
    extraBabelPlugins: [
      ['import', { libraryName: 'antd', libraryDirectory: 'es', style: true }],
    ],
    entry: 'src/index.tsx',
    lessInBabelMode: true,
    doc: {
      base: '/dantd/',
      menu: [
        '首页',
        '组件'
      ]
    },
}

Дополнительные элементы конфигурации можно найти в документации:umijs/father

tsconfig.json
{
    "compilerOptions": {
      "baseUrl": "./src",
      "paths": {
        "antd": ["src/index.tsx"],
        "antd/es/*": ["src/*"]
      },
      "strictNullChecks": true,
      "moduleResolution": "node",
      "esModuleInterop": true,
      "experimentalDecorators": true,
      "jsx": "preserve",
      "noUnusedParameters": true,
      "noUnusedLocals": false,
      "noImplicitAny": true,
      "target": "es6",
      "lib": ["dom", "es2017"],
      "skipLibCheck": true
    },
    "exclude": ["node_modules", "lib", "es"]
}

После добавления этих файлов запуститеnpm start, вы можете увидеть следующий интерфейс.

image

Если вы хотите представитьAntd, просто импортируйте его напрямую. В приведенной выше конфигурации он был добавлен:extraBabelPlugins. Antd может быть загружен по запросу.

Введите код в компонент:

import { Card, Typography } from 'antd';

ES6Код упаковки:

import "antd/es/card/style";
import _Card from "antd/es/card";
import "antd/es/typography/style";
import _Typography from "antd/es/typography";

CommonJSКод упаковки:

require("antd/es/card/style");

var _card = _interopRequireDefault(require("antd/es/card"));

require("antd/es/typography/style");

var _typography = _interopRequireDefault(require("antd/es/typography"));

Упакуйте код и опубликуйте его в NPM.

Первый забегfather buildКод упаковки.

можно увидеть,fatherбудет основываться на:umd,cjs,esЭти три формата упакованы, и после упаковки будут видны следующие файлы.

├── dist
|  ├── empty-line
|  |  ├── EmptyLine.d.ts
|  |  ├── index.d.ts
|  |  └── style
|  |     └── index.d.ts
|  ├── index.d.ts
|  ├── index.umd.css
|  ├── index.umd.js
|  ├── index.umd.js.map
|  ├── index.umd.min.css
|  ├── index.umd.min.js
|  └── index.umd.min.js.map
├── es
|  ├── empty-line
|  |  ├── EmptyLine.js
|  |  ├── index.js
|  |  └── style
|  |     ├── index.css
|  |     └── index.js
|  └── index.js
├── lib
|  ├── empty-line
|  |  ├── EmptyLine.js
|  |  ├── index.js
|  |  └── style
|  |     ├── index.css
|  |     └── index.js
|  └── index.js

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

Еще нет, сравнитеAntdизnpmПосле пакета вы найдетеesа такжеlibВ двух каталогах пока нет файла типов. нужно бытьdistСкопируйте файлы в каталог и поместите.lessизменить на.css. Я собираюсь написать здесь 2 скриптовых хака.

Установить зависимости:

npm install klaw-sync fs-extra -D

Добавьте 2 скрипта:

  • scripts/moveDeclare.js

    const path = require('path'); const klawSync = require('klaw-sync'); const fs = require('fs');

    const filesRegex = /.d.ts$/;

    const declarePaths = klawSync(path.resolve(__dirname, '../dist'), { nodir: true }).filter(pathItem => filesRegex.test(pathItem.path))

    declarePaths.forEach((pathItem) => { const esPath = pathItem.path.replace('/dist', '/es'); const libPath = pathItem.path.replace('/dist', '/lib'); fs.copyFileSync(pathItem.path, esPath); fs.copyFileSync(pathItem.path, libPath); })

    console.log('Файл .d.ts успешно скопирован!');

  • scripts/changeLess2Css.js

    const path = require('path'); const klawSync = require('klaw-sync'); const fs = require('fs');

    const filesRegex = /(.js|.d.ts)$/;

    const fileFilterFn = item => { const basename = path.basename(item.path); return filesRegex.test(basename) || basename.indexOf('.') < 0; }

    const esPaths = klawSync(path.resolve(__dirname, '../es'), { filter: fileFilterFn, nodir: true }).map(item => item.path)

    const libPaths = klawSync(path.resolve(__dirname, '../lib'), { filter: fileFilterFn, nodir: true }).map(item => item.path)

    const allPaths = esPaths.concat(libPaths);

    allPaths.forEach((fileItem) => { const fileContent = fs.readFileSync(fileItem, 'utf8'); const newFileContent = fileContent.replace(/.less/gi, '.css'); fs.writeFileSync(fileItem, newFileContent, 'utf8'); })

    console.log('.less => Суффикс файла .css успешно перезаписан!');

Измените команду упаковки:

"build": "father build && node ./scripts/moveDeclare.js && node ./scripts/changeLess2Css.js"

бегать:npm run build

Упакованные файлы могут быть загружены вnpm.

Сначала войдитеnpm:

image

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

npm version patch
git push
npm publish

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

На данный момент наша первая собственная библиотека компонентов была загружена наnpm, мы можем использовать:npm install dantdСкачайте наш установочный пакет и используйте компоненты в проекте.

image

Упаковать документацию и опубликовать на GitHub Pages

Первый вpackage.jsonфайл, добавитьgitАдрес удобен для публикации документа в будущем:

"repository": {
    "type": "git",
    "url": "https://github.com/jokingzhang/dantd"
},

Выполните следующую команду, чтобы упаковать документ:

npm run doc:build

Выполните следующую команду, чтобы опубликовать документ:

npm run doc:deploy

Затем перейдите по соответствующему адресу, чтобы просмотреть документы компонентов, которые мы опубликовали в Интернете:dantd

image

заключительные замечания

Первая собственная библиотека компонентов, которая была опубликована вnpm. 🎉🎉🎉 Однако то, какие компоненты нужно написать в этой библиотеке компонентов, нам нужно рассмотреть дальше.

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