diff --git a/CHANGELOG.md b/CHANGELOG.md
index e6590a81..c6fd6825 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,18 +1,30 @@
# Change Log
-## V2 (currently v2.4.3)
+## v2.4.5
+
+- Add `babel-plugin-flow-react-proptypes`.
+- Add `eslint-plugin-compat`.
+- Add JSS `composes` example.
+
+## v2.4.4
+
+- Update Immutable to remove the `import * as Immutable from 'immutable'` syntax.
+- Declare Flow types outside of function params for React components.
+- Improve Webpack `publicPath`.
+
+## V2, up to v2.4.3
- Gulp is gone, replaced by NPM (Yarn) scripts.
- Express has been added, with template strings for static HTML. Gzip compression enabled.
- Support for development environment with Nodemon and production environment with PM2.
- Minification or sourcemaps depending on the environment via Webpack.
-- Webpack Dev Server added, with Hot Module Replacement and `react-hot-loader`.
-- Added an asynchronous call example with `redux-thunk`.
+- Add Webpack Dev Server, with Hot Module Replacement and `react-hot-loader`.
+- Add an asynchronous call example with `redux-thunk`.
- Linting / type checking / testing is not launched at every file change anymore, but triggered by Git Hooks via Husky.
- Some chapters have been combined to make it easier to maintain the tutorial.
-- Replaced Chai and Mocha by Jest.
-- Added React-Router, Server-Side rendering, `react-helmet`.
-- Renamed all "dog" things and replaced it by "hello" things. It's a Hello World app after all.
-- Added Twitter Bootstrap, JSS, and `react-jss` for styling.
-- Added a Websocket example with Socket.IO.
-- Added optional Heroku, Travis, and Coveralls integrations.
+- Replace Chai and Mocha by Jest.
+- Add React-Router, Server-Side rendering, `react-helmet`.
+- Rename all "dog" things and replaced it by "hello" things. It's a Hello World app after all.
+- Add Twitter Bootstrap, JSS, and `react-jss` for styling.
+- Add a Websocket example with Socket.IO.
+- Add optional Heroku, Travis, and Coveralls integrations.
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 00000000..8095afd2
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,21 @@
+# MIT License
+
+Copyright (c) 2017 Jonathan Verrecchia
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index 1b2397da..15950eb8 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Stack JavaScript desde Cero
+# Stack JavaScript desde cero
[![Build Status](https://travis-ci.org/verekia/js-stack-from-scratch.svg?branch=master)](https://travis-ci.org/verekia/js-stack-from-scratch)
[![Release](https://img.shields.io/github/release/verekia/js-stack-from-scratch.svg?style=flat-square)](https://github.com/verekia/js-stack-from-scratch/releases)
@@ -18,21 +18,21 @@
Bienvenido a mi tutorial (@verekia) sobre el stack javascript: ** Stack Javascript desde Cero**.
-> 馃帀 **Esta es la V2 del tutorial, con grandes cambios desde la edici贸n de 2016. Puede ver la [Lista de Cambios](/CHANGELOG.md)!**
+> 馃帀 **Esta es la V2 del tutorial, con grandes cambios desde la edici贸n de 2016. Puedes ver la [Lista de Cambios](/CHANGELOG.md)!**
-Esta es una gu铆a orientada a ensamblar un stack JavaScript. Requiere algunos conocimientos de programaci贸n general, y b谩sicos de JavaScript. **Se centra en herramientas que abordaremos juntos** y ofreciendole el **ejemplo m谩s simple posible** para cada herramientas. Puede ver este tutorial como *una manera de escribir su propia boilerplate desde cero*. Debido a que, el objetivo de este tutorial es ensamblar varias herramientas, no voy a entrar en detalles sobre como cada una trabaja individualmente. Consulte su documentaci贸n o encuentre otros tutoriales si desea adquirir un conocimiento m谩s profundo en ellos.
+Esta es una gu铆a orientada directamente a ensamblar un stack JavaScript. Requieres de algunos conocimientos generales de programaci贸n, y conceptos b谩sicos de JavaScript. **Se centra en acoplar varias herramientas** y ofrecerle el **ejemplo m谩s simple posible** para cada herramienta. Puedes ver este tutorial como *una manera de escribir tu propia boilerplate desde cero*. Debido a que el objetivo de este tutorial es ensamblar varias herramientas, no voy a entrar en detalles sobre como funciona cada una individualmente. Consulta la documentaci贸n o encuentra otros tutoriales si deseas adquirir un conocimiento m谩s profundo en estas.
-No necesita usar este stack entero si va a construir una simple p谩gina web con una pocas interacciones de JS interactions obviamente (una combinaci贸n de Browserify/Webpack + Babel + jQuery es suficiente para poder escribir c贸digo ES6 en archivos diferentes), pero si quieres crear una aplicaci贸n web que sea escalable, y necesitas ayuda para configurar las cosas, este tutorial ser谩 muy bueno para ti.
+No necesitas usar este stack entero si vas a construir una simple p谩gina web con pocas interacciones de JS (una combinaci贸n de Browserify/Webpack + Babel + jQuery es suficiente para poder escribir c贸digo ES6 en archivos diferentes), pero si quieres crear una aplicaci贸n web que sea escalable, y necesitas ayuda para configurar las cosas, este tutorial ser谩 muy bueno para ti.
-Una gran parte de lo descrito en este tutorial usa React. Si estas comenzando y quieres aprender React, [create-react-app](https://github.com/facebookincubator/create-react-app) le permitir谩 levantar y correr r谩pidamente un entorno de React ya preconfigurado. Recomiendo este enfoque para quien se este incorporando a un equipo que este usando React y necesite ponerse al d铆a con un ambiente de pruebas. En este tutorial no lo usaremos, porque quiero que entienda lo que esta sucede debajo de todo.
+Una gran parte de lo descrito en este tutorial usa React. Si estas comenzando y s贸lo quieres aprender React, [create-react-app](https://github.com/facebookincubator/create-react-app) te permitir谩 levantar y ejecutar r谩pidamente un entorno de React ya preconfigurado. Recomiendo este enfoque para quien se est茅 incorporando a un equipo que utilice React y necesite ponerse al d铆a con un ambiente de pruebas. En este tutorial no utilizaremos React preconfigurado, porque quiero que entiendas todo lo que hay detr谩s de su funcionamiento.
-Los c贸digos de ejemplos estan disponibles en cada cap铆tulo, puedes correlos todos usando `yarn && yarn start`. Sin embargo, recomiendo que escriba todo desde cero siguiendo las **instrucciones paso a paso**.
+Los c贸digos de los ejemplos estan disponibles en cada cap铆tulo, puedes ejecutarlos usando `yarn && yarn start`. Sin embargo, te recomiendo que escribas todo desde cero siguiendo las **instrucciones paso a paso**.
-El c贸digo final esta disponible en el [repositorio JS-Stack-Boilerplate](https://github.com/verekia/js-stack-boilerplate), en el [releases](https://github.com/verekia/js-stack-from-scratch/releases). As铆 como tambi茅n un [demo en vivo](https://js-stack.herokuapp.com/).
+El c贸digo final esta disponible en el [repositorio JS-Stack-Boilerplate](https://github.com/verekia/js-stack-boilerplate), en [releases](https://github.com/verekia/js-stack-from-scratch/releases). As铆 como tambi茅n un [demo en vivo](https://js-stack.herokuapp.com/).
Funciona en Linux, macOS, y Windows.
-## Tabla de Contenidos
+## Tabla de contenidos
[01 - Node, Yarn, `package.json`](/tutorial/01-node-yarn-package-json.md#readme)
@@ -52,9 +52,9 @@ Funciona en Linux, macOS, y Windows.
[09 - Travis, Coveralls, Heroku](/tutorial/09-travis-coveralls-heroku.md#readme)
-## Proximamente
+## Pr贸ximamente
-Configurando tu editor (Atom), MongoDB, Progressive Web App.
+Configura tu editor (Atom), MongoDB, Progressive Web App.
## Traducciones
diff --git a/how-to-translate.md b/how-to-translate.md
index d2ef5fb1..5ce1c92e 100644
--- a/how-to-translate.md
+++ b/how-to-translate.md
@@ -35,7 +35,7 @@ Since I want to reward you for your good work as much as possible, you can put a
- After your original one-shot translation, if you want to update your repo with the latest change from the main English repo, [sync your fork](https://help.github.com/articles/syncing-a-fork/) with my repo. To make it easy to see what changed since your initial translation, you can use Github's feature to [compare commits](https://help.github.com/articles/comparing-commits-across-time/#comparing-commits). Set the **base** to the last commit from the English repo you used to translate, and compare it to **master**, like so:
-https://github.com/verekia/js-stack-from-scratch/compare/9b3852fcdf8f3000e7513abfcb26e0e58b33b230...master
+https://github.com/verekia/js-stack-from-scratch/compare/c65dfa65d02c21063d94f0955de90947ba5273ad...master
That should give you a easy-to-read diff to see exactly what changed in `README.md` files since your translation!
diff --git a/img/jest-padded-90.png b/img/jest-padded-90.png
index f1aacf78..1f942a87 100644
Binary files a/img/jest-padded-90.png and b/img/jest-padded-90.png differ
diff --git a/img/jest-padded.png b/img/jest-padded.png
index 9e39cba8..ff62dd02 100644
Binary files a/img/jest-padded.png and b/img/jest-padded.png differ
diff --git a/img/jest.png b/img/jest.png
index dffb7fbc..3923b0bc 100644
Binary files a/img/jest.png and b/img/jest.png differ
diff --git a/package.json b/package.json
index 41453e8e..1571271a 100644
--- a/package.json
+++ b/package.json
@@ -1,13 +1,13 @@
{
"name": "js-stack-from-scratch",
- "version": "2.4.3",
+ "version": "2.4.5",
"description": "JavaScript Stack from Scratch - Step-by-step tutorial to build a modern JavaScript stack",
"scripts": {
"test": "node mdlint.js"
},
"devDependencies": {
"glob": "^7.1.1",
- "markdownlint": "^0.3.0"
+ "markdownlint": "^0.4.0"
},
"repository": "verekia/js-stack-from-scratch",
"author": "Jonathan Verrecchia - @verekia",
diff --git a/tutorial/01-node-yarn-package-json.md b/tutorial/01-node-yarn-package-json.md
index cc562bd2..ab4d3375 100644
--- a/tutorial/01-node-yarn-package-json.md
+++ b/tutorial/01-node-yarn-package-json.md
@@ -2,38 +2,38 @@
El c贸digo para este cap铆tulo esta disponible [aqu铆](https://github.com/verekia/js-stack-walkthrough/tree/master/01-node-yarn-package-json).
-en esta secci贸n configuraremos Node, Yarn, un archivo `package.json` b谩sico y probaremos un paquete.
+En esta secci贸n configuraremos Node, Yarn, un archivo `package.json` b谩sico y probaremos un paquete.
## Node
-> 馃挕 **[Node.js](https://nodejs.org/)** es un entorno de ejecuci贸n Javascript. Es mayormente usado para desarrollo Back-End, pero tambi茅n para scripting en general. En el contexto de desarrollo Front-End, puede ser usado para realizar una gran cantidad de tareas como linting, pruebas y ensamblamiento de archivos.
+> 馃挕 **[Node.js](https://nodejs.org/es/)** es un entorno de ejecuci贸n para Javascript. Es mayormente usado para desarrollo Back-End, pero tambi茅n para scripting en general. En el contexto de desarrollo Front-End, puede ser usado para realizar una gran cantidad de tareas como linting, pruebas y ensamblamiento de archivos.
-Usaremos Nodo a lo largo de este tutorial, por tanto va a necesitarlo. Dir铆jase a la [p谩gina de descarga](https://nodejs.org/en/download/current/) para los binarios de **macOS** o **Windows**, o la [p谩gina de instalaci贸n de manejador de paquetes](https://nodejs.org/en/download/package-manager/) para su distribuciones Linux.
+Usaremos Node b谩sicamente para todo a lo largo de este tutorial, por tanto vas a necesitarlo. Dir铆gete a la [p谩gina de descargas](https://nodejs.org/es/download/current/) para obtener los binarios para **macOS** o **Windows**, o a la [p谩gina de instalaci贸n mediante manejador de paquetes](https://nodejs.org/es/download/package-manager/) para distribuciones Linux.
-Por ejemplo, en **Ubuntu / Debian**, correr铆a el siguiente comando para instalar Node:
+Por ejemplo, en **Ubuntu / Debian**, ejecutar铆as los siguientes comandos para instalar Node:
```sh
curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
sudo apt-get install -y nodejs
```
-Si desea cualquier versi贸n de Node > 6.5.0.
+Si deseas cualquier versi贸n de Node > 6.5.0.
-## NVM
+## Herramientas para gestionar distintas versiones de Node
-Si Node esta ya instalado, o si desea m谩s flexibilidad, instale NVM ([Node Version Manager](https://github.com/creationix/nvm)), y gracias a NVM instale y use la versi贸n m谩s reciente de Node.
+Si necesitas flexibilidad para utilizar m煤ltiples versiones de Node, checa [Node Version Manager](https://github.com/creationix/nvm), o [tj/n](https://github.com/tj/n).
## NPM
-NPM es el manejador de paquetes por defecto de Node. El cual se instala automaticametne con Node. Los manejadores de paquetes son usados para instalar y manejar paquetes (modulos del c贸digo que t煤 o alguien m谩s escribi贸). Vamos a usar un mont贸n de paquetes en este tutorial, pero usaremos Yarn, otro manejador de paquetes.
+NPM es el manejador de paquetes por defecto de Node. El cual se instala autom谩ticamente con Node. Los manejadores de paquetes son usados para instalar y manejar paquetes (m贸dulos de c贸digo que t煤 o alguien m谩s escribi贸). Vamos a usar un mont贸n de paquetes en este tutorial, pero usaremos Yarn, otro manejador de paquetes.
## Yarn
> 馃挕 **[Yarn](https://yarnpkg.com/)** es un manejador de paquetes de Node.js que destaca por ser m谩s r谩pido que NPM, tiene soporte offline y obtiene dependencias [m谩s previsiblemente](https://yarnpkg.com/en/docs/yarn-lock).
-Desde su [llegada](https://code.facebook.com/posts/1840075619545360) en Octubre de 2016, ha recivido una r谩pida adopci贸n y en poco tiempo se convirti贸 en el manejador de paquetes por preferencia de la comunidad JavaScript. Si desea en cambio usar NPM puede simplemente reemplazar todos los comandos `yarn add` y `yarn add --dev` de este tutorial por `npm install --save` y `npm install --save-dev`.
+Desde su [llegada](https://code.facebook.com/posts/1840075619545360) en Octubre de 2016, se ha adoptado r谩pidamente y en poco tiempo se convirti贸 en el manejador de paquetes preferido en la comunidad JavaScript. Si deseas en cambio usar NPM puedes simplemente reemplazar todos los comandos `yarn add` y `yarn add --dev` de este tutorial, por `npm install --save` y `npm install --save-dev`.
-Puede instalar Yarn con las siguientes [instrucciones](https://yarnpkg.com/en/docs/install) para tu Sistema Operativp. Recomiendo usar el **Script de instalaci贸n** desde la tab de *Alternativas* si esta usando macOS o Unix, para [evitar](https://github.com/yarnpkg/yarn/issues/1505) confiar en otros manejadores de paquetes:
+Puede instalar Yarn con las siguientes [instrucciones](https://yarnpkg.com/en/docs/install) para tu sistema operativo. Recomiendo usar el **script de instalaci贸n** desde la pesta帽a *Alternatives* si estas usando macOS o Unix, para [evitar](https://github.com/yarnpkg/yarn/issues/1505) confiar en otros manejadores de paquetes:
```sh
curl -o- -L https://yarnpkg.com/install.sh | bash
@@ -41,12 +41,12 @@ curl -o- -L https://yarnpkg.com/install.sh | bash
## `package.json`
-> 馃挕 **[package.json](https://yarnpkg.com/en/docs/package-json)** es el archivo usado para describir y configurar tu proyecto JavaScript. Contiene informaci贸n general (nombre del proyecto, versi贸n, contribuidores, licencia, entre otros), opciones de configuraci贸n para las herramientas que use e incluso una secci贸n para correr *tareas*.
+> 馃挕 **[package.json](https://yarnpkg.com/en/docs/package-json)** es el archivo usado para describir y configurar tu proyecto JavaScript. Contiene informaci贸n general (nombre del proyecto, versi贸n, contribuidores, licencia, entre otros), opciones de configuraci贸n para las herramientas que uses e incluso una secci贸n para ejecutar *tareas*.
-- Cree una nueva carpeta para trabajar, y entre en ella con `cd`.
-- Corra `yarn init` y responda las preguntas (`yarn init -y` para saltarse todas las preguntas), para generar un archivo `package.json` automaticamente.
+- Crea un nuevo directorio para trabajar, y entra en este con `cd`.
+- Ejecuta `yarn init` y responde las preguntas (`yarn init -y` permite saltarse todas las preguntas), para generar un archivo `package.json` autom谩ticamente.
-Aqu铆 puede ver un `package.json` b谩sico que usaremos en este tutorial:
+Aqu铆 puedes ver un `package.json` b谩sico que usaremos en este tutorial:
```json
{
@@ -60,13 +60,13 @@ Aqu铆 puede ver un `package.json` b谩sico que usaremos en este tutorial:
- Crea un archivo `index.js` que contenga `console.log('Hello world')`
-馃弫 Corre `node .` en esta carpeta (`index.js` es el archivo que Node buscar谩 por defecto dentro de la carpeta). Deber铆a imprimir "Hello world".
+馃弫 Ejecuta `node .` en esta carpeta (`index.js` es el archivo que Node buscar谩 por defecto dentro del directorio). Deber谩 imprimir "Hello world".
-**Nota**: ves es emoji de bandera de carrera 馃弫? Lo usar茅 cada vez que llegues a un **punto de control**. Algunas veces vamos a hacer muchos cambios en algunas lineas y su c贸digo no funcionar谩 hasta llegar al siguiente punto de control.
+**Nota**: ves este emoji de bandera de carrera 馃弫? Lo usar茅 cada vez que llegues a un **punto de control**. Algunas veces vamos a hacer muchos cambios en algunas lineas y tu c贸digo no funcionar谩 hasta llegar al siguiente punto de control.
## Script `start`
-Usar `node .` para ejecutar nuestro programa es ir a muy bajo-nivel. Vamos a usar una script NPM/Yarn en su lugar para disparar la ejecuci贸n del c贸digo. Esto nos brindar谩 una buena abstraci贸n para poder siempre usar `yarn start`, aun cuando nuestro programa se vuelva mas complejo.
+Usar `node .` para ejecutar nuestro programa es ir a muy bajo-nivel. Vamos a usar un script NPM/Yarn en su lugar para disparar la ejecuci贸n del c贸digo. Esto nos brindar谩 una buena abstraci贸n para poder usar siempre `yarn start`, aun cuando nuestro programa se vuelva mas complejo.
- En `package.json`, agrega un objeto `scripts` de la siguiente forma:
@@ -81,11 +81,11 @@ Usar `node .` para ejecutar nuestro programa es ir a muy bajo-nivel. Vamos a usa
}
```
-`start` es el nombre que le daemos a la *tarea* que correr nuestro programa. Vamos a crear un mont贸n de diferentes tareas en este objeto `scripts` a lo largo de este tutorial. `start` es tipicamente el nombre que le damos a la tarea por defecto de una aplicaci贸n. Algunas otras tareas estandard son llamadas `stop` y `test`.
+`start` es el nombre que le daremos a la *tarea* que ejecutar谩 nuestro programa. Vamos a crear un mont贸n de diferentes tareas en este objeto `scripts` a lo largo de este tutorial. `start` es tipicamente el nombre que le damos a la tarea por defecto de una aplicaci贸n. Algunas otras tareas est谩ndar son `stop` y `test`.
-`package.json` debe ser un archivo JSON valido, lo cual significa que no puede tener comillas. Tenga mucho cuidado cuando edite manualmente tu archivo `package.json`.
+`package.json` debe ser un archivo JSON valido, lo cual significa que no puede tener comas finales. Ten mucho cuidado cuando edites manualmente tu archivo `package.json`.
-馃弫 Corre `yarn start`. Deber铆a imprimir `Hello world`.
+馃弫 Ejecuta `yarn start`. Debe `Hello world`.
## Git y `.gitignore`
@@ -98,25 +98,25 @@ Usar `node .` para ejecutar nuestro programa es ir a muy bajo-nivel. Vamos a usa
/*.log
```
-Los archivos `.DS_Store` son auto-generados en macOS que nunca deberias tener dentro de tu repositorio.
+Los archivos `.DS_Store` son auto-generados en macOS, que nunca deberias tener dentro de tu repositorio.
`npm-debug.log` y `yarn-error.log` son archivos que son creados cuando tu manejador de paquetes encuentra un error, no queremos que esten versionados en nuestro repositorio.
-## Instalando y udando un paquete
+## Instalando y usando un paquete
-En esta secci贸n intalaremos y usaremos un paquete. Un "paquete" es simplemente una pieza de c贸digo que alguien mas escribi贸 y puede ser usado en tu propio c贸digo. Pueden ser cualquier cosa. Aqu铆, vamos a probar un paquete que le ayudar谩 a manipular los colores por ejemplo.
+En esta secci贸n instalaremos y usaremos un paquete. Un "paquete" es simplemente una pieza de c贸digo que alguien mas escribi贸 y puede ser usado en tu propio c贸digo. Puede ser cualquier cosa. Aqu铆 por ejemplo, vamos a probar un paquete que te ayudar谩 a manipular colores.
- Instala el paquete hecho por la comunidad llamado `color` usando `yarn add color`
-Abre `package.json` y veras como Yarn automaticamente a帽adi贸 `color` en `dependencies`.
+Abre `package.json` y veras como Yarn automaticamente a帽adi贸 `color` en `dependencies`.
Una carpeta `node_modules` ha sido creada para almacenar los paquetes.
- Agrega `node_modules/` a tu `.gitignore`
-Tambi茅n notar谩 que un archivo `yarn.lock` fue generado por Yarn. Deber铆as agregar de este archivo a tu repositorio, con esto te aseguras que todo en tu equipo usen la misma versi贸n que tus paquetes. Si estas usando NPM en vez de Yarn, el equivalente de este archivo es el *shrinkwrap*.
+Tambi茅n notar谩s que un archivo `yarn.lock` fue generado por Yarn. Deberas agregar este archivo a tu repositorio, con esto te aseguras que todo en tu equipo usen la misma versi贸n que tus paquetes. Si estas usando NPM en vez de Yarn, el equivalente de este archivo es el *shrinkwrap*.
-- Escribe los siguiente en tu archivo `index.js`:
+- Escribe lo siguiente en tu archivo `index.js`:
```js
const color = require('color')
@@ -126,22 +126,22 @@ const redHexa = color({ r: 255, g: 0, b: 0 }).hex()
console.log(redHexa)
```
-馃弫 Correo `yarn start`. Deber铆a imprimir `#FF0000`.
+馃弫 Ejecuta `yarn start`. Deber谩 imprimir `#FF0000`.
-隆Felicitaciones, instal贸 y uso un paquete!
+隆Felicitaciones, instalaste y usaste un paquete!
-`color` es usado en esta secci贸n para ense帽arle como usar un simple paquete. No lo necesitaremos mas, as铆 que puedes desintalarlo:
+`color` es usado en esta secci贸n para ense帽arte como usar un simple paquete. No lo necesitaremos mas, as铆 que puedes desintalarlo:
-- Usa `yarn remove color`
+- Ejecuta `yarn remove color`
## Dos tipos de dependecias
-Hay dos tipo sde dependencias de paquetes, `"dependencies"` y `"devDependencies"`:
+Hay dos tipos de dependencias de paquetes, `"dependencies"` y `"devDependencies"`:
-**Dependencias** son librerias que necesita tu aplicaci贸n para funcionar (React, Redux, Lodash, jQuery, etc). Las instala usando `yarn add [paquete]`.
+**Dependencias** son librerias que necesita tu aplicaci贸n para funcionar (React, Redux, Lodash, jQuery, etc). Se instalan usando `yarn add [paquete]`.
-**Dependencias De Desarrollo** son libreias usadas durante el desarrollo o para contruir tu aplicaci贸n (Webpack, SASS, linters, frameworks de pruebas, etc). La instala usando `yarn add --dev [paquete]`.
+**Dependencias De Desarrollo** son librer铆as usadas durante el desarrollo o contruci贸n de tu aplicaci贸n (Webpack, SASS, linters, frameworks de pruebas, etc). Se instalan usando `yarn add --dev [paquete]`.
-Siguiente Secci贸n: [02 - Babel, ES6, ESLint, Flow, Jest, Husky](02-babel-es6-eslint-flow-jest-husky.md#readme)
+Siguiente secci贸n: [02 - Babel, ES6, ESLint, Flow, Jest, Husky](02-babel-es6-eslint-flow-jest-husky.md#readme)
-Volver a la [tabla de contenidos](https://github.com/JMEspiz/js-stack-from-scratch#table-of-contents).
\ No newline at end of file
+Volver a la [tabla de contenidos](https://github.com/JMEspiz/js-stack-from-scratch#table-of-contents).
diff --git a/tutorial/02-babel-es6-eslint-flow-jest-husky.md b/tutorial/02-babel-es6-eslint-flow-jest-husky.md
index 97ede2cb..77aea17f 100644
--- a/tutorial/02-babel-es6-eslint-flow-jest-husky.md
+++ b/tutorial/02-babel-es6-eslint-flow-jest-husky.md
@@ -152,6 +152,36 @@ Yo recomiendo leer la [documentaci贸n de ESLint sobre punto y comas](http://esli
Soy consciente de que algunos de ustedes querr谩n seguir utilizando puntos y comas, lo que har谩 que el c贸digo proporcionado en este tutorial sea un inconveniente. Si est谩s usando este tutorial s贸lo para aprender, estoy seguro de que seguir谩 siendo soportable aprender sin punto y coma, hasta volver a usarlos en tus proyectos reales. Si desea utilizar el c贸digo proporcionado en este tutorial como una plantilla sin embargo, se requerir谩 un poco de reescritura, lo que deber铆a ser bastante r谩pido con ESLint establecido para aplicar puntos y comas para guiarlo a trav茅s del proceso. Me disculpo si est谩s en ese caso.
+### Compat
+
+[Compat](https://github.com/amilajack/eslint-plugin-compat) es un plugin de ESLint que te advierte si estas utilizando algunas APIs de Javascript que no est谩n disponibles en los navegadores que quieres soportar. Utiliza [Browserslist](https://github.com/ai/browserslist), que est谩 basado en [Can I Use](http://caniuse.com/).
+
+- Ejecuta `yarn add --dev eslint-plugin-compat`
+
+- Agrega lo siguiente a tu `package.json`, para indicar que queremos dar soporte a navegadores con mas del 1% de la cuota de mercado.
+
+```json
+"browserslist": ["> 1%"],
+```
+
+- Edita tu archivvvvo `.eslintrc.json`:
+
+```json
+{
+ "extends": "airbnb",
+ "plugins": [
+ "compat"
+ ],
+ "rules": {
+ "semi": [2, "never"],
+ "no-unexpected-multiline": 2,
+ "compat/compat": 2
+ }
+}
+```
+
+Puedes probar el plugin utilizando `navigator.serviceWorker` o `fetch` en tu c贸digo, lo que deber谩 generar una advertencia en ESLint.
+
### ESLint en tu Editor
En este cap铆tulo configurar谩 ESLint en la terminal, lo cual es una excelente manera de detectar errores en tiempo de construcci贸n / antes de hacer pushing, pero tambi茅n es posible que quiera integrarlo con su IDE para recibir una retroalimentaci贸n inmediata. NO use el linting ES6 nativo de su IDE. Configurelo que el binario que utiliza para linting sea el de su carpeta `node_modules` en su lugar. De esta manera puede utilizar todos los config de su proyecto, el preset Airbnb, etc. De lo contrario, s贸lo obtendr谩 un linting ES6 gen茅rico.
@@ -325,8 +355,10 @@ Todo lo que tenemos que hacer es crear dos nuevas tareas en `scripts`,` precommi
馃弫 Si ahora intenta hacer commit o push de su c贸digo, deber铆a automaticamente correr la tarea `test`.
+Si esto no funciona, es posible que `yarn add --dev husky` no haya instalado los Git Hooks apropiadamente. Nunca he tenido este problema, pero a algunos les sucede. Si es tu caso, ejecuta `yarn add --dev husky --force`, y si te es posible escribe un comentario para describir tu situaci贸n [en este issue](https://github.com/typicode/husky/issues/84).
+
**Nota**: Si est谩 haciendo push justo despu茅s de un commit, puede utilizar `git push --no-verify` para evitar ejecutar todas las pruebas de nuevo.
Siguiente secci贸n: [03 - Express, Nodemon, PM2](03-express-nodemon-pm2.md#readme)
-Regresar a la [secci贸n anterior](01-node-yarn-package-json.md#readme) o a la [tabla de contenidos](https://github.com/verekia/js-stack-from-scratch#table-of-contents).
\ No newline at end of file
+Regresar a la [secci贸n anterior](01-node-yarn-package-json.md#readme) o a la [tabla de contenidos](https://github.com/verekia/js-stack-from-scratch#table-of-contents).
diff --git a/tutorial/03-express-nodemon-pm2.md b/tutorial/03-express-nodemon-pm2.md
index 52d91c04..9a80f35a 100644
--- a/tutorial/03-express-nodemon-pm2.md
+++ b/tutorial/03-express-nodemon-pm2.md
@@ -197,7 +197,7 @@ Let's update our `package.json` like so:
"dev:start": "nodemon --ignore lib --exec babel-node src/server",
"prod:build": "rimraf lib && babel src -d lib --ignore .test.js",
"prod:start": "cross-env NODE_ENV=production pm2 start lib/server && pm2 logs",
- "prod:stop": "pm2 delete all",
+ "prod:stop": "pm2 delete server",
"test": "eslint src && flow && jest --coverage",
"precommit": "yarn test",
"prepush": "yarn test"
diff --git a/tutorial/04-webpack-react-hmr.md b/tutorial/04-webpack-react-hmr.md
index 39ad3d0e..e76e90ab 100644
--- a/tutorial/04-webpack-react-hmr.md
+++ b/tutorial/04-webpack-react-hmr.md
@@ -27,7 +27,7 @@ import { APP_CONTAINER_SELECTOR } from '../shared/config'
document.querySelector(APP_CONTAINER_SELECTOR).innerHTML = '
Hello Webpack!
'
```
-If you want to use some of the most recent ES features in your client code, like `Promise`s, you need to include the [Babel Polyfill](https://babeljs.io/docs/usage/polyfill/) before anything else in in your bundle.
+If you want to use some of the most recent ES features in your client code, like `Promise`s, you need to include the [Babel Polyfill](https://babeljs.io/docs/usage/polyfill/) before anything else in your bundle.
- Run `yarn add babel-polyfill`
@@ -59,9 +59,9 @@ export default {
'./src/client',
],
output: {
- filename: 'bundle.js',
- path: path.resolve(__dirname, 'dist/js'),
- publicPath: `http://localhost:${WDS_PORT}/dist/js/`,
+ filename: 'js/bundle.js',
+ path: path.resolve(__dirname, 'dist'),
+ publicPath: isProd ? '/static/' : `http://localhost:${WDS_PORT}/dist/`,
},
module: {
rules: [
@@ -78,7 +78,7 @@ export default {
}
```
-This file is used to describe how our bundle should be assembled: `entry` is the starting point of our app, `output.filename` is the name of the bundle to generate, `output.path` and `output.publicPath` describe the destination folder and URL. We put the bundle in a `dist` folder, which will contain things that are generated automatically (unlike the declarative CSS we created earlier which lives in `public`). `module.rules` is where you tell Webpack to apply some treatment to some type of files. Here we say that we want all `.js` and `.jsx` (for React) files except the ones in `node_modules` to go through something called `babel-loader`. We also want these two extensions to `resolve`. Finally, we declare a port for Webpack Dev Server.
+This file is used to describe how our bundle should be assembled: `entry` is the starting point of our app, `output.filename` is the name of the bundle to generate, `output.path` and `output.publicPath` describe the destination folder and URL. We put the bundle in a `dist` folder, which will contain things that are generated automatically (unlike the declarative CSS we created earlier which lives in `public`). `module.rules` is where you tell Webpack to apply some treatment to some type of files. Here we say that we want all `.js` and `.jsx` (for React) files except the ones in `node_modules` to go through something called `babel-loader`. We also want these two extensions to be used to `resolve` modules when we `import` them. Finally, we declare a port for Webpack Dev Server.
**Note**: The `.babel.js` extension is a Webpack feature to apply our Babel transformations to this config file.
@@ -103,7 +103,7 @@ Let's update our `scripts` to implement all this, and improve some other tasks a
"dev:wds": "webpack-dev-server --progress",
"prod:build": "rimraf lib dist && babel src -d lib --ignore .test.js && cross-env NODE_ENV=production webpack -p --progress",
"prod:start": "cross-env NODE_ENV=production pm2 start lib/server && pm2 logs",
- "prod:stop": "pm2 delete all",
+ "prod:stop": "pm2 delete server",
"lint": "eslint src webpack.config.babel.js --ext .js,.jsx",
"test": "yarn lint && flow && jest --coverage",
"precommit": "yarn test",
@@ -199,9 +199,9 @@ const App = () =>
Hello React!
export default App
```
-Since we use the JSX syntax here, we have to tell Babel that it needs to transform it as well.
+Since we use the JSX syntax here, we have to tell Babel that it needs to transform it with the `babel-preset-react` preset. And while we're at it, we're also going to add a Babel plugin called `flow-react-proptypes` which automatically generates PropTypes from Flow annotations for your React components.
-- Run `yarn add --dev babel-preset-react` and add `react` to your `.babelrc` file like so:
+- Run `yarn add --dev babel-preset-react babel-plugin-flow-react-proptypes` and edit your `.babelrc` file like so:
```json
{
@@ -209,6 +209,9 @@ Since we use the JSX syntax here, we have to tell Babel that it needs to transfo
"env",
"flow",
"react"
+ ],
+ "plugins": [
+ "flow-react-proptypes"
]
}
```
diff --git a/tutorial/05-redux-immutable-fetch.md b/tutorial/05-redux-immutable-fetch.md
index 713fb5db..92fc67b6 100644
--- a/tutorial/05-redux-immutable-fetch.md
+++ b/tutorial/05-redux-immutable-fetch.md
@@ -44,9 +44,7 @@ console.log(immutablePerson)
*/
```
-- Run `yarn add immutable`
-
-**Note**: Due to the implementation of ImmutableJS, Flow does not accept importing it with `import Immutable from 'immutable'`, so use this syntax instead: `import * as Immutable from 'immutable'`. Let's cross fingers for a [fix](https://github.com/facebook/immutable-js/issues/863) soon.
+- Run `yarn add immutable@4.0.0-rc.2`
## Redux
@@ -75,7 +73,8 @@ This file exposes an *action*, `SAY_HELLO`, and its *action creator*, `sayHello`
```js
// @flow
-import * as Immutable from 'immutable'
+import Immutable from 'immutable'
+import type { fromJS as Immut } from 'immutable'
import { SAY_HELLO } from '../action/hello'
@@ -83,7 +82,7 @@ const initialState = Immutable.fromJS({
message: 'Initial reducer message',
})
-const helloReducer = (state: Object = initialState, action: { type: string, payload: any }) => {
+const helloReducer = (state: Immut = initialState, action: { type: string, payload: any }) => {
switch (action.type) {
case SAY_HELLO:
return state.set('message', action.payload)
@@ -95,7 +94,7 @@ const helloReducer = (state: Object = initialState, action: { type: string, payl
export default helloReducer
```
-In this file we initialize the state of our reducer with an Immutable Map containing one property, `message`, set to `Initial reducer message`. The `helloReducer` handles `SAY_HELLO` actions by simply setting the new `message` with the action payload. The Flow annotation for `action` destructures it into a `type` and a `payload`. The `payload` can be of `any` type. It looks funky if you've never seen this before, but it remains pretty understandable. Note the usage of `Immutable.fromJS()` and `set()` as seen before.
+In this file we initialize the state of our reducer with an Immutable Map containing one property, `message`, set to `Initial reducer message`. The `helloReducer` handles `SAY_HELLO` actions by simply setting the new `message` with the action payload. The Flow annotation for `action` destructures it into a `type` and a `payload`. The `payload` can be of `any` type. It looks funky if you've never seen this before, but it remains pretty understandable. For the type of `state`, we use the `import type` Flow instruction to get the return type of `fromJS`. We rename it to `Immut` for clarity, because `state: fromJS` would be pretty confusing. The `import type` line will get stripped out like any other Flow annotation. Note the usage of `Immutable.fromJS()` and `set()` as seen before.
## React-Redux
@@ -112,35 +111,35 @@ In this section we are going to create *Components* and *Containers*.
```js
// @flow
-import React, { PropTypes } from 'react'
-
-const Button = ({ label, handleClick }: { label: string, handleClick: Function }) =>
-
+import React from 'react'
-Button.propTypes = {
- label: PropTypes.string.isRequired,
- handleClick: PropTypes.func.isRequired,
+type Props = {
+ label: string,
+ handleClick: Function,
}
+const Button = ({ label, handleClick }: Props) =>
+
+
export default Button
```
-**Note**: You can see another case of destructuring with Flow annotations here. If `props` contains `handleClick`, instead of writing `const Button = (props) => { props.handleClick() }`, we write `const Button = ({ handleClick }: { handleClick: Function }) => { handleClick() }`. The syntax is a bit cumbersome but worth it.
+**Note**: You can see a case of Flow *type alias* here. We define the `Props` type before annotating our component's destructured `props` with it.
- Create a `src/client/component/message.jsx` file containing:
```js
// @flow
-import React, { PropTypes } from 'react'
-
-const Message = ({ message }: { message: string }) =>
-
+
export default Message
```
@@ -362,6 +361,16 @@ We are going to use `fetch` to make calls to the server from the client. `fetch`
- Run `yarn add isomorphic-fetch`
+Since we're using `eslint-plugin-compat`, we need to indicate that we are using a polyfill for `fetch` to not get warnings from using it.
+
+- Add the following to your `.eslintrc.json` file:
+
+```json
+"settings": {
+ "polyfills": ["fetch"]
+},
+```
+
### 3 asynchronous actions
`sayHelloAsync` is not going to be a regular action. Asynchronous actions are usually split into 3 actions, which trigger 3 different states: a *request* action (or "loading"), a *success* action, and a *failure* action.
@@ -412,7 +421,8 @@ Let's handle these different actions in `src/client/reducer/hello.js`:
```js
// @flow
-import * as Immutable from 'immutable'
+import Immutable from 'immutable'
+import type { fromJS as Immut } from 'immutable'
import {
SAY_HELLO,
@@ -426,7 +436,7 @@ const initialState = Immutable.fromJS({
messageAsync: 'Initial reducer message for async call',
})
-const helloReducer = (state: Object = initialState, action: { type: string, payload: any }) => {
+const helloReducer = (state: Immut = initialState, action: { type: string, payload: any }) => {
switch (action.type) {
case SAY_HELLO:
return state.set('message', action.payload)
@@ -536,7 +546,7 @@ In order to isolate the logic that is specific to `action/hello.js` we are going
- Run `yarn add --dev redux-mock-store fetch-mock`
-- Create a `src/client/action/hello.test.js` containing:
+- Create a `src/client/action/hello.test.js` file containing:
```js
import fetchMock from 'fetch-mock'
diff --git a/tutorial/06-react-router-ssr-helmet.md b/tutorial/06-react-router-ssr-helmet.md
index 539b5475..4eec3550 100644
--- a/tutorial/06-react-router-ssr-helmet.md
+++ b/tutorial/06-react-router-ssr-helmet.md
@@ -303,7 +303,7 @@ Here is our controller. It would typically make business logic and database call
```js
// @flow
-import * as Immutable from 'immutable'
+import Immutable from 'immutable'
import { createStore, combineReducers, applyMiddleware } from 'redux'
import thunkMiddleware from 'redux-thunk'
@@ -408,7 +408,7 @@ export default renderApp
- Edit `src/client/index.jsx` to use that preloaded state:
```js
-import * as Immutable from 'immutable'
+import Immutable from 'immutable'
// [...]
/* eslint-disable no-underscore-dangle */
@@ -458,7 +458,7 @@ const renderApp = (/* [...] */) => {
}
```
-React Helmet uses [react-side-effect](https://github.com/gaearon/react-side-effect)'s `rewind` to pull out some data from the rendering of our app, which will soon contain some `` components. Those `` components are where we set the `title` and other `head` details for each page.
+React Helmet uses [react-side-effect](https://github.com/gaearon/react-side-effect)'s `rewind` to pull out some data from the rendering of our app, which will soon contain some `` components. Those `` components are where we set the `title` and other `head` details for each page. Note that `Helmet.rewind()` *must* come after `ReactDOMServer.renderToString()`.
- Edit `src/shared/app.jsx` like so:
diff --git a/tutorial/08-bootstrap-jss.md b/tutorial/08-bootstrap-jss.md
index 54cfc7e8..d280fe0c 100644
--- a/tutorial/08-bootstrap-jss.md
+++ b/tutorial/08-bootstrap-jss.md
@@ -21,7 +21,9 @@ For this reason, I'm going to make the tradeoff of integrating the official rele
- Delete `public/css/style.css`
-- Download the latest official release from Bootstrap and put `bootstrap.min.css` and `bootstrap.min.css.map` in the `public/css` folder.
+- Run `yarn add bootstrap@4.0.0-alpha.6`
+
+- Copy `bootstrap.min.css` and `bootstrap.min.css.map` from `node_modules/bootstrap/dist` to your `public/css` folder.
- Edit `src/server/render-app.jsx` like so:
@@ -33,7 +35,7 @@ For this reason, I'm going to make the tradeoff of integrating the official rele
Now that we have Bootstrap's styles loaded on our page, we need the JavaScript behavior for the components.
-- Run `yarn add jquery tether bootstrap@4.0.0-alpha.6`
+- Run `yarn add jquery tether`
- Edit `src/client/index.jsx` like so:
@@ -264,7 +266,7 @@ const App = () =>
This is an example of a *React inline style*.
-This will translate into: `
` in your DOM. We need this style to push the content under the navigation bar, but that's what's important here. [React inline styles](https://speakerdeck.com/vjeux/react-css-in-js) are a great way to isolate your component's styles from the global CSS namespace, but it comes at a price: You cannot use some native CSS features like `:hover`, Media Queries, animations, or `font-face`. That's the reason why we're going to integrate a CSS-in-JS library, JSS, later in this chapter. For now, just keep in mind that you can use React inline styles this way if you don't need `:hover` and such.
+This will translate into: `
` in your DOM. We need this style to push the content under the navigation bar, but that's what's important here. [React inline styles](https://speakerdeck.com/vjeux/react-css-in-js) are a great way to isolate your component's styles from the global CSS namespace, but it comes at a price: You cannot use some native CSS features like `:hover`, Media Queries, animations, or `font-face`. That's [one of the reasons](https://github.com/cssinjs/jss/blob/master/docs/benefits.md#compared-to-inline-styles) we're going to integrate a CSS-in-JS library, JSS, later in this chapter.
- Edit `src/shared/component/nav.jsx` like so:
@@ -340,7 +342,7 @@ The cool React kids tend to favor React inline styles, CSS-in-JS, or CSS Modules
CSS Modules work well, but they don't leverage the power of JavaScript and its many features over CSS. They just provide encapsulation, which is fine, but React inline styles and CSS-in-JS take styling to an other level in my opinion. My personal suggestion would be to use React inline styles for common styles (that's also what you have to use for React Native), and use a CSS-in-JS library for things like `:hover` and media queries.
-There are tons of CSS-in-JS libraries. Two leading ones are Aphrodite and JSS. They achieve pretty much the same thing and the syntax is basically the same. To be honest, I haven't done a comparison of the two on any significant-size project, and really just have a slight preference for JSS' API. We can discuss this topic in [this issue](https://github.com/verekia/js-stack-from-scratch/issues/139). I would like to hear the opinion of those who have done a more thorough comparison.
+There are [tons of CSS-in-JS libraries](https://github.com/MicheleBertoli/css-in-js). JSS is a full-featured, well-rounded, and [performant](https://github.com/cssinjs/jss/blob/master/docs/performance.md) one.
## JSS
@@ -425,6 +427,10 @@ const styles = {
color: 'red',
},
},
+ specialButton: {
+ composes: ['btn', 'btn-primary'],
+ backgroundColor: 'limegreen',
+ },
}
const HomePage = ({ classes }: { classes: Object }) =>
@@ -433,6 +439,7 @@ const HomePage = ({ classes }: { classes: Object }) =>