WebDev On Steroids – Bienvenido a 2016 – Ahora vosotros



WebDev On Steroids – Bienvenido a 2016 – Ahora vosotros

2 2


webDev2015

Presentación para la charla webDev2015

On Github Viroide / webDev2015

WebDev On Steroids

Bienvenido a 2016

Creado por Jon E. Eguiluz / @viroide

Jon E. Eguiluz

{
    "name": "Jon E. Eguiluz",
    "title": "webDev ninja",
    "subtitle": "I ♥ coding",
    "languages": ["html", "css", "js", "python", "groovy"],
    "extra_knowledge": ["git", "django", "grails", "gulp", "bash scripting", "linux"],
    "experience": "6 years as hard WebDev",
    "able_to_teaching": true,
    "link": "https://www.twitter.com/viroide"
}
                    

Patrocinadores

Ahora vosotros

¿A qué os dedicáis?

¿Con qué herramientas?

¿Os sentís comodos o acomodados?

De esto...

...a esto

Indice

  • Editores de texto de este siglo: SublimeText3, Coda, Atom
  • Plugins para editores. (Sublime)
  • Terminal + esteroides: Tmux, zsh, Prezto/Oh my bash
  • Gestion de paquetes web: Bower
  • Automatizadores de tareas: Grunt vs Gulp vs webPack vs npm scripts...
  • .dotfiles: configuraciones útiles para casi todo

Editores de texto

  • SublimeText 3
  • Coda
  • Atom
  • (¿sugerencias?)

Sublime Text 3

  • Cursor múltiple
  • Goto lo que haga falta
  • Todos los comandos en la paleta
  • Snippets
  • Settings en un json
  • Mini-mapa
  • Themes y plugins a paladas
  • Rápido y estable
MULTISELECT: ⌘ + d
GOTO: ⌘ + p
PALETA: ⌘ + ⇧ + p

⌘⌥⇧
                    

Coda

Atom

  • Es de github.
  • Gratis y código libre.
  • Integración con Git
  • Install and fun ☺
  • Plugins y themes bien seleccionados.
  • Interface bastante chulo.

Muchos más

Plugins para editores. (Sublime)

Para ST3 hay plugins para todo, de hecho demasiados.

Hay que elegir solo lo que necesites, todo se carga en RAM y no queremos frenar a esta mala bestia.

Mis plugins

{"installed_packages":
    [
        "All Autocomplete",
        "BracketHighlighter",
        "Color Highlighter",
        "ColorPicker",
        "Diffy",
        "Emmet",
        "Emmet Css Snippets",
        "Git",
        "Jade",
        "Markdown Preview",
        "Package Control",
        "Sass",
        "SideBarEnhancements",
        "Stylus",
        "SublimeLinter",
        "SublimeLinter-csslint",
        "SublimeLinter-jshint",
        "SublimeLinter-pyflakes",
        "Theme - Afterglow",
    ]
}
                        

Más plugins

★Terminal★

La terminal es nuestra amiga, cuidemosla adecuadamente y démosle todo el cariño y esteroides que podamos.

Tmux vs terminator

zsh

  • Autocomplete molon
  • Extension de path
  • Corrector de tecleo para "macnos"
  • History mas inteligente
  • Auto-highlight

Oh my zsh!

Auto-tuneo de todo el shell

Prezto

Lo mismo pero + sencillo + ordenado y + bonito

Mis plugins

{
  "git",
  "gulp",
  "sublime",
  "wd",
  "brew",
  "grails",
  "jsontools",
  "history"
}

                        

Bower

Install dependencies like a sir.

bower.json

{
  [...],
  "dependencies": {
    "headjs": "~1.0.3"
  },
  "devDependencies": {
    "bootstrap": "~3.3.5"
  }
}

                        

Meta-lenguajes

De css

SaSS, Less, stylus...

De js

Coffee, ECMASCRIPT 7, TypeScript

De html

Jade, Mustache.js, EJS...

Grunt vs Gulp VS WebPack VS NPM scripts

Pros y contras

  • Grunt
  • +plugins
  • configuracion
  • Gulp
  • +rápido
  • hype
  • Brunch
  • como viene
  • -plugins

Grunt

