Démarrage de la bibliothèque de composants React et TypeScript


La plupart de mon travail, j'écris des backends, mais l'autre jour, il y avait une tâche pour démarrer une bibliothèque de composants sur React. Il y a quelques années, alors que la version React était aussi petite que mon expérience en développement frontal, j'ai déjà adopté une approche du projectile et il s'est avéré maladroitement et maladroitement. Compte tenu de la maturité de l'écosystème React actuel et de mon expérience grandissante, j'ai été inspiré cette fois pour tout faire correctement et commodément. En conséquence, j'avais un blanc pour la future bibliothèque, et afin de ne rien oublier et de tout rassembler en un seul endroit, cet article de triche a été écrit, ce qui devrait également aider ceux qui ne savent pas par où commencer. Voyons voir ce que j'ai fait.


TL / DR: le code d'une bibliothèque prête à démarrer peut être consulté sur github


Le problème peut être abordé de deux côtés:


  1. Trouver un kit de démarrage, un passe-partout ou un générateur cli prêts à l'emploi
  2. Collectionnez tout vous-même

La première méthode est bonne pour un démarrage rapide, lorsque vous ne voulez absolument pas gérer la configuration et la connexion des packages nécessaires. En outre, cette option convient aux débutants qui ne savent pas par où commencer et quelle devrait être la différence entre la bibliothèque et l'application régulière.


Au début, je suis allé dans le premier sens, mais j'ai ensuite décidé de mettre à jour les dépendances et de fixer quelques paquets supplémentaires, puis toutes sortes d'erreurs et d'incohérences ont plu. En conséquence, il a retroussé ses manches et a tout fait lui-même. Mais je mentionnerai le générateur de bibliothèque.


Créer une bibliothèque React


La plupart des développeurs qui traitent avec React ont entendu parler d'un démarreur d'application React pratique qui vous permet de minimiser la configuration du projet et fournit des valeurs par défaut raisonnables - Create React App (CRA). En principe, il pourrait être utilisé pour la bibliothèque ( il y a un article sur le Habré ). Cependant, la structure du projet et l'approche du développement de l'ui-kit sont légèrement différentes de la SPA habituelle. Nous avons besoin d'un répertoire séparé avec les codes sources des composants (src), un bac à sable pour leur développement et débogage (exemple), un outil de documentation et de démonstration ("showcase") et un répertoire séparé avec des fichiers préparés pour l'exportation (dist). De plus, les composants de bibliothèque ne seront pas ajoutés à l'application SPA, mais seront exportés via un fichier d'index. En y réfléchissant, je suis allé chercher et j'ai rapidement découvert un package CRA similaire - Creat React Library (CRL).


CRL, comme CRA, est un utilitaire CLI facile à utiliser. En l'utilisant, vous pouvez générer un projet. Il contiendra:


  • Rollup configuré pour créer des modules cjs et es et une carte source avec prise en charge des modules css
  • babel pour la transpilation dans ES5
  • Plaisanterie pour les tests
  • TypeScript (TS) comme option que nous aimerions utiliser

Pour générer le projet de bibliothèque, nous pouvons le faire ( npx nous permet de ne pas installer les packages globalement):


npx create-react-library 

Nous répondons aux questions proposées.

Questions CLR


Et grâce à l'utilitaire, nous obtenons un projet généré et prêt à travailler de la bibliothèque de composants.


Avec une certaine structure

Arbre clr


Et puis quelque chose s'est mal passé ...

Les dépendances sont un peu dépassées aujourd'hui, j'ai donc décidé de toutes les mettre à jour vers les dernières versions en utilisant npm-check :


 npx npm-check -u 

Un autre fait triste est que l'application sandbox dans le répertoire d' example est générée en js. Vous devrez le réécrire manuellement dans TypeScript, en ajoutant tsconfig.json et certaines dépendances (par exemple, typescript lui-même et @types base).


Le package react-scripts-ts est également déclaré deprecated et n'est plus pris en charge. Au lieu de cela, vous devez installer react-scripts , car depuis un certain temps maintenant CRA (dont le package est react-scripts ) prend en charge TypeScript à partir de la boîte (en utilisant Babel 7).


