Curso de React.js 2017

Toma las primeras clases gratis

COMPARTE ESTE ARTÍCULO Y MUESTRA LO QUE APRENDISTE

He visto a muchos preguntar como hacer extensiones para Chrome en la comunidad de Platzi, así que decide hacer este tutorial para poder explicar al detalle como crear, probar y publicar tu propia extension.

Que vamos a crear

Crearemos una simple extension que nos muestre una frase diaria utilizando una API.

Requisitos previos

Tener node y npm instalados

Que tecnologías usaremos

Estructura del proyecto

Esta sera la estructura a seguir.

app

Primeros pasos

Manos a la obra!

1. manifest.json

Lo principal para crear una extension es un archivo manifest.json que contendrá información basica, como el nombre y la descripcion de la extension.

{
  "manifest_version": 2,
  "name": "Platzi Quote of Day",
  "description": "Platzi Quote of Day extension",
  "version": "1.0.0",
  "icons": {
    "16": "./icons/icon.png",
    "48": "./icons/icon_48.png",
    "128": "./icons/icon_128.png"
  },
  "browser_action": {
    "default_icon": "./icons/icon.png",
    "default_popup": "./index.html"
  },
  "permissions": [
    "activeTab",
    "tabs"
  ],
  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*"],
      "js": ["./build/index.js"]
    }
  ]
}

Como podras ver hay iconos de 3 tamaños diferentes 16x16, 48x48 y 128x128 esto es debido a que son los requeridos por Chrome, puedes utilizar Resize Image para agregar tus propios iconos.

2. index.html

Crea la primera vista en un archivo index.html, en esta se debe indicar un tamaño adecuado al body debido a que este sera el tamaño del modal que tendrá la extension.

<!doctype html>
<html>

<head>
  <title>Platzi Quote of Day</title>
  <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css">
  <style>
    body,
    html {
      font-family: 'Open Sans', sans-serif;
      font-size: 14px;
      margin: 0;
      min-height: 180px;
      padding: 0;
      width: 384px;
    }

    h1 {
      font-family: 'Menlo', monospace;
      font-size: 22px;
      font-weight: 400;
      margin: 0;
      color: #188287;
    }

    img {
      width: 30px;
    }

    .modal-header {
      align-items: center;
      border-bottom: .5px solid #dadada;
    }

    .modal-content {
      padding: 0 22px;
    }

    .modal-buttons {
      border-top: .5px solid #dadada;
      height: 50px;
      width: 100%;
    }

    .logo {
      padding: 16px;
    }

    .logo-icon {
      vertical-align: text-bottom;
      margin-right: 12px;
    }

    .flex-container {
      display: flex;
      justify-content: space-between;
      padding: 22px 22px;
    }

    .btn {
      padding: 8px;
      text-align: center;
      color: white;
      border-radius: 5px;
      background: #188287;
      text-decoration: none;
      display: inline-block;
      cursor: pointer;
      width: 65px;
    }
  </style>
</head>

<body>
  <!-- Contenido temporal -->
  <div class="modal-header">
    Header
  </div>
  <div class="modal-content">
    Contenido
  </div>
  <div class="modal-buttons">
    <div class="flex-container">
      <a class="btn">
        Test
      </a>
    </div>
  </div>
  <!-- Fin contenido temporal -->
  <!-- Div donde se creara los componentes  -->
  <div id="quote-of-day-extension"></div>
  <!-- Script que trabajaremos luego -->
  <script src="./build/index.js"></script>
</body>

</html>

3. Extension en desarrollo

Para probar la extension se debe ir a chrome://extensions y habilitar el modo programador luego con la opción “cargar extension sin empaquetar” selecciona la carpeta del proyecto, una vez terminado podrás ver la extension en la barra de Chrome.

test app

Agregando React y Parcel

Primero se debe iniciar el proyecto con npm e instalar Parcel de manera global.

npm init -y

npm i -g parcel-bundler

Ahora se deben instalar las dependencias.

npm i -S react react-dom

npm i -S -D babel-preset-react babel-core babel-preset-env babel-plugin-transform-runtime babel-plugin-transform-class-properties

Como muchos sabrán Babel nos permite utilizar la ultima version de ES y transpila el código de manera que sea compatible con el navegado, para ello necesitaremos un archivo .babelrc con el siguiente.