module.exports = function( grunt ) {
    'use strict';

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        meta:{
            banner : '/* <%= pkg.name %> v<%= pkg.version %> - <%= grunt.template.today("yyyy/m/d") %>\n' +
                    '   <%= pkg.homepage %>\n' +
                    '   Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>' +
                    ' - Licensed <%= (pkg.license).join(", ") %> */\n',
            path : "emoweb/media/"
        },
        stylus: {
          compileDist: {
            options: {compress: true},
            files: {
              '<%= meta.path %>css/dist/estilos.css':
              ['<%= meta.path %>css/estilos.styl', '<%= meta.path %>css/icons.styl', '<%= meta.path %>css/graficas.styl'] // 1:1 compile
              // 'path/to/another.css': ['path/to/sources/*.styl', 'path/to/more/*.styl'] // compile and concat into single file
            }
          },
          compileDebug: {
            options: {compress: false,linenos: true},
            files: {
              '<%= meta.path %>css/dist/estilos_debug.css':
              ['<%= meta.path %>css/estilos.styl', '<%= meta.path %>css/icons.styl', '<%= meta.path %>css/graficas.styl'] // 1:1 compile
              // 'path/to/another.css': ['path/to/sources/*.styl', 'path/to/more/*.styl'] // compile and concat into single file
            }
          }
        },
        uglify: {
            options: {
                banner:"<%= meta.banner %>",
                report: 'gzip'
            },
            dist: {
                files: {
                    // 'yokse/static/dist/yokse.min.js': '<%= concat.dist.dest %>',
                    '<%= meta.path %>js/dist/all.min.js':
                     ['<%= meta.path %>components/scroll/jquery.mCustomScrollbar.min.js',
                       '<%= meta.path %>components/jquery-cookie/jquery.cookie.js',
                       '<%= meta.path %>js/main.js',
                       '<%= meta.path %>js/coffee.js'  ]
                }
            },
            beauty: {
                options: {
                    beautify: true
                },
                files: {
                    // 'yokse/static/dist/yokse.min.js': '<%= concat.dist.dest %>',
                    '<%= meta.path %>js/dist/beauty.min.js':
                    ['<%= meta.path %>components/scroll/jquery.mCustomScrollbar.min.js',
                       '<%= meta.path %>components/jquery-cookie/jquery.cookie.js',
                       '<%= meta.path %>js/main.js',
                       '<%= meta.path %>js/coffee.js'  ]
                }
            }
        },
        coffee:{
            compile: {
                files: {
                  '<%= meta.path %>js/coffee.js':
                  '<%= meta.path %>js/coffee/source.coffee', // 1:1 compile, identical output to join = false
                  // 'path/to/another.js': ['path/to/sources/*.coffee', 'path/to/more/*.coffee'] // concat then compile into single file
                }
          },
        },
        notify: {
            estilos: {
              options: {
                title: 'Nuevos stylos!!',  // optional
                message: 'grunt grunt gruuuunt', //required
              }
            },
            jss: {
              options: {
                title: 'Nuevos JSs!!',  // optional
                message: 'grunt grunt gruuuunt', //required
              }
            },
            deploy: {
              options: {
                title: 'DESPLEGAD!!',  // optional
                message: 'grunt grunt gruuuunt', //required
              }
            },
            coffee: {
                options: {
                    title: 'CAFECITO CALIENTEEE!!',  // optional
                    message: 'grunt grunt gruuuunt', //required
                }
            }
        },

        jshint: {
            all: ['Gruntfile.js', '<%= meta.path %>js/main.js', '<%= meta.path %>js/coffee.js']
        },


        watch: {
            options: {livereload: true},
            fruntfile:{
                files: ['Gruntfile.js'],
                tasks: ['jshint']
            },
            javascript: {
                files: ['<%= meta.path %>js/*.js'],
                tasks: ['jshint','uglify', 'notify:jss']
            },
            stiles: {
                files: ['<%= meta.path %>css/*.styl'],
                tasks: ['stylus', 'notify:estilos']
            },
            coffee:{
                files: '<%= meta.path %>js/coffee/source.coffee',
                tasks: ['coffee:compile', 'notify:coffee']
            }
        },


    });

    // grunt.loadNpmTasks( 'grunt-contrib-sass' );
    grunt.loadNpmTasks( 'grunt-contrib-watch' );
    grunt.loadNpmTasks( 'grunt-contrib-clean' );
    grunt.loadNpmTasks( 'grunt-contrib-concat' );
    grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
    grunt.loadNpmTasks( 'grunt-contrib-uglify' );
    grunt.loadNpmTasks( 'grunt-contrib-stylus' );
    grunt.loadNpmTasks( 'grunt-notify');
    grunt.loadNpmTasks('grunt-contrib-coffee');
    grunt.loadNpmTasks('grunt-contrib-jshint');



    grunt.registerTask('compilar', [
      'jshint',
      'uglify',
      'stylus',
      'notify:compilar'
      ]);
    grunt.registerTask('desplegar', [
        'gitcommit',
        'gitpush',
        'sshexec:deploy',
        'notify:deploy']);

    grunt.registerTask('commit', [
        'gitcommit',
        'gitpush'
    ]);

    // grunt.registerTask( 'css', ['stylus'] );

};

                        