En conséquence, je n'ai pas réussi à tirer la react-scripts sur mon idée de la bibliothèque. Pour autant que je m'en souvienne, le Jest de ce package nécessitait l'option de compilateur isolatedModules , qui allait à l'encontre de mon désir de générer et d'exporter d.ts partir de la bibliothèque (tout cela est en quelque sorte lié aux limitations de Babel 7, qui est utilisé par Jest et react-scripts pour compiler TS ) J'ai donc fait une eject pour les react-scripts de react-scripts , regardé le résultat et tout refait avec mes mains, dont je parlerai plus tard.


tsdx


Merci à l'utilisateur StanEgo , qui a parlé d'une excellente alternative à Create React Library - tsdx . Ce cli-utilitaire est également similaire à CRA et dans une commande créera la base de votre bibliothèque avec Rollup, TS, Prettier, husky, Jest et React configurés. Et React est disponible en option. Assez simple à faire:


 npx tsdx create mytslib 

Et par conséquent, les nouvelles versions nécessaires des packages seront installées et tous les paramètres définis. Obtenez un projet de type CRL. La principale différence avec CRL est Zero-config. Autrement dit, la configuration Rollup nous est cachée dans tsdx (tout comme CRA le fait).


Ayant rapidement parcouru la documentation, je n'ai pas trouvé les méthodes recommandées pour une configuration plus fine ou quelque chose comme éjecter comme dans CRA. Après avoir examiné la question du projet, j'ai constaté que jusqu'à présent, il n'y a pas une telle possibilité . Pour certains projets, cela peut être critique, auquel cas vous devrez travailler un peu avec vos mains. Si vous n'en avez pas besoin, alors tsdx est un excellent moyen de démarrer rapidement.


Prenez le contrôle entre nos mains


Mais que se passe-t-il si vous suivez la deuxième voie et que vous collectez tout vous-même? Commençons donc depuis le début. Exécutez npm init et générez package.json pour la bibliothèque. Ajoutez-y quelques informations sur notre forfait. Par exemple, nous écrivons les versions minimales pour node et npm dans le champ engines . Les fichiers collectés et exportés seront placés dans le répertoire dist . Nous l'indiquons dans le champ des files . Nous créons une bibliothèque de composants react, nous espérons donc que les utilisateurs auront les packages nécessaires - nous peerDependencies versions minimales requises de peerDependencies react-dom dans le champ peerDependencies .


Installez maintenant les packages react et react react-dom et les types nécessaires (puisque nous scierons des composants sur TypeScript) en tant que devDependencies (comme tous les packages de cet article):


 npm install --save-dev react react-dom @types/react @types/react-dom 

Installez TypeScript:


 npm install --save-dev typescript 

Créons des fichiers de configuration pour le code principal et les tests: tsconfig.json et tsconfig.test.json . Notre target sera en es5 , nous générerons sourceMap , etc. Une liste complète des options possibles et leur signification peut être trouvée dans la documentation . N'oubliez pas d' include répertoire source dans l' include , et ajoutez les node_modules et dist dans l' exclude . Dans package.json nous indiquons dans le champ typings où trouver les types pour notre bibliothèque - dist/index .


Créez le répertoire src pour les composants source de la bibliothèque. Ajoutez toutes sortes de petites choses, comme .gitignore , .editorconfig , un fichier avec une licence et README.md .


Rollup


Nous utiliserons Rollup pour l'assemblage, comme suggéré par CRL. Paquets et config requis, j'ai aussi espionné CRL. En général, j'ai entendu l'opinion que Rollup est bon pour les bibliothèques et Webpack pour les applications. Cependant, je n'ai pas configuré Webpack (ce que CRA fait pour moi), mais Rollup est vraiment bon, simple et beau.


Installer:


 npm install --save-dev rollup rollup-plugin-babel rollup-plugin-commonjs rollup-plugin-node-resolve rollup-plugin-peer-deps-external rollup-plugin-postcss rollup-plugin-typescript2 rollup-plugin-url @svgr/rollup 

Dans package.json ajoutez les champs avec la distribution des ensembles de bibliothèques collectés, comme le recommande le rollup - pkg.module :


  "main": "dist/index.js", "module": "dist/index.es.js", "jsnext:main": "dist/index.es.js" 

