Como Crear una Página Web con Node JS 10, Express JS 4 y Bootstrap 4 – Parte 4 (Final)

Demo Github

En este capitulo continuaremos con el capitulo anterior Como Crear una Página Web con Node JS 10, Express JS 4 y Bootstrap 4 – Parte 3 en donde creamos la estructura de nuestro proyecto, las rutas para las vistas HTML y las páginas HTML. En este último capitulo mejoraremos el aspecto visual de nuestras páginas HTML con Bootstrap 4, vayamos con el tutorial.

Partes

En el primer capitulo de este tutorial, instalamos Bootstrap 4, lo dejamos listo para ser empleado en mejorar la interface visual de las páginas HTML.

Ahora deberás de instanciar a los archivos de Bootstrap, jQuery y Popper JS, los archivos se encuentran en la carpeta node_modules, abre el archivo app.js

/proyectoweb
├── bin
│   └── www
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    └── contacto.pug 
    ├── error.pug
    ├── index.pug
    └── layout.pug
    └── nosotros.pug 
    └── servicios.pug  
├── app.js // Abre este archivo
├── package.json

y agrega lo siguiente

// Bootstrap 4 y librerías necesarias
app.use('/css', express.static(__dirname + '/node_modules/bootstrap/dist/css'));
app.use('/js', express.static(__dirname + '/node_modules/jquery/dist'));
app.use('/js', express.static(__dirname + '/node_modules/popper.js/dist'));
app.use('/js', express.static(__dirname + '/node_modules/bootstrap/dist/js'));

Con las lineas anteriores de código estamos instanciando los archivos necesarios para que Bootstrap 4 funcione correctamente.

Todo el código de nuestro archivo app.js quedaría así

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// Bootstrap 4 y librerías necesarias
app.use('/css', express.static(__dirname + '/node_modules/bootstrap/dist/css'));
app.use('/js', express.static(__dirname + '/node_modules/jquery/dist'));
app.use('/js', express.static(__dirname + '/node_modules/popper.js/dist'));
app.use('/js', express.static(__dirname + '/node_modules/bootstrap/dist/js'));

app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

Listo, ya podemos usar las clases, módulos, componentes, etc. de Bootstrap 4, ahora para hacer uso de los archivos debemos de instanciarlos en nuestra vista HTML, como estamos usando un Layout para todas las paginas, abre el archivo layout.pug

/proyectoweb
├── bin
│   └── www
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    └── contacto.pug 
    ├── error.pug
    ├── index.pug
    └── layout.pug // Abre este archivo
    └── nosotros.pug 
    └── servicios.pug  
├── app.js
├── package.json

y agrega los archivos de la siguiente manera, para mantener las buenas prácticas, arriba colocamos el archivo bootstrap.min.css y debajo el archivo bootstrap.min.js con los archivos Javascript necesarios para que funcione Bootstrap, como jQuery y Popper

