# Bootstrap 4 starter (ZURB Style)

## Introducción

**Que trae zurb template por defecto:**

* Handlebars HTML templates con Panini
* Sass compilación y prefijado
* JavaScript module bundling con webpack
* BrowserSync servidor local
* Para producción construye:
  * CSS compresión
  * JavaScript compresión
  * Image compresión

**Construcción de páginas**

El directorio src/ incluye tres directorios utilizados para crear las páginas HTML: pages/, layouts/, y partials/. Para construir las páginas zurb utiliza Panini, su propio motor de plantillas, Panini está basado en [Handlebars](http://handlebarsjs.com/) y te permite crear layouts, partials, includes etc… como si estubieras trabajando con [líquid](https://shopify.github.io/liquid/) en un Jekyll.

[Aprender más sobre Panini.](https://foundation.zurb.com/sites/docs/panini.html)

**Compilación de Sass**

Sass se compila a CSS con Libsass (via node-sass).

También crea un source map. Para producción el CSS se comprime con clean-css, y elimina todo el CSS que no utilizas con UnCSS.

**Compilación de JavaScript**

Javascript se transpila con Babel (con el pluguin es2015) así que puedes utilizar código ES2015.

Te crea un source map de js. Por defecto te crea un archivo app.js sin comprimir. Cuando construyes para producción utiliza UglifyJS para comprimir.

Todo el proceso de construcción de JS es llevado a cabo por [webpack](https://webpack.js.org/).

**Compresión de imagenes**

Todas las imágenes se copian de assets/img a tu directorio dist. Cuando construyes para producción las imágenes se comprimen con gulp-imagemin.

**BrowserSync**

La plantilla te monta un servidor local con BrowserSync en el puerto <http://localhost:8000>. Cuando haces un cambio en tus archivos,  el navegador se actualiza en tiempo real.

**Creación de guía de Estilo**

En Zurb tienen [Style Sherpa](https://foundation.zurb.com/sites/docs/style-sherpa.html), un pequeño plugin que te genera una plantilla para que puedas crear la guía de estilo para tu proyecto. Esto es genial pero queda fuera de mi objetivo actual en este proyecto.

#### Porque utilizar webpack y gulp en el mismo proyecto?

Ahora la tendencia es utilizar webpack para todo, pero digamos que webpack es más complejo mientras que Gulp es sencillo y hace bien su trabajo. Me parece bien utilizar webpack para transpilar el js porque webpack es lo que se utiliza con vue.js y react y está bien acostumbrarse.

## Utilizar la plantilla

Para utilizar la plantilla necesitas [NodeJS](https://nodejs.org/es/)(0.12 o superior) y [Git](https://git-scm.com/) instalados en tu computadora.

Puedes descargar la plantilla con Git o bajarla del repositorio de [**GitHub**](https://github.com/yuraksisa/bootstrap-starter)**.**

```bash
# Descarga la plantilla con Git
git clone https://github.com/yuraksisa/bootstrap-starter.git

# Situate en la carpeta del proyecto, e instala las dependencias

cd projectname
yarn

# Construye el proyecto
yarn start
```

Con `yarn start` arrancas Gulp, que creará el sitio en la carpeta `dist` visible desde la siguiente URL:

```bash
http://localhost:8000
```

Para crear una versión del sito para producción, con los assets comprimidos, ejecuta `yarn run build`.

## Como he creado la plantilla

### Crear la estructura de archivos

Descarga o haz un clone de [Foundation ZURB template](https://github.com/zurb/foundation-zurb-template), estudia como funciona y su estructura de archivos, pues la idea es hacer lo mismo pero remplazando los estilos y el los scripts de ZURB por los de Bootstrap.

`$ git clone` [`https://github.com/zurb/foundation-zurb-template.git`](https://github.com/zurb/foundation-zurb-template.git)

Crea un directorio para tu proyecto:

`$ mkdir my-bootstrap-starter && cd my-bootstrap-starter`

Crea la estructura de archivos de tu proyecto al estilo ZURB (desde la terminal o desde tu editor):

`$ mkdir src && cd src`

`$ mkdir assets layouts pages partials`

`$ cd src/assets`

`$ mkdir img js scss`

Crea los archivos scss y js en assets. Crea los archivos de layouts. Crea un index.html en pages y especifica el tipo de layout en sintaxis yaml.

Vamos a trabajar con [node](https://nodejs.org/es/download/) así que si no tienes node en tu máquina ya estás tardando.

Creamos un archivo package.json:

`$ npm-init`

Si no quieres que npm te haga la encuesta para rellenar el package.json añade `-y`:

`$ npm init -y`

Edita el archivo package.json y especifica gulpfile como main y añade tu configuración de los scripts.

```
 "main": "gulpfile.js",
  "scripts": {
    "start": "gulp",
    "build": "gulp build --production"
  },
```

### **Instala las dependencias**

Para instalar paquetes de node (con npm) escribe:

&#x20;`$ npm install <package_name>`

&#x20;o su abreviatura:

`$ npm i <package_name>`.

**Instala Bootstrap, jQuery y popper.js:**

`$ npm i bootstrap jquery popper.js`

**Puedes ser más intrépido y hacerlo todo en una línea:**

`$ npm init -y && npm i bootstrap jquery popper.js`

Esto añadirá las siguientes dependencias en node\_modules y aparecerá así en tu package.json:

```javascript
  "dependencies": {
    "bootstrap": "^4.1.3",
    "jquery": "^3.3.1",
    "popper.js": "^1.14.3"
  }
```

### **Instalar las dependencias de desarrollo**

Para instalar paquetes de node como dependencias de desarrollo utiliza:

`$ npm install <package_name> —save-dev`

o su atajo:

&#x20;`$ npm <package_name> -D`.

{% hint style="info" %}
Recuerda: puedes instalar paquetes uno a uno, varios a la vez, o puedes editar tu package.json manualmente y ejecutar `npm install` para que instale las dependencias.
{% endhint %}

### Trabajando con npm y yarn

{% hint style="info" %}
Para instalar paquetes de node tanto puedes utilizar npm como Yarn, simplemente decide cual usar. Para no tener problemas mejor no ir cambiando de uno a otro en el mismo proyecto.
{% endhint %}

**Comparación de comandos CLI:**

| npm5                                   | Yarn                           |
| -------------------------------------- | ------------------------------ |
| npm install                            | yarn install                   |
|                                        | yarn install --flat            |
|                                        | yarn install har               |
| npm install --no-package-lock          | yarn install --no-lockfile     |
| npm install \[package]                 | yarn add \[package]            |
| npm install \[package] --save-dev      | yarn add \[package] --dev      |
|                                        | yarn add \[package] --per      |
| npm install \[package] --save-optional | yarn add \[package] --optional |
| npm install \[package] --save-exact    | yarn add \[package] --exact    |
|                                        | yarn add \[package] --tilde    |
| npm install \[package --global         | yarn global add package        |
| npm update --global                    | yarn global upgrade            |
| npm rebuild                            | yarn add --force               |
| npm unistall \[package]                | yarn remove \[package]         |
| npm cache clean                        | yarn cache clean \[package]    |
| rm -rf node\_modules & npm install     | yarn upgrade                   |
| npm version major                      | yarn version --major           |
| npm version minor                      | yarn version --minor           |
| npm version patch                      | yarn version --patch           |

**Editar el package.json manualmente:**

En este proyecto voy a instalar todas las dependencias de desarrollo de la plantilla de ZURB menos style-sherpa, así que iré más rápido haciendo un copy paste de su package.json.

```javascript
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-plugin-transform-object-assign": "^6.22.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-register": "^6.26.0",
    "browser-sync": "^2.10.0",
    "gulp": "github:gulpjs/gulp#4.0",
    "gulp-autoprefixer": "^3.1.0",
    "gulp-babel": "^6.1.2",
    "gulp-clean-css": "^3.3.1",
    "gulp-cli": "^1.2.1",
    "gulp-concat": "^2.5.2",
    "gulp-extname": "^0.2.0",
    "gulp-if": "^2.0.0",
    "gulp-imagemin": "^2.2.1",
    "gulp-load-plugins": "^1.1.0",
    "gulp-sass": "^2.1.0",
    "gulp-sourcemaps": "^1.6.0",
    "gulp-uglify": "^1.2.0",
    "gulp-uncss": "^1.0.1",
    "js-yaml": "^3.4.6",
    "panini": "^1.3.0",
    "rimraf": "^2.4.3",
    "vinyl-named": "^1.1.0",
    "webpack": "^2.6.1",
    "webpack-stream": "^4.0.0",
    "yargs": "^3.8.0"
  }
```

{% hint style="info" %}
Si instalas un paquete por error siempre puedes eliminarlo con:

`$ npm uninstall <package_name>`
{% endhint %}

**Crea tu archivo gulpfile.js en la raíz del proyecto:**

`$ touch gulfile.babel.js`

De nuevo hacemos copy paste del gulpfile de zurb, elimina las referencias a sherpa y la tarea styleGuide pues no vamos a utilizarla.

Crea tu archivo de configuración yml.

`$ touch config.yml`

De nuevo hacemos copy paste de zurb…

**Cambiamos los Path de Sass en config.yml:**

```yaml
    #Cambiamos las rutas delos css a Foundation por las de Bootstrap:
    sass:
    - "node_modules/foundation-sites/scss"
    - "node_modules/motion-ui/src"

     sass:
    - "node_modules/bootstrap/scss"
```

**Crea un archivo de configuración de babel:**

`$ touch .babelrc`

Edita tu archivo oculto de configuración de babel:

```javascript
{
    "presets": ["es2015"],
  "compact": false
}
```

**Crea tu archivo gitignore:**

`$ touch .gitignore`

Edita el index.html y añade algo como:

&#x20;`<h1>Hellow world! </h1>`

Ejecuta `$ npm start` y tu sitio web debería abrirse en el puerto <http://localhost:8000>.

### Añadir los scripts de Bootstrap

He mantenido la estructura de Zurb template, simplemente he remplazado las rutas a los scripts de Foundation por las rutas a los scripts de Bootstrap.

He preparado los scripts de forma que tienes 2 opciones:

Importar Bootstrap completo de node\_modules o importar solo los componentes que necesites para optimizar tu aplicación:

```javascript
// Option 1: Import Full boostrap from dependencies
//import 'bootstrap';

// Option 2 : If you want to pick and choose which modules to include, comment out the above and uncomment
// the line below
require('./lib/bootstrap-explicit-pieces.js');
```

```javascript
// Core
import 'bootstrap/js/dist/util';
window.Popper = require('popper.js').default;
import 'bootstrap/js/dist/tooltip';

// Components
import 'bootstrap/js/dist/alert';
import 'bootstrap/js/dist/button';
import 'bootstrap/js/dist/carousel';
import 'bootstrap/js/dist/collapse';
import 'bootstrap/js/dist/dropdown';
import 'bootstrap/js/dist/modal';
import 'bootstrap/js/dist/popover';
import 'bootstrap/js/dist/scrollspy';
import 'bootstrap/js/dist/tab';
```

Tarea scripts tal como viene en ZURB, no necesitamos modificarla:

```javascript
let webpackConfig = {
    module: {
        rules: [{
            test: /.js$/,
            use: [{
                loader: 'babel-loader'
            }]
        }]
    }
}
// Combine JavaScript into one file
// In production, the file is minified
function javascript() {
    return gulp.src(PATHS.entries)
        .pipe(named())
        .pipe($.sourcemaps.init())
        .pipe(webpackStream(webpackConfig, webpack2))
        .pipe($.if(PRODUCTION, $.uglify()
            .on('error', e => {
                console.log(e);
            })
        ))
        .pipe($.if(!PRODUCTION, $.sourcemaps.write()))
        .pipe(gulp.dest(PATHS.dist + '/assets/js'));
}
```

Para añadir funciones solo en una página utilizamos panini:

```markup
<body class="{{page}}">

    {{> body}}

<script src="{{root}}assets/js/app.js"></script>
</body>
```

```javascript
// Index Page load
$('body.index').ready(function () {
    // For index Page coding
});
```

### Añadir los estilos de Bootstrap

Igual que con los scripts para cargar los estilos de Bootstrap podemos cargar Bootstrap completo o solamente los módulos que necesitemos:

```css
// Option A: Include all of Bootstrap

//@import "node_modules/bootstrap/scss/bootstrap";

// Option B: Include parts of Bootstrap

// // Required
@import "node_modules/bootstrap/scss/functions";
@import "node_modules/bootstrap/scss/variables";
@import "node_modules/bootstrap/scss/mixins";

// // Optional
@import 'node_modules/bootstrap/scss/alert';
@import 'node_modules/bootstrap/scss/badge';
@import 'node_modules/bootstrap/scss/breadcrumb';
@import 'node_modules/bootstrap/scss/button-group';
@import 'node_modules/bootstrap/scss/buttons';
@import 'node_modules/bootstrap/scss/card';
@import 'node_modules/bootstrap/scss/carousel';
@import 'node_modules/bootstrap/scss/close';
// More Bootstrap parts...
```

Tarea styles tal como viene en la plantilla de ZURB, no necesitamos modificarla:

```javascript
// Compile Sass into CSS
// In production, the CSS is compressed
function sass() {
    return gulp.src('src/assets/scss/app.scss')
        .pipe($.sourcemaps.init())
        .pipe($.sass({
                includePaths: PATHS.sass
            })
            .on('error', $.sass.logError))
        .pipe($.autoprefixer({
            browsers: COMPATIBILITY
        }))
        // Comment in the pipe below to run UnCSS in production
        //.pipe($.if(PRODUCTION, $.uncss(UNCSS_OPTIONS)))
        .pipe($.if(PRODUCTION, $.cleanCss({
            compatibility: 'ie9'
        })))
        .pipe($.if(!PRODUCTION, $.sourcemaps.write()))
        .pipe(gulp.dest(PATHS.dist + '/assets/css'))
        .pipe(browser.reload({
            stream: true
        }));
}
```

**Para organizar los CSS he seguido la metodología SMACSS:**

SMACSS divide los CSS en categorías:

* Base
* Layout
* Module
* State
* Theme

{% hint style="info" %}
Organizar los CSS según la metodología SMACS solo es una sugerencia, puedes eliminar la carpeta parts y organizar los CSS como quieras.
{% endhint %}

### **Añadir fontawesome 5 con npm:**

Puedes instalar fontawesome en tus node\_modules con el siguiente comando:

`$ npm install @fortawesome/fontawesome-free`

Tendrás que copiar tus fuentes de node\_modules a dist, esto lo puede hacer con Gulp:

```javascript
// Copy Fontawesome fonts into dist folder
function fontawesome() {
    return gulp.src("./node_modules/@fortawesome/fontawesome-free/webfonts/*.{woff,woff2,eot,svg,ttf}")
        .pipe(gulp.dest(PATHS.dist + '/assets/fonts'));
}
```

Ahora tienes que editar tus css:

He creado un archivo \_variables.scss de variables para fontawesome, en la variable `fa-font-path` indicas la ruta a la carpeta de fontawesome en dist desde el css final:

```css
$fa-font-path: '../fonts';
```

Y otro archivo \_main.scss donde importo la librería:

```css
// Variable overrides
@import 'variables';
// Core
@import 'node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss';
@import 'node_modules/@fortawesome/fontawesome-free/scss/variables';
@import 'node_modules/@fortawesome/fontawesome-free/scss/mixins';
@import 'node_modules/@fortawesome/fontawesome-free/scss/core';
@import 'node_modules/@fortawesome/fontawesome-free/scss/larger';
@import 'node_modules/@fortawesome/fontawesome-free/scss/fixed-width';
@import 'node_modules/@fortawesome/fontawesome-free/scss/list';
@import 'node_modules/@fortawesome/fontawesome-free/scss/bordered-pulled';
@import 'node_modules/@fortawesome/fontawesome-free/scss/animated';
@import 'node_modules/@fortawesome/fontawesome-free/scss/rotated-flipped';
@import 'node_modules/@fortawesome/fontawesome-free/scss/stacked';
@import 'node_modules/@fortawesome/fontawesome-free/scss/icons';
@import 'node_modules/@fortawesome/fontawesome-free/scss/screen-reader';
// Fonts
@import 'node_modules/@fortawesome/fontawesome-free/scss/regular';
@import 'node_modules/@fortawesome/fontawesome-free/scss/solid';
@import 'node_modules/@fortawesome/fontawesome-free/scss/brands';
```

### Referencias

**Links**

* [Combine Webpack with Gulp 4](https://css-tricks.com/combine-webpack-gulp-4/)
* [using webpack with gulpjs](https://pawelgrzybek.com/using-webpack-with-gulpjs/)
* [Bootstrap framework best practises](https://hackernoon.com/bootstrap-framework-best-practises-b1d81c02d6cf)
* [All about the ZURB Template](https://zendev.com/2017/09/05/front-end-development-kickstarter-zurb-template.html#scss)
* [Scalable and Modular Architecture for CSS](https://smacss.com/)

**Tools**

* [Gulp](https://gulpjs.com/)
* [Webpack](https://webpack.js.org/)
* [Sass](http://sass-lang.com/)
* [Panini](https://github.com/zurb/panini)
* [Browsersync](https://www.browsersync.io/)
* [gulp-imagemin](https://github.com/sindresorhus/gulp-imagemin)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://netinetidesign.gitbook.io/bootstrap-starter/master.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
