Bootstrap 4 starter (ZURB Style)

La plantilla de ZURB es genial por defecto y quería un sistema de construcción de páginas similar con Bootstrap.

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 y te permite crear layouts, partials, includes etc… como si estubieras trabajando con líquid en un Jekyll.

Aprender más sobre Panini.

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.

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, 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(0.12 o superior) y Git instalados en tu computadora.

Puedes descargar la plantilla con Git o bajarla del repositorio de GitHub.

# 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:

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, 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

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 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:

$ npm install <package_name>

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:

"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:

$ npm <package_name> -D.

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.

Trabajando con npm y yarn

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.

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.

"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"
}

Si instalas un paquete por error siempre puedes eliminarlo con:

$ npm uninstall <package_name>

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:

#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:

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

Crea tu archivo gitignore:

$ touch .gitignore

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

<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:

// 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');
// 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:

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:

<body class="{{page}}">
{{> body}}
<script src="{{root}}assets/js/app.js"></script>
</body>
// 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:

// 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:

// 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

Organizar los CSS según la metodología SMACS solo es una sugerencia, puedes eliminar la carpeta parts y organizar los CSS como quieras.

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:

// 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:

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

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

// 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

Tools