Psaní vaší první knihovny uživatelského rozhraní React – Část 4:Odešlete! (V1)

Toto je čtvrtý příspěvek ze série o tom, jak vytvořit vlastní knihovnu UI React Library.

Co budeme dělat?

  • Namapujte náš zkompilovaný Javascript pro starší a novější klienty do souboru package.json.
  • Změňte trochu konfiguraci příběhové knihy a našeho tvůrce, aby podporoval kompilaci ze zdroje.
  • Publikování s Lernou!

Odešleme!

Nyní byste měli mít téměř vše připraveno k odeslání:

  1. Spuštění npm run build kořenový adresář by měl vytvořit sestavení všech vašich komponent s cjs a esm formátuje výstup ve formátu dist folder.

  2. Spuštěn npm run storybook by měla začít synchronizace vaší vývojářské kuchyně.

  3. Moduly CSS fungují v knize příběhů a css můžete vidět také na kompilovaných souborech.

Mapování našich kompilovaných souborů v package.json

Pro naši knihovnu uživatelského rozhraní máme dva typy klientů:

1) Lidé, kteří chtějí pouze it just works™ pouhým importem našich komponent a zapomenutím na ně; Dostanou naše zkompilované komponenty + css, které nebudou většinou v rozporu s jejich styly.

2) Lidé považovaní za power users které mají svůj vlastní systém svazků a chtějí generovat své třídy v procesu sestavování.

Za tímto účelem upravíme package.json ve všech našich distribuovatelných balíčcích na:

phoenix/package.json

  "main": "dist/phoenix.cjs.js",
  "module": "dist/phoenix.esm.js",
  "src": "lib/phoenix.js",

phoenix-button/package.json

  "main": "dist/phoenix-button.cjs.js",
  "module": "dist/phoenix-button.esm.js",
  "src": "lib/phoenix-button.js",

phoenix-text/package.json

  "main": "dist/phoenix-text.cjs.js",
  "module": "dist/phoenix-text.esm.js",
  "src": "lib/phoenix-text.js",

Moderní balíčky jako Webpack nebo Rollup budou používat module zadání při použití imports/exports v prostředí ES6 a main když používáme require .

Chceme, aby byly vyřešeny z kompilované verze v případě, že naši klienti nemají ve své aplikaci moduly CSS a chtějí pouze používat naše komponenty.

Upozornění Přidali jsme src Atribut, je to v podstatě ukazatel na skutečný zdroj, který chceme, aby naše power users použít.

Než budeme moci pokračovat, musíme také přidat dist složku k souborům, které publikujeme do NPM; To lze provést přidáním názvu složky do files pole v každém balíčku.json. Například toto je modifikace v phoenix balíček.

phoenix/package.json

  "files": [
    "dist",
    "lib"
  ],

Udělejte totéž pro phoenix-button a phoenix-text balíčky.

Opravit nastavení Storybook

Problém nyní je, že když běží storybook získá kód ukazující na module protože toto je výchozí chování konfigurace webového balíčku.

Viz zde:https://webpack.js.org/configuration/resolve/#resolvemainfields

To nechceme, protože náš kuchyňský dřez by měl vždy ukazovat na nejnovější src takže můžeme zkoušet nové věci, aniž bychom museli spouštět build při každé změně;

Pojďme to změnit:

.storybook/main.js

module.exports = {
  stories: ['../packages/**/*.stories.js'],
  addons: ['@storybook/addon-actions', '@storybook/addon-links'],
  webpackFinal: async (config) => {
    // remove default css rule from storybook
    config.module.rules = config.module.rules.filter((f) => f.test.toString() !== '/\\.css$/');

    // push our custom easy one
    config.module.rules.push({
      test: /\.css$/,
      use: [
        'style-loader',
        {
          loader: 'css-loader',
          options: {
            // Key config
            modules: true,
          },
        },
      ],
    });
    // This is where we change the order of resolution of main fields
    config.resolve.mainFields = ['src', 'module', 'main'];

    // Return the altered config
    return config;
  },
};

S výše uvedeným říkáme webpacku s pohádkami, aby si nejprve vzal src a pokud to nenajde, vrátí se k ostatním možnostem. Toto je stejná konfigurace, na kterou se zeptáme našeho power users použít při kompilaci komponent samostatně.

