Usar un paquete npm con Webpack creado con Storybook, React y TypeScript

Escrito por el .
javascript planeta-codigo web
Enlace permanente Comentarios

TypeScript

html.svg

En el ejemplo Desarrollar componentes React con TypeScript y sistemas de diseño con Storybook mostraba cómo desarrollar componentes React con TypeScript y de forma aislada con Storybook junto con sus pruebas unitarias y visuales con Jest. El resultado de ese proyecto es un paquete npm a instalar y usar en otros proyectos como este.

Un paquete npm es un archivo comprimido que se instala como dependencia en un proyecto. En este ejemplo se usa el paquete directamente, utilizar un repositorio de paquetes facilita el uso y distribución de los paquetes a los proyectos que los usen y esta es la forma que se debe utilizar en un proyecto real.

Este comando crea la estructura inicial de archivos y carpetas de un proyecto JavaScript que use React y TypeScript. Sobre esta base he creado el archivo de configuración para Webpack, eliminado la dependencia de react-script y creada la tarea start en el archivo package.json.

1
2
$ npx create-react-app app --template typescript

create-react.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
{
  "name": "app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.4.1",
    "@testing-library/user-event": "^7.2.1",
    "@types/jest": "^24.9.1",
    "@types/node": "^12.12.29",
    "@types/react": "^16.9.23",
    "@types/react-dom": "^16.9.5",
    "react": "^16.13.0",
    "react-dom": "^16.13.0",
    "typescript": "^3.7.5"
  },
  "devDependencies": {
    "css-loader": "^3.4.2",
    "less": "^3.11.1",
    "less-loader": "^5.0.0",
    "storybook": "file:storybook-1.0.0.tgz",
    "style-loader": "^1.1.3",
    "ts-loader": "^6.2.2",
    "webpack": "^4.42.1",
    "webpack-cli": "^3.3.11"
  },
  "scripts": {
    "start": "webpack-dev-server --mode development",
    "build": "webpack"    
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
package.json

El paquete npm del proyecto en el que se desarrolla el componente de ejemplo se instala con el siguiente comando.

1
2
$ npm install --save-dev storybook-1.0.0.tgz

npm-install-package.sh

Usando el gestor de módulos Webpack en un proyecto se puede hacer referencia a los componentes de los paquetes instalados y generar como resultado los archivos distribuibles que son los que realmente se enviarán al cliente. En Webpack se indica un punto de partida y todas las referencias necesarias a otros módulos se empaquetan. En este caso se hace referencia a un archivo JavaScript que hace tiene un uso del componente del paquete npm del componente ejemplo.

Lo primero es instalar el gestor de módulos Webpack y crear se archivo de configuración. En esta configuración se indica el directorio donde se generará el resultado del empaquetado de cada uno de los puntos de entrada y también la configuración para el servidor de desarrollo. En el servidor de desarrollo Webpack hace de servidor web que sirve los archivos procesados y un directorio público donde los html pueden hacer referencia a ellos como en el caso de index.html.

1
2
$ npm install --save-dev webpack webpack-cli
$ npm install --save-dev style-loader css-loader ts-loader less-loader
npm-install-webpack.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
const path = require("path");
const webpack = require("webpack");

module.exports = {
  mode: 'development',
  entry: {
    index: './src/index.tsx'
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/build/webpack/'
  },
  module: {
    rules: [
      { test: /\.(ts|tsx)$/, use: 'ts-loader' },
      { test: /\.(css|less)$/, use: [
        { loader: 'style-loader' },
        { loader: 'css-loader' },
        { loader: 'less-loader' }
      ]}
    ]
  },
  resolve: {
    extensions: ['.js', '.ts', '.tsx']
  },
  devServer: {
    contentBase: path.join(__dirname, "public"),
    port: 3000,
    publicPath: "/",
    hotOnly: true
  }
};
webpack.config.js

El archivo index.tsx sería un punto de entrada para Webpack, en el se importa el componente App y se incluye en la página.

1
2
3
4
5
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));
index.tsx
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import React from 'react';
import HelloWorld from 'storybook/components/HelloWorld';

import './App.css';

function App() {
  return (
    <div className="App">
      <HelloWorld />
    </div>
  );
}

export default App;
App.tsx

El archivo index.html permite probar la página con el componente incluído.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>React App</title>
    <script type="text/javascript" src="index.js" defer="defer"></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
index.html

En el directorio indicado en la configuración de Webpack se generan los archivos de resultado. En el están los archivos .map para depurar en javascript y los .d.ts con definiciones de tipos de TypeScript para archivos JavaScript.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ tree build/
build/
├── typescript
│   ├── App.d.ts
│   ├── App.js
│   ├── App.js.map
│   ├── index.d.ts
│   ├── index.js
│   └── index.js.map
└── webpack
    └── index.js

2 directories, 7 files
tree-build.out

En la página de prueba que hace uso del JavaScript producido por Webpack se carga el componente del paquete npm desarrollado en otro proyecto haciendo uso de Storybook.

Componente desarrollado en Storybook en una página
Terminal

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando siguiente comando:
npm install && npm run start


Comparte el artículo: