Crear nuestro primer proyecto

Contactar con el profesor

  1. Instalamos nodejs
  2. A partir de aquí, tenemos dos opciones:
    • Usar create-react-app
    • Configurar el proyecto manualmente

Usar create-react-app

npx create-react-app mi-aplicacion

Configurar el proyecto manualmente

Es buena idea partir del siguiente proyecto que ya tiene una configuración con únicamente las cosas que necesitamos habitualmente. Para ejecutar el primer comando necesitaremos tener git instalado.

git clone https://github.com/monteserin/react-template.git
Si no queremos descargar la carpeta .git:
npx degit monteserin/react-template

El código relevante que está dentro de esta plantilla es:

package.json
{
  "name": "template",
  "version": "1.0.0",
  "description": "",
  "main": "./dist",
  "scripts": {
    "build": "cross-env NODE_ENV=production PUBLIC_PATH=/ruta-del-proyecto-en-produccion webpack -p",
    "start": "cross-env NODE_ENV=development webpack-dev-server --open --watch",
    "upload": "node ./bin/upload.js"
  },
  "author": "Pablo Monteserín",
  "license": "ISC",
  "devDependencies": {
    "@babel/cli": "^7.0.0",
    "@babel/core": "^7.3.4",
    "@babel/plugin-proposal-optional-chaining": "^7.7.5",
    "@babel/plugin-transform-runtime": "^7.3.4",
    "@babel/preset-env": "^7.3.4",
    "@babel/preset-react": "^7.0.0",
    "@babel/runtime": "^7.5.5",
    "babel-loader": "^8.0.5",
    "babel-plugin-import-directory": "^1.1.0",
    "babel-plugin-inline-import": "^3.0.0",
    "babel-plugin-module-resolver": "^3.2.0",
    "babel-plugin-wildcard": "^5.0.0",
    "babel-preset-react": "^6.24.1",
    "cross-env": "^7.0.2",
    "html-webpack-plugin": "^3.2.0",
    "file-loader": "^4.1.0",
    "react-styleguidist": "9.2.0",
    "terser-webpack-plugin": "^1.2.3",
    "url-loader": "^2.2.0",
    "webpack": "4.29.6",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.2.1"
  },
  "dependencies": {
    "axios": "^0.19.0",
    "easy-ftp": "^0.4.1",
    "react": "16.9.0",
    "react-dom": "16.9.0",
    "react-router": "^5.0.1",
    "react-router-dom": "^5.0.1",
    "styled-components": "4.4.1"
  }
}

El webpack.config.js se encarga de configurar el empaquetado (bundle) de la aplicación que vamos a generar:

/webpack.config.js
// Cargamos un módulo nativo de node que nos gestiona rutas
const path = require('path');

// Cargamos webpack para definir plugins propios
const webpack = require('webpack');

// Este módulo minifica el bundle (el archivo compilado)
const TerserPlugin = require('terser-webpack-plugin');

// Este módulo inyecta el bundle en el HTML
const HtmlWebpackPlugin = require('html-webpack-plugin');

// Constantes con los paths de la aplicación
const paths = {
  ROOT: path.resolve(__dirname),
  DIST: path.resolve(__dirname, 'dist'),
  SRC: path.resolve(__dirname, 'src'),
};

//process.env nos permite acceder a las variables de entorno del sistema operativo
//Accedemos a las variables definidas de entorno que hemos definido en el package.json
const development = process.env.NODE_ENV === 'development';
const publicPath = process.env.PUBLIC_PATH || '';

// Set plugins
const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
  template: './src/index.html',
  hash: !development,
});

const processEnvPlugin = new webpack.DefinePlugin({
  'process.env': {
    PUBLIC_PATH: JSON.stringify(publicPath),
  },
});

module.exports = {
  entry: path.join(paths.SRC, 'index.js'),
  output: {
    path: paths.DIST,
    filename: 'bundle.js',
    publicPath: publicPath || '/',
  },
  module: {
    rules: [
      {
        test: /\.(js)$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
      {
        test: /\.(jpg|jpeg|gif|png|wav)$/,
        loader: 'file-loader',
        options: {
          publicPath: `${publicPath}/statics/images/`,
          outputPath: './statics/images/',
          name: '[name].[ext]',
        },
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2|otf)$/,
        loader: 'file-loader',
        options: {
          publicPath: `${publicPath}/statics/vectors/`,
          outputPath: './statics/vectors/',
          name: '[name].[ext]',
        },
      },
    ],
  },
  resolve: {
    extensions: ['.js'],
  },
  devServer: {
    historyApiFallback: true,
    disableHostCheck: true,
    hot: false,
    port: 8080,
  },
  optimization: {
    minimize: !development,
    minimizer: [
      new TerserPlugin({
        sourceMap: development,
        cache: true,
        parallel: true,
        terserOptions: {
          compress: !development,
          ecma: 6,
          ie8: false,
          mangle: true,
        },
      }),
    ],
  },
  mode: process.env.NODE_ENV,
  devtool: development && 'source-map',
  plugins: [
    HtmlWebpackPluginConfig,
    processEnvPlugin,
  ],
};

Babel se encarga de transpilar nuestro código Javascript EcmaScript 6+ ( preset-env ) y nuestro código JSX ( preset-react ) a versiones más antiguas y por tanto más aceptadas por la mayoría de los nacegadores.

Un preset es una agrupación de plugins. Los plugins definirán como se hará la transpilación en babel.

Cómo ves, primero ponemos las agrupaciones de plugins (presets) y luego los plugins sueltos.

/.babelrc
{
  "presets": [
    "@babel/preset-env", "@babel/preset-react"
  ],
  "plugins": [
    "@babel/plugin-transform-runtime"
  ]
}
/src/index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>React App</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
/src/App.js
import React from 'react';

const App = _ => (
    <div>
        hola
    </div>
);

export default App;
/bin/upload.js
const EasyFtp = require('easy-ftp');
const ftp = new EasyFtp();
const config = {
    "name": "pablomonteserin.com",
    "host": "example.com",
    "port": 21,
    "type": "ftp",
    "username": "usuario",
    "password": "password",
};

//(connect)
ftp.connect(config);
ftp.upload("./dist/**", "/www/termine", function(err) {
    if(err) {
        return console.error(err);
    }
    console.info('Deployed!');
});

Arrancar una aplicación

npm start
← El editor
JSX →

Aviso Legal | Política de privacidad