Créez le fichier de configuration rollup.config.js
 import typescript from 'rollup-plugin-typescript2'; import commonjs from 'rollup-plugin-commonjs'; import external from 'rollup-plugin-peer-deps-external'; import postcss from 'rollup-plugin-postcss'; import resolve from 'rollup-plugin-node-resolve'; import url from 'rollup-plugin-url'; import svgr from '@svgr/rollup'; import pkg from './package.json'; export default { input: 'src/index.tsx', output: [ { file: pkg.main, format: 'cjs', exports: 'named', sourcemap: true }, { file: pkg.module, format: 'es', exports: 'named', sourcemap: true } ], plugins: [ external(), postcss({ modules: false, extract: true, minimize: true, sourceMap: true }), url(), svgr(), resolve(), typescript({ rollupCommonJSResolveHack: true, clean: true }), commonjs() ] }; 

La config est un fichier js, ou plutôt un objet exporté. Dans le champ de input , spécifiez le fichier dans lequel les exportations de notre bibliothèque sont enregistrées. output - décrit nos attentes sur la sortie - dans quel module compiler dans le format et où le mettre.


Vient ensuite le terrain avec une liste et la configuration des plugins
  • rollup-plugin-peer-deps-external - vous permet d'exclure peerDependencies du bundle pour réduire sa taille. Ceci est raisonnable, car peerDependencies est attendu de l'utilisateur de la bibliothèque.
  • rollup-plugin-postcss - intègre PostCss et Rollup . Ici, nous désactivons les modules css, incluons css dans le package d'exportation de notre bibliothèque, le minimisons et activons la création de sourceMap. Si vous n'exportez aucun css autre que celui utilisé par les composants de la bibliothèque, l' extract peut être évitée - les css nécessaires dans les composants seront ajoutés à la balise head sur la page si nécessaire à la fin. Cependant, dans mon cas, il est nécessaire de distribuer des CSS supplémentaires (grille, couleurs, etc.), et le client devra se connecter explicitement à la bibliothèque css-bundle.
  • rollup-plugin-url - vous permet d'exporter diverses ressources, telles que des images
  • svgr - transforme svg en composants React
  • rollup-plugin-node-resolution - définit l'emplacement des modules tiers dans node_modules
  • rollup-plugin-typescript2 - connecte le compilateur TypeScript et offre la possibilité de le configurer
  • rollup-plugin-commonjs - convertit les modules de dépendance commonjs en modules es afin qu'ils puissent être inclus dans le bundle

Ajoutez une commande dans le champ scripts package.json à construire ( "build": "rollup -c" ) et démarrez l'assemblage en mode veille pendant le développement ( "start": "rollup -c -w && npm run prettier-watch" ) .


Le premier composant et fichier d'exportation


Nous allons maintenant écrire le composant React le plus simple pour vérifier le fonctionnement de notre assemblage. Chaque composant de la bibliothèque sera placé dans un répertoire séparé du répertoire parent - src/components/ExampleComponent . Ce répertoire contiendra tous les fichiers associés au composant - tsx , css , test.tsx et ainsi de suite.
Créons un fichier de styles pour le composant et tsx fichier tsx du composant lui-même.


ExampleComponent.tsx
 /** * @class ExampleComponent */ import * as React from 'react'; import './ExampleComponent.css'; export interface Props { /** * Simple text prop **/ text: string; } /** My First component */ export class ExampleComponent extends React.Component<Props> { render() { const { text } = this.props; return ( <div className="test"> Example Component: {text} <p>Coool!</p> </div> ); } } export default ExampleComponent; 

De plus, dans src vous devez créer un fichier avec des types communs aux bibliothèques, où un type sera déclaré pour css et svg (jeté un œil à CRL).


typings.d.ts
 /** * Default CSS definition for typescript, * will be overridden with file-specific definitions by rollup */ declare module '*.css' { const content: { [className: string]: string }; export default content; } interface SvgrComponent extends React.FunctionComponent<React.SVGAttributes<SVGElement>> {} declare module '*.svg' { const svgUrl: string; const svgComponent: SvgrComponent; export default svgUrl; export { svgComponent as ReactComponent }; } 

Tous les composants exportés et css doivent être spécifiés dans le fichier d'exportation. Nous l'avons - src/index.tsx . Si certains css ne sont pas utilisés dans le projet et ne sont pas répertoriés comme faisant partie de ceux importés dans src/index.tsx , ils seront alors rejetés de l'assembly, ce qui est correct.


src / index.tsx
 import { ExampleComponent, Props } from './ExampleComponent'; import './export.css'; export { ExampleComponent, Props }; 

Vous pouvez maintenant essayer de construire la bibliothèque - npm run build . En conséquence, le rollup démarre et collecte notre bibliothèque en bundles, que nous trouverons dans le répertoire dist .


Ensuite, nous ajoutons quelques outils pour améliorer la qualité de notre processus de développement et son résultat.


Oublier la mise en forme du code avec Prettier


Je déteste dans une révision de code pour souligner une mise en forme négligente ou non standard pour un projet, et encore plus pour en discuter. De telles failles devraient naturellement être corrigées, mais les développeurs devraient se concentrer sur ce que fait et comment le code fait, plutôt que sur son apparence. Ces correctifs sont le premier candidat à l'automatisation. Il y a un paquet merveilleux pour cette tâche - plus joli . Installez-le:


 npm install --save-dev prettier 

Ajoutez une configuration pour un petit raffinement des règles de formatage.


.prettierrc.json
 { "tabWidth": 3, "singleQuote": true, "jsxBracketSameLine": true, "arrowParens": "always", "printWidth": 100, "semi": true, "bracketSpacing": true } 

Vous pouvez voir la signification des règles disponibles dans la documentation . WebStrom après avoir créé le fichier de configuration lui-même suggérera une utilisation prettier lors du démarrage du formatage via l'EDI. Pour éviter que le formatage ne perde du temps, ajoutez les /node_modules et /dist aux exceptions à l'aide du fichier .prettierignore (le format est similaire à .gitignore ). Vous pouvez maintenant exécuter prettier en appliquant des règles de mise en forme au code source:


 prettier --write "**/*" 

Afin de ne pas exécuter la commande explicitement à chaque fois avec vos mains et pour être sûr que le code des autres développeurs de projet sera également plus prettier , ajoutez la prettier exécution sur le precommit-hook de precommit-hook pour les fichiers marqués comme intermédiaires (via git add ). Pour une telle chose, nous avons besoin de deux outils. Premièrement, il est hasky , responsable de l'exécution des commandes avant de valider, de pousser, etc. Et deuxièmement, il est par étapes , qui peut exécuter différents linters sur les fichiers intermédiaires. Nous devons exécuter une seule ligne pour livrer ces packages et ajouter des commandes de lancement à package.json :


 npx mrm lint-staged 

Nous ne pouvons pas attendre le formatage avant de nous engager, mais assurez-vous que le prettier travaille constamment sur les fichiers modifiés dans le processus de notre travail. Oui, nous avons besoin d'un autre package - onchange . Il vous permet de surveiller les modifications apportées aux fichiers dans le projet et d'exécuter immédiatement la commande nécessaire pour eux. Installer:


 npm install --save-dev --save-exact onchange 

Ensuite, nous ajoutons aux commandes de champ de scripts dans package.json :


 "prettier-watch": "onchange 'src/**/*' -- prettier --write {{changed}}" 

Sur ce point, tous les litiges concernant la mise en forme dans le projet peuvent être considérés comme clos.


Éviter les erreurs avec ESLint


ESLint est depuis longtemps devenu un standard et peut être trouvé dans presque tous les projets js et ts. Il nous aidera aussi. Dans la configuration ESLint, je fais confiance à CRA, alors prenez simplement les packages nécessaires de CRA et branchez-les dans notre bibliothèque. De plus, ajoutez des configurations pour TS et prettier (pour éviter les conflits entre ESLint et prettier ):


 npm install --save-dev eslint eslint-config-react-app eslint-loader eslint-plugin-flowtype eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/eslint-plugin @typescript-eslint/parser babel-eslint eslint-config-prettier eslint-plugin-prettier 

ESLint à l'aide du fichier de configuration.


.eslintrc.json
 { "extends": [ "plugin:@typescript-eslint/recommended", "react-app", "prettier", "prettier/@typescript-eslint" ], "plugins": [ "@typescript-eslint", "react" ], "rules": { "@typescript-eslint/no-empty-interface": "off", "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-member-accessibility": "off" } } 

Ajoutez la commande lint - eslint src/**/* --ext .ts,.tsx --fix au champ scripts de package.json . Vous pouvez maintenant exécuter eslint via npm run lint .


Tester avec Jest


Pour écrire des tests unitaires pour les composants de bibliothèque, installez et configurez Jest , une bibliothèque de test de Facebook. Cependant, depuis nous compilons TS non via babel 7, mais via tsc, nous devons également installer le paquet ts-jest :


 npm install --save-dev jest ts-jest @types/jest 