Opravte nastavení nástroje Builder

Potřebujeme také upravit naše phoenix-builder získat kód z src místo main jako jsme měli předtím.

phoenix-builder/lib/phoenix-builder.js

#!/usr/bin/env node
const rollup = require('rollup');
const path = require('path');
const resolve = require('@rollup/plugin-node-resolve').default;
const babel = require('@rollup/plugin-babel').default;
const postcss = require('rollup-plugin-postcss');

const currentWorkingPath = process.cwd();
// Little refactor from where we get the code
const { src, name } = require(path.join(currentWorkingPath, 'package.json'));

// build input path using the src
const inputPath = path.join(currentWorkingPath, src);

// Little hack to just get the file name
const fileName = name.replace('@cddev/', '');

// see below for details on the options
const inputOptions = {
  input: inputPath,
  external: ['react'],
  plugins: [
    resolve(),
    postcss({
      // Key configuration
      modules: true,
    }),
    babel({
      presets: ['@babel/preset-env', '@babel/preset-react'],
      babelHelpers: 'bundled',
      exclude: 'node_modules/**',
    }),
  ],
};
const outputOptions = [
  {
    file: `dist/${fileName}.cjs.js`,
    format: 'cjs',
  },
  {
    file: `dist/${fileName}.esm.js`,
    format: 'esm',
  },
];

async function build() {
  // create bundle
  const bundle = await rollup.rollup(inputOptions);
  // loop through the options and write individual bundles
  outputOptions.forEach(async (options) => {
    await bundle.write(options);
  });
}

build();

Nyní jsme připraveni publikovat

Běh

lerna publish

Tím se ve vašem terminálu otevře výzva k výběru verze, kterou chcete publikovat.

Začali jsme ve verzi 0.0.0 a protože je to naše první vydání, vyberme Major. To bude představovat zprávu o tom, co se stane:

Changes:
 - @cddev/phoenix-builder: 0.0.0 => 1.0.0
 - @cddev/phoenix-button: 0.0.0 => 1.0.0
 - @cddev/phoenix-text: 0.0.0 => 1.0.0
 - @cddev/phoenix: 0.0.0 => 1.0.0

Spusťte to!

Pokud vše půjde dobře, měli byste vidět:

Successfully published:
 - @cddev/[email protected]
 - @cddev/[email protected]
 - @cddev/[email protected]
 - @cddev/[email protected]
lerna success published 4 packages

Gratuluji! Vaše knihovna byla zveřejněna

Jak to mohou vaši klienti konzumovat?

Krása tohoto nastavení spočívá v tom, že vaši klienti mohou využívat hlavní balíček phoenix který jim dostane všechny komponenty nebo každou komponentu zvlášť. Zde je několik příkladů:

Spotřeba jako celek

npm i --save-dev @cddev/phoenix

A pak později ve vašem JS

import { Button, Text } from '@cddev/phoenix';

render() {
  return (
    <>
      <Button>Woo</Button>
      <Text>Waa</Text>
    </>
  );
}

Spotřeba pouze jednoho balení

npm i --save-dev @cddev/phoenix-button

A pak později ve vašem JS

import { Button } from '@cddev/phoenix-button';

render() {
  return (
    <Button>Woo</Button>
  );
}

Závěr

S tímto nastavením byste měli být schopni přidávat další balíčky, vydávat je nezávisle a doufejme, že máte malý kanál z hlediska vývoje uživatelského rozhraní.

V budoucích dílech prozkoumáme přidávání nástrojů, jako je eslint , stylelint , prettier mít konzistentní kódovou základnu a předcházet malým chybám; Chystáme se také zavést testovací infrastrukturu využívající jest a react testing library .

Prozatím vám nechávám frázi, abyste se mohli dál učit sami:"V případě pochybností zatlačte ještě o kousek dál a pak pokračujte."

Zdroje

  • Úložiště Github se všemi kódy:https://github.com/davixyz/phoenix
  • Ukázková kniha příběhů:https://davixyz.github.io/phoenix
  • Github:https://github.com/davixyz
  • Twitter:https://twitter.com/carloscastrodev