doctype html
html
  head
    meta(name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no')
    meta(charset='utf-8')
    title= title
    link(rel='stylesheet', href='/css/bootstrap.min.css')
    
  body
    block content

   
    link(rel='stylesheet', href='/js/jquery.min.js')
    link(rel='stylesheet', href='/js/popper.js')
    link(rel='stylesheet', href='/js/bootstrap.min.js')

Arriba puedes ver que colocamos el soporte para que la pagina se vuelve scalable a las pantallas

meta(name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no')

También colocamos el soporte para caracteres especiales mediante la codificación UTF-8

meta(charset='utf-8')

Ahora en nuestra carpeta views en donde se encuentra el archivo del Layout llamado layout.pug, también se encuentran las Páginas a las que les aplicaremos Bootstrap 4

/proyectoweb
├── bin
│   └── www
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    └── contacto.pug // Página Contacto 
    ├── error.pug
    ├── index.pug // Página Home 
    └── layout.pug
    └── nosotros.pug // Página Nosotros 
    └── servicios.pug // Página Servicios 
├── app.js
├── package.json

Dentro de cada una de las páginas vamos a instanciar el layout y hacer referencia a la zona o bloque (block content) en donde colocaremos el contenido que debe ser único para cada una de nuestras vistas HTML.

Empezaremos con la vista Home, abre el archivo index.pug y agrega lo siguiente

extends layout

block content

  nav.navbar.navbar-expand-md.navbar-dark.bg-dark.mb-4
    a.navbar-brand(href='#') Mi Proyecto
    button.navbar-toggler(type='button' data-toggle='collapse' data-target='#navbarCollapse' aria-controls='navbarCollapse' aria-expanded='false' aria-label='Toggle navigation')
      span.navbar-toggler-icon
    #navbarCollapse.collapse.navbar-collapse
      ul.navbar-nav.mr-auto
        li.nav-item.active
          a.nav-link(href='/')
            | Home 
            span.sr-only (current)
        li.nav-item
          a.nav-link(href='nosotros') Nosotros
        li.nav-item
          a.nav-link(href='servicios') Servicios
        li.nav-item
          a.nav-link(href='contacto') Contacto
      form.form-inline.mt-2.mt-md-0
        input.form-control.mr-sm-2(type='text' placeholder='Buscar' aria-label='Buscar')
        button.btn.btn-outline-success.my-2.my-sm-0(type='submit') Buscar
  main.container(role='main')
    .jumbotron
      h1 Home
      p.lead
        | Estás en la página Home
      a.btn.btn-lg.btn-primary(href='#' role='button') Botón »
    .container
    
    .row
      .col-md-4
        h2 Contenido
        p
          | Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
        p
          a.btn.btn-secondary(href='#' role='button') Ver más »
      .col-md-4
        h2 Contenido
        p
          | Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
        p
          a.btn.btn-secondary(href='#' role='button') Ver más »
      .col-md-4
        h2 Contenido
        p
          | Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.
        p
          a.btn.btn-secondary(href='#' role='button') Ver más »
    hr

  footer
  .container
    div(align='center')
      | Desarrollado por 
      a(href='https://www.nubecolectiva.com' target='_blank') Nube Colectiva

Puedes ver que no son etiquetas HTML convencionales, es porque estamos usando Pug, que es un motor para renderizar etiquetas HTML, Pug solo nos pide que escribamos la inicial de la etiqueta HTML y este se encargará de renderizarlo en el navegador, abre tu navegador y ejecuta el servidor

npm start

GET / 304 1951.482 ms - -
GET /css/bootstrap.min.css 304 5.669 ms - -
GET /js/jquery.min.js 304 2.869 ms - -
GET /js/popper.js 304 3.382 ms - -
GET /js/bootstrap.min.js 304 4.060 ms - -

Abre el servidor con el puerto 3000 https://localhost:3000/ y veras la vista Home con la interface Visual más agradable diseñada con etiquetas y clases de Bootstrap 4

Para la página Nosotros le agregamos la siguiente estructura

extends layout

block content

  nav.navbar.navbar-expand-md.navbar-dark.bg-dark.mb-4
    a.navbar-brand(href='#') Mi Proyecto
    button.navbar-toggler(type='button' data-toggle='collapse' data-target='#navbarCollapse' aria-controls='navbarCollapse' aria-expanded='false' aria-label='Toggle navigation')
      span.navbar-toggler-icon
    #navbarCollapse.collapse.navbar-collapse
      ul.navbar-nav.mr-auto
        li.nav-item
          a.nav-link(href='/') Home
        li.nav-item.active
          a.nav-link(href='nosotros')
            | Nosotros 
            span.sr-only (current)
        li.nav-item
          a.nav-link(href='servicios') Servicios
        li.nav-item
          a.nav-link(href='contacto') Contacto
      form.form-inline.mt-2.mt-md-0
        input.form-control.mr-sm-2(type='text' placeholder='Buscar' aria-label='Buscar')
        button.btn.btn-outline-success.my-2.my-sm-0(type='submit') Buscar
  main.container(role='main')
    .jumbotron
      h1 Nosotros
      p.lead
        | Estás en la página Nosotros
      a.btn.btn-lg.btn-primary(href='#' role='button') Botón »
    .container

    p.lead
        | Compartimos tutoriales sobre:
    
    .row
      .col-md-4
        h2 Frontend
        p
          | Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
          a(href='https://nubecolectiva.com/blog/category/frontend/' target='_blank')
           img.img-fluid.mt-3(src='https://nubecolectiva.com/blog/wp-content/uploads/2018/11/img_destacada_blog_devs-11-300x169.png')

      .col-md-4
        h2 Backend
        p
          | Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
          a(href='https://nubecolectiva.com/blog/category/backend/' target='_blank')
           img.img-fluid.mt-2(src='https://nubecolectiva.com/blog/wp-content/uploads/2018/11/img_destacada_blog_devs-8-300x169.png')

      .col-md-4
        h2 Android
        p
          | Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa.
          a(href='https://nubecolectiva.com/blog/category/android/' target='_blank')
           img.img-fluid.mt-2(src='https://nubecolectiva.com/blog/wp-content/uploads/2018/11/img_destacada_blog_devs-9-300x169.png')

    hr

  footer
  .container
    div(align='center')
      | Desarrollado por 
      a(href='https://www.nubecolectiva.com' target='_blank') Nube Colectiva

Navegamos hacia la página Nosotros https://localhost:3000/nosotros y tenemos

Vayamos con la Página Servicios, para este página agregamos el siguiente diseño

extends layout

block content

  nav.navbar.navbar-expand-md.navbar-dark.bg-dark.mb-4
    a.navbar-brand(href='#') Mi Proyecto
    button.navbar-toggler(type='button' data-toggle='collapse' data-target='#navbarCollapse' aria-controls='navbarCollapse' aria-expanded='false' aria-label='Toggle navigation')
      span.navbar-toggler-icon
    #navbarCollapse.collapse.navbar-collapse
      ul.navbar-nav.mr-auto
        li.nav-item
          a.nav-link(href='/') Home
        li.nav-item
          a.nav-link(href='nosotros') Nosotros             
        li.nav-item.active
          a.nav-link(href='servicios')
           | Servicios
           span.sr-only (current)
        li.nav-item
          a.nav-link(href='contacto') Contacto
      form.form-inline.mt-2.mt-md-0
        input.form-control.mr-sm-2(type='text' placeholder='Buscar' aria-label='Buscar')
        button.btn.btn-outline-success.my-2.my-sm-0(type='submit') Buscar
  main.container(role='main')
    .jumbotron
      h1 Servicios
      p.lead
        | Estás en la página Servicios
      a.btn.btn-lg.btn-primary(href='#' role='button') Botón »
    
    p.lead
      | Nuestros Servicios:

    .container

    .row
      .col-md-4
        .card
         img.card-img-top.img-fluid(src='data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22286%22%20height%3D%22180%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20286%20180%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_1674528f4eb%20text%20%7B%20fill%3Argba(255%2C255%2C255%2C.75)%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_1674528f4eb%22%3E%3Crect%20width%3D%22286%22%20height%3D%22180%22%20fill%3D%22%23777%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22107.203125%22%20y%3D%2296.3%22%3E286x180%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E' alt='Card image cap')
        .card-body
         h5.card-title Servicio 1
         p.card-text
          | Some quick example text to build on the card title and make up the bulk of the card's content.
         a.btn.btn-primary(href='#') Ver más


      .col-md-4
        .card
         img.card-img-top.img-fluid(src='data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22286%22%20height%3D%22180%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20286%20180%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_1674528f4eb%20text%20%7B%20fill%3Argba(255%2C255%2C255%2C.75)%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_1674528f4eb%22%3E%3Crect%20width%3D%22286%22%20height%3D%22180%22%20fill%3D%22%23777%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22107.203125%22%20y%3D%2296.3%22%3E286x180%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E' alt='Card image cap')
        .card-body
         h5.card-title Servicio 2
         p.card-text
          | Some quick example text to build on the card title and make up the bulk of the card's content.
         a.btn.btn-primary(href='#') Ver más

      .col-md-4
        .card
         img.card-img-top.img-fluid(src='data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22286%22%20height%3D%22180%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20286%20180%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_1674528f4eb%20text%20%7B%20fill%3Argba(255%2C255%2C255%2C.75)%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_1674528f4eb%22%3E%3Crect%20width%3D%22286%22%20height%3D%22180%22%20fill%3D%22%23777%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22107.203125%22%20y%3D%2296.3%22%3E286x180%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E' alt='Card image cap')
        .card-body
         h5.card-title Servicio 3
         p.card-text
          | Some quick example text to build on the card title and make up the bulk of the card's content.
         a.btn.btn-primary(href='#') Ver más

    hr

  footer
  .container
    div(align='center')
      | Desarrollado por 
      a(href='https://www.nubecolectiva.com' target='_blank') Nube Colectiva

Ahora ve la ruta de la página Servicios https://localhost:3000/servicios y tendrás el siguiente diseño

Y la última página Contacto, le agregamos el siguiente diseño con un sencillo formulario

extends layout

block content

  nav.navbar.navbar-expand-md.navbar-dark.bg-dark.mb-4
    a.navbar-brand(href='#') Mi Proyecto
    button.navbar-toggler(type='button' data-toggle='collapse' data-target='#navbarCollapse' aria-controls='navbarCollapse' aria-expanded='false' aria-label='Toggle navigation')
      span.navbar-toggler-icon
    #navbarCollapse.collapse.navbar-collapse
      ul.navbar-nav.mr-auto
        li.nav-item
          a.nav-link(href='/') Home
        li.nav-item
          a.nav-link(href='nosotros') Nosotros             
        li.nav-item
          a.nav-link(href='servicios') Servicios          
        li.nav-item.active
          a.nav-link(href='contacto') 
           | Contacto
           span.sr-only (current)
      form.form-inline.mt-2.mt-md-0
        input.form-control.mr-sm-2(type='text' placeholder='Buscar' aria-label='Buscar')
        button.btn.btn-outline-success.my-2.my-sm-0(type='submit') Buscar
  main.container(role='main')
    .jumbotron
      h1 Contacto
      p.lead
        | Estás en la página Contacto
      a.btn.btn-lg.btn-primary(href='#' role='button') Botón »
    
    p.lead
      | Contactanos por medio del siguiente Formulario:

    .container

    .row
      .col-md-12
        form(action='/')
         .form-group
          label(for='nya')
           strong Nombres y Apellidos
          input#nya.form-control(type='text' aria-describedby='nyaHelp' placeholder='Ingresa tus Nombres y Apellidos', required)
          small#nyaHelp.form-text.text-muted Por favor, Nombres y Apellidos Completos.

         .form-group
          label(for='email')
           strong Email
          input#email.form-control(type='email' aria-describedby='emailHelp' placeholder='Ingresa tu Email', required)
          small#emailHelp.form-text.text-muted Tu correo activo.

          .form-group
          label(for='mensaje')
           strong Mensaje
          textarea#comment.form-control(rows='5', required)
          small#mensajeHelp.form-text.text-muted Tu Mensaje.
          br  
          button.btn.btn-primary(type='submit') Enviar


    hr

  footer
  .container
    div(align='center')
      | Desarrollado por 
      a(href='https://www.nubecolectiva.com' target='_blank') Nube Colectiva

Si abrimos la página Contacto https://localhost:3000/contacto, tendremos el siguiente diseño

Listo ya tenemos nuestras páginas creadas correctamente.

Ahora vamos a compilar nuestro proyecto, lo pasaremos a producción para publicarlo, para esto usaremos Webpack 4, el cual nos pide crear el archivo webpack.config.js en la carpeta principal del proyecto

/proyectoweb
├── bin
│   └── www
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    └── contacto.pug 
    ├── error.pug
    ├── index.pug
    └── layout.pug
    └── nosotros.pug 
    └── servicios.pug  
├── app.js
├── package.json
├── webpack.config.js // Crea este archivo

Abre el archivo webpack.config.js y agrega lo siguiente:

const path = require('path');

var HtmlWebpackPlugin = require('html-webpack-plugin');
var HtmlWebpackPugPlugin = require('html-webpack-pug-plugin');

module.exports = {
    entry: {
        app: './app.js'
    },
    module: {
        rules: [
          {
            test: /\.pug$/,
            use: [
              "raw-loader",
              "pug-html-loader"
            ]
          }
        ],
        noParse: function (content) {
            return /express/.test(content);
        }
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: 'views/index.pug',
        filename: 'index.html'
      }),
      new HtmlWebpackPlugin({
        template: 'views/nosotros.pug',
        filename: 'nosotros.html'
      }),
      new HtmlWebpackPlugin({
        template: 'views/servicios.pug',
        filename: 'servicios.html'
      }),
      new HtmlWebpackPlugin({
        template: 'views/contacto.pug',
        filename: 'contacto.html'
      })
    ],
    mode: 'production',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    }
};