Gulp

'use strict';

var gulp        = require('gulp'),
    rename      = require('gulp-rename'),
    uglify      = require('gulp-uglify'),
    concat      = require('gulp-concat'),
    sourcemaps  = require('gulp-sourcemaps'),
    stylus      = require('gulp-stylus'),
    jshint      = require('gulp-jshint'),
    livereload  = require('gulp-livereload'),
    watch       = require('gulp-watch'),
    imagemin    = require('gulp-imagemin'),
    header      = require('gulp-header'),
    replace     = require('gulp-token-replace'),
    nib         = require('nib'),
    jade        = require('gulp-jade');

var pkg         = require('./package.json'),
    config      = require('./config/config.json');
    config.debug.version = pkg.version;
    config.build.version = pkg.version;


var templatespath        = config.templatespath,
    srcPath     = config.srcPath,
    distPath    = config.distPath;

var banner = ['/**',
  ' * <%= pkg.name %> - <%= pkg.description %>',
  ' * @version v<%= pkg.version %>',
  ' * @author <%= pkg.author %>',
  ' * @license <%= pkg.license %>',
  ' */',
  ''].join('\n');

gulp.task('html', function() {

  gulp.src(srcPath+'/templates/*.jade')
    .pipe(jade({
      locals: config.debug,
      pretty: true
    }))
    .pipe(gulp.dest(templatespath))
    .pipe(livereload());
});

gulp.task('html-build', function() {

  gulp.src(srcPath+'/templates/*.jade')
    .pipe(jade({
      locals: config.build
    }))
    .pipe(gulp.dest(templatespath))
    .pipe(livereload());
});


gulp.task('js-build', function () {
  return gulp.src(srcPath+'/js/*.js')
    .pipe(jshint())
    .pipe(jshint.reporter('default'))
    .pipe(uglify())
    .pipe(concat(pkg.name+'.min.js'))
    .pipe(header(banner, { pkg : pkg } ))
    .pipe(gulp.dest(distPath+"/js/"))
    .pipe(livereload());
});

gulp.task('js', function () {
  return gulp.src(srcPath+'/js/*.js')
    .pipe(jshint())
    .pipe(jshint.reporter('default'))
    .pipe(concat(pkg.name+'.js'))
    .pipe(header(banner, { pkg : pkg } ))
    .pipe(gulp.dest(distPath+"/js/"))
    .pipe(livereload());
});

gulp.task('css-build', function() {
  return gulp.src(srcPath+'/css/*.styl')
    .pipe(stylus({ use: nib(), compress: true }))
    .pipe(rename({ basename: pkg.name  , suffix:".min"}))
    .pipe(header(banner, { pkg : pkg } ))
    .pipe(gulp.dest(distPath+'/css/'));
});

gulp.task('css', function() {
  return gulp.src(srcPath+'/css/*.styl')
    .pipe(sourcemaps.init())
    .pipe(stylus({use: nib(),linenos: true}))
    .pipe(rename({ basename: pkg.name}))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(distPath+'/css/'))
    .pipe(livereload());

});

gulp.task('img', function () {
    return gulp.src(distPath+'/img/*.*')
        .pipe(imagemin())
        .pipe(gulp.dest(distPath+'/img/'));
});


