Cómo crear un proyecto Gatsby con TypeScript

El autor seleccionó el Fondo de Diversidad en Tecnología para recibir una donación como parte del programa Write for DOnations .
Introducción
TypeScript es un superconjunto de JavaScript que agrega tipado estático opcional en el momento de la compilación, lo que reduce la depuración de errores en tiempo de ejecución. Se ha convertido en una alternativa poderosa a JavaScript con el paso de los años. Al mismo tiempo, Gatsby ha surgido como un marco de interfaz útil para crear sitios web estáticos. Las capacidades de tipado estático de TypeScript se combinan bien con un generador de sitios estáticos como Gatsby, y Gatsby tiene soporte integrado para codificación en TypeScript.
En este tutorial, utilizará las funciones integradas de Gatsby para configurar un proyecto de Gatsby para TypeScript. Después de este tutorial, habrá aprendido a integrar TypeScript en su proyecto de Gatsby.
Prerrequisitos
- Necesitará tener instalados Node y npm para ejecutar un entorno de desarrollo y manejar paquetes relacionados con TypeScript o Gatsby, respectivamente. Este tutorial se probó con la versión 14.17.2 de Node.js y la versión 6.14.13 de npm. Para instalar en macOS o Ubuntu 18.04, siga los pasos de Cómo instalar Node.js y crear un entorno de desarrollo local en macOS o la sección Instalación mediante un PPA de Cómo instalar Node.js en Ubuntu 20.04 .
- Necesitará tener instalada en su computadora la herramienta de línea de comandos Gatsby CLI. Para configurarla, lea el comienzo de Cómo configurar su primer sitio Gatsby . Este tutorial se ha probado en Gatsby v3.9.0 y Gatsby CLI v3.9.0.
- Necesitará conocimientos suficientes de JavaScript, especialmente de sintaxis ES6+, como desestructuración e importaciones/exportaciones. Puede encontrar más información sobre estos temas en Comprensión de la desestructuración, los parámetros Rest y la sintaxis Spread en JavaScript y Comprensión de los módulos y las declaraciones Import and Export en JavaScript .
- Además, necesitarás tener TypeScript instalado en tu máquina. Para ello, consulta el sitio web oficial de TypeScript . Si estás usando un editor además de Visual Studio Code , es posible que tengas que realizar algunos pasos adicionales para asegurarte de que TypeScript realice comprobaciones de tipos en el momento de la compilación y muestre los errores. Por ejemplo, si estás usando Atom, tendrás que instalar el
atom-typescript
paquete para poder lograr una verdadera experiencia con TypeScript. Si deseas descargar TypeScript solo para tu proyecto, hazlo después de que se haya configurado la carpeta del proyecto Gatsby.
Paso 1: creación de un nuevo sitio de Gatsby y eliminación del texto estándar
Para comenzar, creará su sitio de Gatsby y se asegurará de que pueda ejecutar un servidor y ver el sitio. Después de eso, eliminará algunos archivos repetitivos y código que no utilice. Esto preparará su proyecto para modificaciones en pasos posteriores.
Abra la consola/terminal de su computadora y ejecute el siguiente comando:
- gatsby new gatsby-typescript-tutorial
Esto tardará unos segundos en ejecutarse, ya que configura los archivos y carpetas necesarios para el sitio de Gatsby. Una vez finalizado, cd
en el directorio del proyecto:
- cd gatsby-typescript-tutorial
Para asegurarse de que el entorno de desarrollo del sitio pueda iniciarse correctamente, ejecute el siguiente comando:
- gatsby develop
Después de unos segundos, recibirás el siguiente mensaje en la consola:
Output...You can now view gatsby-starter-default in the browser. http://localhost:8000
Normalmente, el puerto predeterminado es :8000
, pero puedes cambiarlo ejecutando en su lugar.gatsby develop -p another_number
Dirígete a tu navegador preferido y escribe http://localhost:8000
en la barra de direcciones para encontrar el sitio. Se verá así:
Nota: Existe un problema conocido con la gatsby-plugin-sharp
versión 3.9.0 del complemento que puede provocar el siguiente error al crear su sitio Gatsby:
Output ERRORENOENT: no such file or directory, open 'your_file_path/gatsby-typescript-tutorial/.cache/caches/gatsby-plugin-sharp/diskstore-f6dcddbf3c9007cd2587894f75b5cd62.json'
Una solución alternativa para este error es actualizar gatsby-plugin-sharp
a la versión 3.8.0. Para ello, abra el package.json
archivo y realice el siguiente cambio resaltado:
[gatsby-typescript-tutorial/package.json]... "dependencies": { "gatsby": "^3.9.0", "gatsby-plugin-gatsby-cloud": "^2.9.0", "gatsby-plugin-image": "^1.9.0", "gatsby-plugin-manifest": "^3.9.0", "gatsby-plugin-offline": "^4.9.0", "gatsby-plugin-react-helmet": "^4.9.0", "gatsby-plugin-sharp": "3.8.0", "gatsby-source-filesystem": "^3.9.0", "gatsby-transformer-sharp": "^3.9.0", "prop-types": "^15.7.2", "react": "^17.0.1", "react-dom": "^17.0.1", "react-helmet": "^6.1.0" },...
Guarde el archivo y luego vuelva a instalar sus dependencias con el siguiente comando:
- npm install
Ahora use la CLI de Gatsby para eliminar las carpetas public
y .cache
para que puedan reconstruirse con la nueva lista de dependencias:
- gatsby clean
Ahora podrá iniciar su sitio Gatsby en un servidor de desarrollo local con gatsby develop
. Para obtener más información sobre esta solución, lea el hilo de GitHub Memory sobre Error: ENOENT: no such file or directory
el error de Gatsby .
A continuación, eliminará todos los archivos innecesarios gatsby-node.js
, incluidos gatsby-browser.js
, y gatsby-ssr.js
:
- rm gatsby-node.js
- rm gatsby-browser.js
- rm gatsby-ssr.js
A continuación, para finalizar la configuración, eliminará parte del código repetitivo de la página de índice de su proyecto. En el directorio raíz de su proyecto, diríjase al src
directorio pages
y, a continuación, abra el index.js
archivo.
En este tutorial, solo trabajará con un StaticImage /
componente, por lo que puede eliminar el código relacionado con el Link /
componente, junto con los elementos h1
y p
. Su archivo se verá así:
tutorial-de-tipografia-de-gatsby/src/pages/index.js
import * as React from "react"import { StaticImage } from "gatsby-plugin-image"import Layout from "../components/layout"import Seo from "../components/seo"const IndexPage = () = ( Layout Seo / StaticImage src="../images/gatsby-astronaut.png" width={300} quality={95} formats={["AUTO", "WEBP", "AVIF"]} alt="A Gatsby astronaut" style={{ marginBottom: `1.45rem` }} / /Layout)export default IndexPage
Guarde y cierre el archivo.
Ahora que ha creado su proyecto y completado algunas configuraciones iniciales, está listo para instalar los complementos necesarios.
Paso 2: Instalación de dependencias
Para configurar el soporte para TypeScript en Gatsby, necesitará algunos complementos y dependencias adicionales, que instalará en este paso.
El gatsby-plugin-typescript
complemento ya viene con un sitio Gatsby recién creado. A menos que desee cambiar alguna de sus opciones predeterminadas, no es necesario que agregue este complemento a su gatsby-config.js
archivo de forma explícita. Este complemento Gatsby permite escribir .ts
y .tsx
crear archivos en TypeScript.
Dado que su aplicación puede leer archivos TypeScript, ahora cambiará los archivos JavaScript de Gatsby a una extensión de archivo TypeScript. En particular, cambie header.js
, layout.js
, y seo.js
en src/components
y index.js
en src/pages
a header.tsx
, layout.tsx
, seo.tsx
, y index.tsx
:
- mv src/components/header.js src/components/header.tsx
- mv src/components/layout.js src/components/layout.tsx
- mv src/components/seo.js src/components/seo.tsx
- mv src/pages/index.js src/pages/index.tsx
Estás utilizando el mv
comando para cambiar el nombre de los archivos al segundo argumento. .tsx
es la extensión del archivo, ya que estos archivos usan JSX .
Sin embargo, hay una salvedad importante sobre el gatsby-plugin-typescript
complemento: no incluye la verificación de tipos en el momento de la compilación (una función fundamental de TypeScript). Si usa VS Code, esto no será un problema porque TypeScript es un lenguaje compatible con Visual Studio. Pero si usa otro editor, como Atom , deberá realizar algunas configuraciones adicionales para lograr una experiencia de desarrollo completa con TypeScript.
Dado que Gatsby es un marco basado en React, también se recomienda agregar algún tipado adicional relacionado con React. Para agregar verificación de tipos específicos de React, ejecute el siguiente comando:
- npm add @types/react
Para agregar verificación de tipos para los tipos relacionados con React DOM, use este comando:
- npm add @types/react-dom
Ahora que se ha familiarizado con el complemento gatsby-plugin-typescript
, está listo para configurar su sitio Gatsby para TypeScript en el siguiente paso.
Paso 3: Configuración de TypeScript para Gatsby con el tsconfig.jsonarchivo
En este paso, creará un tsconfig.json
archivo. Un tsconfig.json
archivo tiene dos propósitos principales: establecer el directorio raíz del proyecto TypeScript ( include
) y anular las configuraciones predeterminadas del compilador TypeScript ( compilerOptions
). Hay un par de formas de crear este archivo. Si tiene la tsc
herramienta de línea de comandos instalada con npm, podría crear un nuevo tsconfig
archivo con tsc --init
. Pero el archivo se llenará con muchas opciones y comentarios predeterminados.
En su lugar, cree un nuevo archivo en la raíz de su directorio ( gatsby-typescript-project/
) y nómbrelo tsconfig.json
.
A continuación, cree un objeto con dos propiedades, compilerOptions
y include
, rellenado con el siguiente código:
[label gatsby-typescript-tutorial/tsconfig.json] { "compilerOptions": { "module": "commonjs", "target": "es6", "jsx": "preserve", "lib": ["dom", "es2015", "es2017"], "strict": true, "noEmit": true, "isolatedModules": true, "esModuleInterop": true, "skipLibCheck": true, "noUnusedLocals": true, "noUnusedParameters": true, "removeComments": false }, "include": ["./src/**/*"]}
Nota: Esta configuración se basa parcialmente en el gatsby-starter-typescript-plus
motor de arranque.
Guarde este archivo y ciérrelo cuando haya terminado.
La include
propiedad apunta a una matriz de nombres de archivos o rutas que el compilador sabe convertir de TypeScript a JavaScript.
A continuación se muestra una breve explicación de cada opción utilizada en compilerOptions
:
module
– Establece el sistema de módulos para el proyecto;commonjs
se utiliza de forma predeterminada.target
– Según la versión de JavaScript que estés usando, esta opción determina qué funciones debes reducir y cuáles no. Esto puede resultar útil si tu proyecto se implementa en entornos más antiguos en comparación con entornos más nuevos.jsx
– Configuración de cómo se trata JSX en.tsx
los archivos. Lapreserve
opción deja el JSX sin cambios.lib
– Una matriz de definiciones de tipos específicos de diferentes bibliotecas/API de JS (dom
,es2015
, etc.).strict
– Cuando se establece entrue
, esto habilita las capacidades de verificación de tipos de TypeScript en el momento de la compilación.noEmit
– Dado que Gatsby ya usa Babel para compilar su código en JavaScript legible, cambie esta opción paratrue
dejar TypeScript fuera.isolatedModules
– Al elegir Babel como compilador/transpilador, opta por compilar un archivo a la vez, lo que puede causar posibles problemas en tiempo de ejecución. Si configura esta opción,true
TypeScript le advertirá si está a punto de encontrarse con este problema.esModuleIterop
– Habilitar esta opción le permite usar CommonJS (su conjuntomodule
) y módulos ES (importación y exportación de variables y funciones personalizadas) para trabajar mejor juntos y permitir objetos de espacio de nombres para todas las importaciones.noUnusedLocals
ynoUnusedParamters
– Al habilitar estas dos opciones se deshabilitan los errores que TypeScript normalmente informaría si creara una variable o parámetro local no utilizado.removeComments
– Establecer esto enfalse
(o no establecerlo en absoluto) permite que haya comentarios presentes después de que cualquier archivo TypeScript se haya convertido a JavaScript.
Puede obtener más información sobre estas diferentes opciones y muchas más visitando la guía de referencia de TypeScript para tsconfig
.
Ahora que TypeScript está configurado para Gatsby, vas a completar tu integración con TypeScript refactorizando algunos de tus archivos repetitivos en src/components
y src/pages
.
Paso 4: refactorización seo.tsxpara TypeScript
En este paso, agregará algo de sintaxis de TypeScript al seo.tsx
archivo. Este paso explica en profundidad algunos conceptos de TypeScript; el siguiente paso mostrará cómo refactorizar otro código repetitivo de una manera más abreviada.
Una característica de TypeScript es su flexibilidad con su sintaxis. Si no desea agregar tipificación a sus variables explícitamente, no tiene que hacerlo. Gatsby cree que la adopción de TypeScript en su flujo de trabajo “puede y debe ser gradual”, por lo que este paso se concentrará en tres conceptos básicos de TypeScript:
- tipos básicos
- Definición de tipos e interfaces
- Trabajando con errores en tiempo de compilación
Tipos básicos en TypeScript
TypeScript admite tipos de datos básicos, entre ellos: boolean
, number
, y string
. La principal diferencia sintáctica con TypeScript, en comparación con JavaScript, es que ahora las variables se pueden definir con un tipo asociado.
Por ejemplo, el siguiente bloque de código muestra cómo asignar los tipos básicos con el código resaltado:
let num: number;num = 0let str: string;str = "TypeScript Gatsby"let typeScriptIsAwesome: boolean;typeScriptIsAwesome = true;
En este código, num
debe ser un number
, str
debe ser un string
, y typeScriptIsAwesome
debe ser un boolean
.
Ahora examinará las declaraciones defaultProps
y propTypes
en el seo.tsx
archivo que se encuentra en el src/components
directorio. Abra el archivo en su editor y busque las siguientes líneas resaltadas:
tutorial-de-tipografia-gatsby/src/components/seo.tsx
...import * as React from "react"import PropTypes from "prop-types"import { Helmet } from "react-helmet"import { useStaticQuery, graphql } from "gatsby"... ].concat(meta)} / )}SEO.defaultProps = { lang: `en`, meta: [], description: ``,}SEO.propTypes = { description: PropTypes.string, lang: PropTypes.string, meta: PropTypes.arrayOf(PropTypes.object), title: PropTypes.string.isRequired,}export default SEO
De manera predeterminada, el componente SEO de un sitio de Gatsby viene con un sistema de tipado débil que utiliza PropTypes
. Los defaultProps
y propTypes
se declaran explícitamente, utilizando la PropsTypes
clase importada. Por ejemplo, en la meta
propiedad (o alias ) del propTypes
objeto, su valor es una matriz de objetos, cada uno de los cuales es en sí mismo una propiedad del PropTypes
componente. Algunas propiedades están marcadas como obligatorias ( isRequired
) mientras que otras no, lo que implica que son opcionales.
Dado que está utilizando TypeScript, deberá reemplazar este sistema de tipificación. Continúe y elimine defaultProps
and propTypes
(junto con la import
declaración correspondiente PropTypes
en la parte superior del archivo). Su archivo se verá así:
[label gatsby-typescript-tutorial/src/components/seo.tsx] ...import * as React from "react"import { Helmet } from "react-helmet"import { useStaticQuery, graphql } from "gatsby"... ].concat(meta)} / )}export default SEO
Ahora que ha eliminado la tipificación predeterminada, escribirá los alias de tipo con TypeScript.
Definición de interfaces TypeScript
En TypeScript, se utiliza una interfaz para definir la “forma” de un tipo personalizado. Estas se utilizan para representar el tipo de valor de piezas complejas de datos, como componentes de React y parámetros de funciones. En el seo.tsx
archivo, creará un interface
para reemplazar las definiciones defaultProps
y propTypes
que se eliminaron.
Añade las siguientes líneas resaltadas:
[label gatsby-typescript-tutorial/src/components/seo.tsx] ...import * as React from "react"import { Helmet } from "react-helmet"import { useStaticQuery, graphql } from "gatsby"interface SEOProps { description?: string, lang?: string, meta?: Array{name: string, content: string}, title: string}...
La interfaz SEOProps
logra lo que SEO.propTypes
hizo estableciendo cada una de las propiedades asociadas al tipo de datos y marcando algunas como requeridas con el ?
carácter.
Escribir una función
Al igual que en JavaScript, las funciones desempeñan un papel importante en las aplicaciones TypeScript. Incluso puedes escribir funciones especificando el tipo de datos de los argumentos que se les pasan. En el seo.tsx
archivo, ahora trabajarás en el SEO
componente de función definido. En donde se SEOProps
definió la interfaz for, vas a declarar explícitamente el tipo de los SEO
argumentos de función del componente, junto con un tipo de retorno de SEOProps
justo después:
Añade el siguiente código resaltado:
tutorial-de-tipografia-gatsby/src/components/seo.tsx
...interface SEOProps { description?: string, lang?: string, meta?: Array{name: string, content: string}, title: string}function SEO({ description='', lang='en', meta=[], title }: SEOProps) { ...}
Aquí se establecen valores predeterminados para los SEO
argumentos de la función para que se ajusten a la interfaz y se agrega la interfaz con : SEOProps
. Recuerde que al menos debe incluir title
en la lista de argumentos que se pasan al SEO
componente porque se definió como una propiedad obligatoria en la SEOProps
interfaz que definió anteriormente.
Por último, puedes revisar las declaraciones metaDescription
de defaultTitle
constantes y estableciendo su tipo, que string
en este caso es:
[label gatsby-typescript-tutorial/src/components/seo.tsx] ...function SEO({ description='', lang='en', meta=[], title }: SEOProps) { const { site } = useStaticQuery( graphql` query { site { siteMetadata { title description author } } } ` ) const metaDescription: string = description || site.siteMetadata.description const defaultTitle: string = site.siteMetadata?.title...
Otro tipo en TypeScript es el any
tipo. En situaciones en las que se trabaja con una variable cuyo tipo no está claro o es difícil de definir, se utiliza any
como último recurso para evitar errores en el momento de la compilación.
Un ejemplo de uso del any
tipo es cuando se trabaja con datos obtenidos de un tercero, como una solicitud de API o una consulta GraphQL. En el archivo, donde se define seo.tsx
la propiedad desestructurada con una consulta estática GraphQL, configure su tipo como :site
any
tutorial-de-tipografia-gatsby/src/components/seo.tsx
...interface SEOProps { description?: string, lang?: string, meta?: Array{name: string, content: string}, title: string}function SEO({ description='', lang='en', meta=[], title }: Props) { const { site }: any = useStaticQuery( graphql` query { site { siteMetadata { title description author } } } ` ) ...}
Guardar y salir del archivo.
Es importante mantener siempre la coherencia de los valores definidos con su tipo. De lo contrario, verás que aparecen errores en tiempo de compilación a través del compilador TypeScript.
Errores en el momento de la compilación
Será útil acostumbrarse a los errores que TypeScript detecta y reporta en el momento de la compilación. La idea es que TypeScript detecte estos errores, en su mayoría relacionados con los tipos, en el momento de la compilación, y esto reduce la cantidad de depuración a largo plazo (en el momento de la compilación).
Un ejemplo de un error en tiempo de compilación es cuando declaras una variable de un tipo pero le asignas un valor de otro tipo. Si cambias el valor de uno de los argumentos de palabras clave que se pasan al SEO
componente por uno de un tipo diferente, el compilador de TypeScript detectará la inconsistencia e informará el error. La siguiente es una imagen de cómo se ve esto en VSCode:
El error dice Type 'number' is not assignable to type 'string'
. Esto se debe a que, cuando configuraste tu interface
, dijiste que la description
propiedad sería del tipo string
. El valor 0
es del tipo number
. Si cambias el valor de description
nuevo a una “cadena”, el mensaje de error desaparecerá.
Paso 5: Refactorización del resto del código repetitivo
Por último, refactorizará los archivos repetitivos restantes con TypeScript: layout.tsx
y header.tsx
. Al igual que seo.tsx
, estos archivos de componentes se encuentran en el src/components
directorio.
Abra src/components/layout.tsx
. Hacia la parte inferior, se encuentra el Layout.propTypes
. Elimine las siguientes líneas resaltadas:
[label gatsby-typescript-tutorial/src/components/layout.tsx] /** * Layout component that queries for data * with Gatsby's useStaticQuery component * * See: https://www.gatsbyjs.com/docs/use-static-query/ */import * as React from "react"import PropTypes from "prop-types"import { useStaticQuery, graphql } from "gatsby"...Layout.propTypes = { children: PropTypes.node.isRequired,}export default Layout
La children
propiedad muestra que su valor es del tipo node
de la PropTypes
clase. Además, es una propiedad obligatoria. Dado que children
en el diseño puede haber cualquier cosa, desde texto simple hasta componentes secundarios de React, utilícela ReactNode
como el tipo asociado importándola cerca de la parte superior y agregándola a la interfaz:
Añade las siguientes líneas resaltadas:
tutorial-de-tipografia-gatsby/src/componentes/diseño.tsx
...import * as React from "react"import { useStaticQuery, graphql } from "gatsby"import Header from "./header"import "./layout.css"interface LayoutProps { children: ReactNode}const Layout = ({ children }: LayoutProps) = { ...
A continuación, agregue un tipo a la data
variable que almacena una consulta GraphQL que obtiene datos del título del sitio. Dado que este objeto de consulta proviene de una entidad de terceros como GraphQL, proporcione data
un any
tipo. Por último, agregue el string
tipo a la siteTitle
variable que trabaja con esos datos:
[label gatsby-typescript-tutorial/src/components/layout.tsx] ...const Layout = ({ children }: LayoutProps) = { const data: any = useStaticQuery(graphql` query MyQuery { site { siteMetadata { title } } }`)const siteTitle: string = data.site.siteMetadata?.title || `Title` return ( Header siteTitle={siteTitle} / div...
Guarde y cierre el archivo.
Ahora abre el src/components/header.tsx
archivo. Este archivo también incluye tipos de propiedades predefinidos, utilizando la PropTypes
clase. Como seo.tsx
y layout.tsx
, reemplaza Header.defaultProps
y Header.propTypes
por un interface
utilizando los mismos nombres de propiedades:
tutorial-de-tipografia-gatsby/src/componentes/header.tsx
import * as React from "react"import { Link } from "gatsby"interface HeaderProps { siteTitle: string}const Header = ({ siteTitle }: HeaderProps) = ( header style={{ background: `rebeccapurple`, marginBottom: `1.45rem`, }} div style={{ margin: `0 auto`, maxWidth: 960, padding: `1.45rem 1.0875rem`, }} h1 style={{ margin: 0 }} Link to="/" style={{ color: `white`, textDecoration: `none`, }} {siteTitle} /Link /h1 /div /header)export default Header
Guarde y cierre el archivo.
Una vez que hayas refactorizado tus archivos para TypeScript, puedes reiniciar el servidor para asegurarte de que todo funciona. Ejecuta el siguiente comando:
- gatsby develop
Cuando navega a localhost:8000
, su navegador mostrará lo siguiente:
Conclusión
Las capacidades de tipado estático de TypeScript ayudan mucho a mantener la depuración al mínimo. También es un lenguaje excelente para los sitios de Gatsby, ya que se admite de forma predeterminada. Gatsby en sí mismo es una herramienta de interfaz útil para crear sitios estáticos, como páginas de destino.
Ahora tienes dos herramientas populares a tu disposición. Para obtener más información sobre TypeScript y todo lo que puedes hacer con él, visita nuestra serie Cómo codificar en TypeScript .
Deja una respuesta