Con el código anterior anterior lo que hacemos es crear los archivos HTML, los convertimos del formato *.pug al formato *.html

Las páginas HTML las configuramos para que se guarden automáticamente en la carpeta dist

/proyectoweb
├── bin
│   └── www
└── dist
    └── contacto.html // Página HTML Contacto 
    ├── index.html // Página HTML Home 
    └── nosotros.html // Página HTML Nosotros 
    └── servicios.html // Página HTML Servicios 
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    └── contacto.pug 
    ├── error.pug
    ├── index.pug
    └── layout.pug
    └── nosotros.pug 
    └── servicios.pug  
├── app.js
├── package.json
├── webpack.config.js

Estuvimos investigando y para no complicarnos con los archivos de Bootstrap, jQuery y Popper, lo que haremos sera copiarlos a nuestra carpeta dist para esto crearemos una tarea que realice la copia de los archivos, para esto debemos de instalar Gulp ejecutando el siguiente comando

npm install gulp --save

y para el soporte te comandos funciones instala Gulp Cli con el siguiente comando

npm install gulp-cli --save

Gulp es una herramienta que te permite realizar tareas dentro de tu proyecto, Gulp nos pide crear un archivo llamado gulpfile.js en donde colocaremos nuestra tarea para copiar los archivos

/proyectoweb
├── bin
│   └── www
└── dist
    └── contacto.html // Página HTML Contacto 
    ├── index.html // Página HTML Home 
    └── nosotros.html // Página HTML Nosotros 
    └── servicios.html // Página HTML Servicios 
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    └── contacto.pug 
    ├── error.pug
    ├── index.pug
    └── layout.pug
    └── nosotros.pug 
    └── servicios.pug  