Pour que Jest accepte correctement les importations de fichiers CSS ou autres, vous devez les remplacer par Mokami. Créez le répertoire __mocks__ et créez-y deux fichiers.
styleMock.ts :


 module.exports = {}; 

fileMock.ts :


 module.exports = 'test-file-stub'; 

Créez maintenant la configuration de plaisanterie.


jest.config.js
 module.exports = { preset: 'ts-jest', testEnvironment: 'node', moduleNameMapper: { '\\.(css|less|sass|scss)$': '<rootDir>/__mocks__/styleMock.ts', '\\.(gif|ttf|eot|svg)$': '<rootDir>/__mocks__/fileMock.ts' } }; 

Nous allons écrire le test le plus simple pour notre ExampleComponent dans son répertoire.


ExampleComponent.test.tsx
 import { ExampleComponent } from './ExampleComponent'; describe('ExampleComponent', () => { it('is truthy', () => { expect(ExampleComponent).toBeTruthy(); }); }); 

Ajoutez la commande test - npm run lint && jest au champ scripts de package.json . Pour plus de fiabilité, nous conduirons également le linter. Vous pouvez maintenant exécuter nos tests et vous assurer qu'ils réussissent - npm run test . Et pour que les tests ne tombent pas dans dist lors de l'assemblage, ajoutez le champ d' exclude du plug-in de configuration Rollup au champ d' exclude - ['src/**/*.test.(tsx|ts)'] . Spécifiez l'exécution des tests dans le husky pre-commit hook avant d'exécuter lint-staged - "pre-commit": "npm run test && lint-staged" .


Concevoir, documenter et admirer des composants avec un livre d'histoires


Chaque bibliothèque a besoin d'une bonne documentation pour une utilisation réussie et productive. Quant à la bibliothèque de composants d'interface, non seulement je veux en savoir plus, mais aussi voir à quoi ils ressemblent, et il vaut mieux les toucher et les changer. Pour prendre en charge une telle liste de souhaits, il existe plusieurs solutions. J'avais l'habitude d'utiliser un Styleguidist . Ce package vous permet d'écrire de la documentation au format markdown, ainsi que d'y insérer des exemples des composants React décrits. En outre, la documentation est collectée et à partir de celle-ci, un catalogue de site-vitrine est obtenu, où vous pouvez trouver le composant, lire la documentation à son sujet, connaître ses paramètres et y pousser une baguette.


Cependant, cette fois, j'ai décidé de regarder de plus près son concurrent - Storybook . Aujourd'hui, il semble plus puissant avec son système de plugins. De plus, il est en constante évolution, possède une grande communauté et commencera bientôt également à générer ses pages de documentation à l'aide de fichiers de démarques. Un autre avantage du Storybook est qu'il s'agit d'un bac à sable - un environnement pour le développement de composants isolés. Cela signifie que nous n'avons pas besoin d'exemples d'applications à part entière pour le développement de composants (comme le suggère CRL). Dans le livre d'histoires, nous écrivons des stories - des fichiers ts dans lesquels nous transférons nos composants avec des props entrée vers des fonctions spéciales (il est préférable de regarder le code pour le rendre plus clair). En conséquence, une application vitrine est assemblée à partir de ces stories .


Exécutez le script qui initialise le livre d'histoires:


 npx -p @storybook/cli sb init 

Maintenant, faites-vous des amis avec TS. Pour ce faire, nous avons besoin de quelques packages supplémentaires, et en même temps, nous mettrons quelques modules complémentaires utiles:


 npm install --save-dev awesome-typescript-loader @types/storybook__react @storybook/addon-info react-docgen-typescript-loader @storybook/addon-actions @storybook/addon-knobs @types/storybook__addon-info @types/storybook__addon-knobs webpack-blocks 

Le script a créé un répertoire avec la configuration du storybook - .storybook et un exemple de répertoire que nous .storybook impitoyablement. Et dans le répertoire de configuration, nous changeons les extensions et la config en ts . Nous ajoutons des addons au fichier addons.ts :


 import '@storybook/addon-actions/register'; import '@storybook/addon-links/register'; import '@storybook/addon-knobs/register'; 

Maintenant, vous devez aider le livre d'histoires à l'aide de la configuration du .storybook dans le répertoire .storybook .