gulp.task('watch', function() {
  livereload.listen();
  gulp.watch(srcPath+'templates/*.jade', ['html']);
  gulp.watch(srcPath+'css/*.styl', ['css']);
  gulp.watch(srcPath+'js/*.js', ['js']);
});


gulp.task('server', ['js-build', 'css-build', 'html-build']);
gulp.task('build', ['js-build', 'css-build', 'img', 'html-build']);
gulp.task('build-js', ['js-build']);
gulp.task('build-css', ['css-build']);
gulp.task('build-html', ['html-build']);

gulp.task('dev', ['js', 'css', 'html']);


gulp.task('default', ['js', 'css', 'html']);

                        

✌ Aleluya ✌

Comparte todas tus .configs

Lista de github

“Simply start making stuff.”

Shawn Wilkins 2013

Workflow

Creamos la carpeta y el package.json

mcd prueba101
npm init
                

Instalamos gulp en local

npm install --save-dev gulp

Creamos el gulp file

subl gulpfile.js

Creamos la estructura de carpetas

mkdir src src/stylus src/coffee src/jade dist
              

Copiar la plantilla de gulp

Edita las default task

gulp.task('css', function() {
  return gulp.src(srcPath+'/stylus/*.styl')
    .pipe(stylus({use: nib(),linenos: true}))
    .pipe(rename({ basename: pkg.name}))
    .pipe(gulp.dest(distPath+'/css/'))
    .pipe(livereload());

});
              

Configura el config.json

Mi truco para volverme menos loco
{
  "debug":{
    "path_js":  "./js/prueba101.js",
    "path_css":"./css/prueba101.css",
    "livereload": true,
    "bootstrap_css": "../lib/bootstrap/dist/css/bootstrap.min.css",
    "bootstrap_js": "../lib/bootstrap/dist/js/bootstrap.min.js",
    "jquey": "../lib/jquery/dist/jquery.min.js"

  },
  "build":{
    "path_js":  "/js/prueba101.min.js",
    "path_css":"/css/prueba101.min.css",
    "livereload": false,
    "bootstrap_css": "//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css",
    "bootstrap_js": "//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js",
    "jquey": "//code.jquery.com/jquery-1.11.2.min.js"
  },
  "srcPath" :"./src",
  "distPath" :"./dist"
}

Instalar todos los módulos con gulp

npm install gulp-rename gulp-uglify gulp-concat gulp-sourcemaps gulp-stylus
gulp-jshint gulp-livereload gulp-watch gulp-header gulp-replace
nib gulp-jade gulp-coffee gulp-token-replace --save-dev

Instalar bower y usarlo para bajar dependencias

Lo inicializamos para que cree el bower.json

bower init

Copiar el .bowerrc

Y configuramos la ruta

Instalamos bootstrap

bower install bootstrap --save-dev

Probamos los comandos de gulp

Con/sin uglyfied

links locales o a CDNs

El config.json gloria vendita

Compartir el proyecto

Iniciar git

git init

Añadimos a git solo lo que sea imprescindible

git add *.json
git add src
git add gulpfile.js
git add .bowerrc
              

Primer commit

git commit -am "Primer commit u Hola mundo"

Creamos un repositorio remoto

Por ejemplo github

Añadimos el repo remoto a nuestro git local

git remote add origin git@github.com:Viroide/prueba101.git

Y "pusheamos"

git push -u origin master

Que se lo baje un compi

Crear carpeta

mcd prueba102

Clonar repo

git clone https://github.com/Viroide/prueba101.git ./

Instalar modulos npm

npm install

Instalar dependencias web

bower install

El día a día

Tmux

con detach podemos dejar todo para mañanaDeja los puertos bloqueados

Terminator

guardas la config en un archivoNo es tan flipado como el tmux

¡Alias!

alias prueba101_env="chromium-browser 127.0.0.1:8000 &&
  subl --project ~/proyectos/prueba101.sublime-project &&
  cd /home/viroide/proyectos/prueba101/ &&
  terminator -mbl prueba101 &"

Despues de este ejemplo...

¿Qué necesitáis vosotros?

  • ¿ less/sass/stylus ?
  • ¿ Qué variables han de ir al config?
  • ¿ Qué tareas necesito ?

Configuremos un entorno más real!

Patrocinadores

¿Preguntas?

WebDev On Steroids Bienvenido a 2016 Creado por Jon E. Eguiluz / @viroide