├── app.js
├── package.json
├── webpack.config.js
├── gulpfile.js // Crea este archivo

Abre el archivo gulpfile.js y agrega la siguiente tarea

var gulp = require('gulp');

gulp.task('copy', function () {
    gulp.src('./node_modules/bootstrap/dist/css/bootstrap.min.css')
        .pipe(gulp.dest('./dist/css/'));
    gulp.src('./node_modules/jquery/dist/jquery.min.js')
        .pipe(gulp.dest('./dist/js/'));
    gulp.src('./node_modules/popper.js/dist/popper.js')
        .pipe(gulp.dest('./dist/js/'));
    gulp.src('./node_modules/bootstrap/dist/js/bootstrap.min.js')
        .pipe(gulp.dest('./dist/js/'));
});

Ahora vamos a ejecutar el código anterior, que va a copiar los archivos.

Si tu consola de comandos no soporta comandos Gulp,  puedes usar de preferencia la consola de comandos de Node JS que se integro al sistema cuando instalaste Node JS y ejecuta el siguiente comando para ejecutar las tareas de copiado del codigo anterior

gulp copy

[02:38:20] Using gulpfile \proyectoweb\gulpfile.js
[02:38:20] Starting 'copy'...
[02:38:20] Finished 'copy' after 13 ms

