Introduction

Si vous utilisez toujours le même genre de composants (container, widget …) dans vos projets, il peut être intéressant de les déployer dans des packages sur npmjs.com pour pouvoir les réutiliser ou pour faire profiter le monde de vos talents (sachez qu’il est également possible d’avoir des packages privés). Nous verrons qu’il est très simple de déployer un composant ReactJS sur npm et de le réutiliser dans d’autres projets. Nous créerons ce nouveau composant dans un projet utilisant ES6 et JSX grace à webpack. Si vous avez besoin d’aide sur la mise en place de ces technologies vous trouverez ici comment configurer un projet ReactJS avec webpack.

Créer un projet npm

Pour initialiser votre projet npm, vous pouvez éditer directement le fichier package.json s’il existe ou le générer en utilisant la commande :

$ npm init

Le programme va alors vous poser plusieurs questions auxquelles vous allez devoir répondre pour paramétrer votre package. Nous allons passer en revue les informations importantes à renseigner, pour les autres vous pouvez simplement appuyer sur entrée.

Name

Il est important de bien nommer votre projet pour que d’autres développeurs puissent le trouver. La première chose à faire est donc d’utilisez la recherche de module de npmjs.com comme si vous étiez à la recherche de votre composant.

Vous ne trouverez pas de règles de nommage universelles mais beaucoup de packages ReactJS sont préfixés par react-. De par le grand nombre de packages npm, les collisions de nom sont courantes. Pensez donc à vérifier si le nom que vous avez choisi est disponible ! Si le nom que vous avez choisi est déjà pris mais que vous souhaitez tout de même le conserver, sachez que le site de npm a une section consacrée à ce sujet .

Comme react-hello-world est déjà utilisé nous apellerons notre package react-hello-wonderfull-world.

Version

Si votre composant est stable et utilisable, il est conseillé de commencer avec la version 1.0.0. Vous pouvez choisir de respecter les conventions d’incrémentation de version ou suivre vos propres règles.

Entry point

C’est le point d’entrée de votre application, quand votre package sera importé, c’est le code présent dans ce fichier qui sera utilisé. Dans notre cas nous utiliserons index.js.

Author

Si vous le souhaitez, vous pouvez ajouter votre email dans ce champ John Doe <john.doe@whatever.com>.

Résultat dans package.json

Vous pouvez renseigner les autres champs comme git repository, keywords ou les laisser vides. Dans tous les cas, vous devriez avoir dans votre package.json.

{
  "name": "react-hello-wonderfull-world",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "John Doe <john.doe@whatever.com>",
  "license": "ISC"
}

Écrire le composant

L’utilisation des syntaxes ES6 et JSX nous permmettent d’avoir un code plus simple et plus lisible. Dans notre cas le composant est un simple HelloWorld :

    import React from "react";

    class HelloWorld extends React.Component {
      render() {
        return <div id="main-element" className="title">Hello World !</div>
      }
    }
    
    export default HelloWorld;

N’oubliez pas d’exporter votre composant, c’est ce qui permettra aux utilisateurs du package npm de l’utiliser.

Générer le fichier index.js

La syntaxe avec laquelle nous avons écrit le composant de cet exemple n’est pas (encore) nativement supportée par les navigateurs, nous avons donc besoin de la transformer avant de publier le package. Pour cela, nous utilisons webpack avec cette configuration.

$ webpack -p

Créer un compte npm

Maintenant que le composant est prêt, il vous faut un compte npm pour pouvoir le déployer. Si vous n’en avez pas, il y a deux façons d’en créer un.

Depuis le site

Créez votre compte utilisateur depuis la page d’inscription. Une fois créé, vous pouvez associer votre compte à votre environment grâce à la commande :

$ npm login

En ligne de commande

Pour les plus geek, vous pouvez créer votre compte directement en ligne de commande :

$ npm adduser

Publier le package

Il ne reste plus qu’à publier notre nouveau package contenant le composant HelloWorld. Notez la complexité de cette opération !

$ npm publish

Et c’est tout 🙂 ! Une fois une version du package publiée il vous faudra obligatoirement augmenter le numéro de version avant de pouvoir le re-publier.

Utilisation du package

Vous pouvez désormais installer votre nouveau package dans un autre projet.

$ npm install react-hello-wonderfull-world

Et l’utiliser dans votre application…

    import React from "react";
    import HelloWorld from "react-hello-wonderfull-world";

    class App extends React.Component {
      render() {
        return <HelloWorld />
      }
    }
    
    export default App;

Conclusion

Nous venons de voir qu’il est très simple de publier un composant ReactJS dans un package npm. Il ne vous reste plus qu’à tester et documenter votre composant pour assurer sa stabilité et sa réutilisabilité.

« Webpack ? pas de ca chez moi !!!!! »

Si vous ne pouvez/voulez pas utiliser webpack, c’est possible, il vous suffit de travailler directement dans le fichier index.js. Pour le même composant, cela demande un peu plus de code… on vous avait prévenu !

"use strict";
    Object.defineProperty(exports, "__esModule", {
    value: true
    });
    
    var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
    
    var _react = require("react");
    
    var _react2 = _interopRequireDefault(_react);
    
    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
    
    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
    
    function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
    
    function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
    
    var HelloWorld = function (_React$Component) {
    _inherits(HelloWorld, _React$Component);
    
    function HelloWorld() {
     _classCallCheck(this, HelloWorld);
    
     return _possibleConstructorReturn(this, (HelloWorld.__proto__ || Object.getPrototypeOf(HelloWorld)).apply(this, arguments));
    }
    
    _createClass(HelloWorld, [{
     key: "render",
     value: function render() {
       return _react2.default.createElement(
         "div",
         { id: "main-element", className: "title" },
         "Hello World !"
       );
     }
    }]);
    
    return HelloWorld;
    }(_react2.default.Component);
    
    exports.default = HelloWorld;