webpack.config.js
 module.exports = ({ config }) => { config.module.rules.push({ test: /\.(ts|tsx)$/, use: [ { loader: require.resolve('awesome-typescript-loader') }, // Optional { loader: require.resolve('react-docgen-typescript-loader') } ] }); config.resolve.extensions.push('.ts', '.tsx'); return config; }; 

config.ts un peu la configuration config.ts , en ajoutant des décorateurs pour connecter des modules complémentaires à toutes nos histoires.


config.ts
 import { configure } from '@storybook/react'; import { addDecorator } from '@storybook/react'; import { withInfo } from '@storybook/addon-info'; import { withKnobs } from '@storybook/addon-knobs'; // automatically import all files ending in *.stories.tsx const req = require.context('../src', true, /\.stories\.tsx$/); function loadStories() { req.keys().forEach(req); } configure(loadStories, module); addDecorator(withInfo); addDecorator(withKnobs); 

Nous allons écrire notre première story dans le répertoire des composants ExampleComponent


ExampleComponent.stories.tsx
 import * as React from 'react'; import { storiesOf } from '@storybook/react'; import { ExampleComponent } from './ExampleComponent'; import { text } from '@storybook/addon-knobs/react'; const stories = storiesOf('ExampleComponent', module); stories.add('ExampleComponent', () => <ExampleComponent text={text('text', 'Some text')} />, { info: { inline: true }, text: ` ### Notes Simple example component ### Usage ~~~js <ExampleComponent text="Some text" /> ~~~ ` }); 

Nous avons utilisé des addons:


  • boutons - permet de changer les accessoires en temps réel dans le composant affiché dans le livre d'histoires. Pour ce faire, enveloppez les accessoires dans des fonctions spéciales dans les histoires
  • info - vous permet d'ajouter de la documentation et une description des accessoires à la page d'histoire

Notez maintenant que le script d'initialisation du livre d'histoires a ajouté la commande storybook à notre package.json . Utilisez-le pour exécuter le npm run storybook . Le livre de contes sera assemblé et exécuté à l' http://localhost:6006 . N'oubliez pas d'ajouter à l'exception pour le module typescript dans la configuration Rollup - 'src/**/*.stories.tsx' .


Nous développons


Ainsi, après vous être entouré de nombreux outils pratiques et les avoir préparés pour le travail, vous pouvez commencer à développer de nouveaux composants. Chaque composant sera placé dans son répertoire dans src/components avec le nom du composant. Il contiendra tous les fichiers qui lui sont associés - css, le composant lui-même dans le fichier tsx, les tests, les histoires. Nous commençons le livre d'histoires, créons des histoires pour le composant, et là nous écrivons la documentation pour celui-ci. Nous créons des tests et testons. L'import-export du composant fini est écrit dans index.ts .


De plus, vous pouvez vous connecter à npm et publier votre bibliothèque en tant que nouveau package npm. Et vous pouvez le connecter directement à partir du référentiel git à la fois du maître et d'autres branches. Par exemple, pour ma pièce, vous pouvez faire:


 npm i -s git+https://github.com/jmorozov/react-library-example.git 

Pour que dans l'application consommateur de bibliothèque du répertoire node_modules , il n'y ait que le contenu du répertoire dist à l'état assemblé, vous devez ajouter la commande "prepare": "npm run build" au champ scripts .


De plus, grâce à TS, l'auto-complétion dans l'EDI fonctionnera.


Pour résumer


À la mi-2019, vous pouvez commencer assez rapidement à développer votre bibliothèque de composants sur React et TypeScript, à l'aide d'outils de développement pratiques. Ce résultat peut être obtenu à la fois à l'aide d'un utilitaire automatisé et en mode manuel. La deuxième façon est préférable si vous avez besoin de packages actuels et de plus de contrôle. L'essentiel est de savoir où creuser, et à l'aide d'un exemple dans cet article, j'espère que cela est devenu un peu plus facile.


Vous pouvez également emporter la pièce résultante ici .


Entre autres choses, je ne prétends pas être la vérité ultime et, en général, je suis engagé dans le front-end dans la mesure où. Vous pouvez choisir d'autres packages et options de configuration et réussir à créer votre bibliothèque de composants. Je serais heureux si vous partagez vos recettes dans les commentaires. Bon codage!

Source: https://habr.com/ru/post/fr461439/


All Articles