El código anterior que hace es copiar todos los archivos a la carpeta dist y dentro de esta carpeta crea 2 carpetas una llamada js para los archivos Javascript y otra carpeta llamada css para los archivos CSS

/proyectoweb
├── bin
│   └── www
└── dist
    └── css
        └── bootstrap.min.css // Archivo Bootstrap CSS
    └── js
        └── bootstrap.min.js // Archivo Bootstrap JS
        └── jquery.min.js // Archivo jQuery
        └── popper.js  // Archivo Popper
    └── contacto.html
    ├── index.html
    └── nosotros.html
    └── servicios.html
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    └── contacto.pug 
    ├── error.pug
    ├── index.pug
    └── layout.pug
    └── nosotros.pug 
    └── servicios.pug  
├── app.js
├── package.json
├── webpack.config.js
├── gulpfile.js // Crea este archivo

Eso es todo, ahora puedes abrir los archivos que se encuentra en la carpeta dist y visualizar tu pagina web, lista para publicarse

Notas

  • En los archivos HTML que generamos en la carpeta dist, si tienes problemas cargando los archivos CSS y Javascript, puedes borrar la barra diagonal  ‘/’  que esta al inicio, para que llame correctamente a los archivos, por ejemplo el archivo CSS de Bootstrap “/css/bootstrap.min.css” le quitas la primera barra diagonal y queda así “css/bootstrap.min.css”
  • Los comandos y pasos mencionados en todos los capítulos de este tutorial pueden cambiar, esto no depende de nosotros, si no de los desarrolladores que dan soporte a estas tecnologías.
  • Si tienes problemas con los paquetes y herramientas que usamos, puedes descargar el proyecto de repositorio Github e instalar los paquetes usando el comando npm install

 

Síguenos en las Redes Sociales para que no te pierdas nuestros próximos contenidos.