{
  "presets": ["env", "react"],
  "plugins": [
    "transform-class-properties",
    "transform-runtime"
  ]
}

En orden de construir el código se deben agregar los siguientes scripts al package.json

"scripts": {
    "watch": "parcel watch src/index.js -d build/ -o index.js --no-source-maps",
    "build": "parcel build src/index.js -d build/ -o index.js --no-source-maps"
 }

Parcel crea un hash para los nombres de los archivos al compilarse (Ej. src.147rsafa55a4fa.js) por lo tanto se debe indicar el output y destino en el que se generara -d build/ -o index.js.

El comando watch estará al tanto de cambios en el código y generara un nuevo build para este y el comando build dejara el código listo para producción.

Creando los componentes

Para comenzar se debe eliminar el contenido temporal en el index.html.

1. src/components/Header.js

Header sera el encabezado de la extension, tendrá un logo, el nombre de la extension y la categoría de la frase a mostrar.

import React from 'react'

export default function Header({ category }) {
  return (
    <h1 className="logo">
      <img className="logo-icon" src='../icons/icon_128.png' />
      Quote of Day - {category}
    </h1>
  )
}

2. src/components/Content.js

En este componente se mostrara la frase y su autor.

import React, { Fragment } from 'react'

export default function Content({ quote, author }) {
  return (
    <Fragment>
      <p> { quote } </p>
      <p> - { author } </p>
    </Fragment>
  )
}

3. src/components/Buttons.js

Estos botones serán las categorías y la parte inferior de la extension, recibirán una función la cual hará la petición a la API.

import React from 'react'

export default function Buttons({ click }) {
  return (
    <div className="flex-container">
      <a className="btn" onClick={() => click('inspire')}>
        Inspire
      </a>
      <a className="btn" onClick={() => click('students')}>
        Students
      </a>
      <a className="btn" onClick={() => click('life')}>
        Life
      </a>
      <a className="btn" onClick={() => click('management')}>
        Manage
      </a>
    </div>
  )
}

4. src/App.js

App contendrá toda la lógica de la extension, aquí se hará uso de los componentes anteriores y la API de la cual obtendremos las frases diarias.

import React, { Component, Fragment } from 'react'
import Header from './components/Header'
import Content from './components/Content'
import Buttons from './components/Buttons'

class App extends Component {
  state = {
    quote: 'Content',
    author: '',
    category: ''
  }

  componentDidMount() {
    this.getQuote()
  }

  getQuote = async (category='inspire') => {
    try {
      const url = `https://quotes.rest/qod.json?category=${category}`
      const data = await fetch(url).then(res => res.json())
      const content = data.contents.quotes[0]

      this.setState({
        category,
        quote: content.quote,
        author: content.author
      })
    } catch (error) {
      this.setState({
        quote: error.message
      })
    }
  }

  render () {
    const { quote, author, category } = this.state
    return (
      <Fragment>
        <div className="modal-header">
          <Header category={category} />
        </div>
        <div className="modal-content">
          <Content quote={quote} author={author} />
        </div>
        <div className="modal-buttons">
          <Buttons click={this.getQuote} />
        </div>
      </Fragment>
    )
  }
}

export default App

5. src/index.js

Por ultimo solo queda hacer render de App en la vista

import React from 'react'
import ReactDOM from 'react-dom'

import App from './App'

ReactDOM.render(<App />, document.getElementById('platzi-quote-of-day-extension'))

6. Test

Crea la app para producción con npm run build y recarga la extension en el panel de chrome 🔄 y tendrás tu extension terminada.

app

Ahora estas listo para publicar tu extension 🔥🔥🔥

1. ZIP

Crea un zip de con los archivos necesarios.

build/*
icons/*
index.html
manifest.json

2. Publicar

Ve al developer dashboard de google > Add new item (Añadir nuevo elemento) y selecciona el Zip que acabas de crear, ahora solo debes seguir los pasos para publicar tu extension, Información adicional.

Puedes ver todo el cogido en GitHub

Si aun tienes dudas deja tu comentario y sera un placer ayudarte!

Personal Info:
GitHub
Twitter

Curso de React.js 2017

Toma las primeras clases gratis

COMPARTE ESTE ARTÍCULO Y MUESTRA LO QUE APRENDISTE

0 Comentarios

para escribir tu comentario

Artículos relacionados