Madrid JS
Octubre2014
Build
About
Drupal e integración continua
Desarrollo de juegos en html5
Señor agente,eso es tabaco de liar
QUÉ ES?
Un proceso
Automatizado
Que genera un entregable
necesario para la integración continua
y facilita la entrada de nuevos miembros al equipo
PREPARE
COMPILE
UNIT TEST
PACKAGE
INTEGRATION TEST
VERIFY
npm install
bower install
sass less coffee
karma mocha qunit jasmine
zip nar min
pioneer selenium phantomJS
jslint jshint coverage
TOOLS
Task oriented
Product oriented
Ant
Grunt
Gulp*
MsBuild ..
Maven
Make
Rake*
Reinventar la rueda?
After a lot of experimentation and failed attempts, I learned that writing and maintaining a suite of “javascript build process” tasks in a gigantic, monolithic Makefile / Jakefile / Cakefile / Rakefile / ?akefile that was shared across all my projects was overwhelming, especially considering how many projects I have. That approach just wasn’t going to scale to meet my needs.
In the end, I realized that a task-based build tool with built-in, commonly used tasks was the approach that would work best for me. Unfortunately, I couldn’t find a build tool that worked the way that I wanted. So I built one.
2012- Why grunt ?
http://benalman.com/news/2012/08/why-grunt/
Los gruñidos de mi build
uN POCO DE HISTORIA... *
RECIENTE
WTF
CUál?
El que más te guste
hasta make
Coz it haz all the bitches
SETUP
PLUGIN
GENERALIDADES
Registrar una tarea
grunt.registerTask('build', [
'miTarea',
'miOtraTarea'
]);
Instalar un plugin
npm install --save grunt-contrib-uglify
Cargar un plugin
grunt.loadNpmTasks('grunt-contrib-uglify');
Cargarlos todos
require('load-grunt-tasks')(grunt);
Configurar una tarea
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build: {
src: 'src/<%= pkg.name %>.js',
dest: 'build/<%= pkg.name %>.min.js'
}
}
});
// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-uglify');
// Default task(s).
grunt.registerTask('default', ['uglify']);
};
Invocar una tarea
grunt serve:dist
FLOW
PREPARE
npm instal
bower install
//npm install -g grunt-cli
//npm install -g bower
language: node_js
node_js:
- "0.10"
before_install:
- npm install -g grunt-cli
- npm install -g bower
install:
- npm install
- bower install
COMPILE
compass: {
options: {
sassDir: '<%= yeoman.app %>/styles',
cssDir: '.tmp/styles',
generatedImagesDir: '.tmp/images/generated',
imagesDir: '<%= yeoman.app %>/images',
javascriptsDir: '<%= yeoman.app %>/scripts',
fontsDir: '<%= yeoman.app %>/styles/fonts',
importPath: './bower_components',
httpImagesPath: '/images',
httpGeneratedImagesPath: '/images/generated',
httpFontsPath: '/styles/fonts',
relativeAssets: false,
assetCacheBuster: false,
raw: 'Sass::Script::Number.precision = 10\n'
},
dist: {
options: {
generatedImagesDir: '<%= yeoman.dist %>/images/generated'
}
},
server: {
options: {
debugInfo: true
}
}
}
sass: {
options: {
sourceMap: true
},
dist: {
files: {
'main.css': 'main.scss'
}
}
}
autoprefixer: {
options: {
browsers: ['last 1 version']
},
dist: {
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '{,*/}*.css',
dest: '.tmp/styles/'
}]
}
},
UNIT TEST
karma: {
unit: {
configFile: 'test/karma.conf.js',
singleRun: true
}
}
mocha: {
test: {
src: ['tests/**/*.html'],
},
},
mochaTest: {
test: {
options: {
reporter: 'spec',
captureFile: 'results.txt', // Optional
quiet: false // Optional
},
src: ['test/**/*.js']
}
}
PACKAGE
HTML minification
CSS minification / concatenation
Uglify/Concat
Update references
Revision
<!-- build:css style.css -->
<link rel="stylesheet" href="css/clear.css"/>
<link rel="stylesheet" href="css/main.css"/>
<!-- endbuild -->
<!-- build:js js/lib.js -->
<script src="../lib/angular-min.js"></script>
<script src="../lib/angular-animate-min.js"></script>
<!-- endbuild -->
<!-- build:js1 js/app.js -->
<script src="js/app.js"></script>
<script src="js/controllers/thing-controller.js"></script>
<script src="js/models/thing-model.js"></script>
<script src="js/views/thing-view.js"></script>
<!-- endbuild -->
<!-- build:remove -->
<script src="js/localhostDependencies.js"></script>
<!-- endbuild -->
useminPrepare: {
html: ['app/html/**.html'],
options: {
dest: '<%= appRoutes.dist %>'
}
},
usemin: {
html: ['dist/app/**/**.html'],
css: ['<%= appRoutes.dist %>/style/{,*/}*.css'],
options: {
dirs: ['<%= appRoutes.dist %>'],
assetsDirs: ['<%= appRoutes.dist %>']
}
}
var usemin = require('gulp-usemin');
var uglify = require('gulp-uglify');
var minifyHtml = require('gulp-minify-html');
var minifyCss = require('gulp-minify-css');
var rev = require('gulp-rev');
gulp.task('usemin', function() {
gulp.src('./*.html')
.pipe(usemin({
css: [minifyCss(), 'concat'],
html: [minifyHtml({empty: true})],
js: [uglify(), rev()]
}))
.pipe(gulp.dest('build/'));
});
IMAGES
imagemin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/images',
src: '{,*/}*.{png,jpg,jpeg,gif}',
dest: '<%= yeoman.dist %>/images'
}]
}
},
O probar grunt-webp
https://developers.google.com/speed/webp/
INTEGRATION TEST
karma: {
e2e: {
configFile: 'karma-e2e.conf.js',
singleRun: true
}
},
'use strict';
describe('E2E: Testing Routes:', function () {
beforeEach(function() {
browser().navigateTo('/');
});
it('test', function() {
browser().navigateTo('#/');
expect(browser().location().path()).toBe("/list_persons");
});
})
VERIFY
jshint: {
options: {
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
},
all: {
src: [
'Gruntfile.js',
'<%= yeoman.app %>/scripts/{,*/}*.js'
]
},
test: {
options: {
jshintrc: 'test/.jshintrc'
},
src: ['test/spec/{,*/}*.js']
}
},
BUILD
grunt.registerTask('build', [
'clean:dist',
'wiredep',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'filerev',
'usemin',
'htmlmin'
]);
DEmo
Evolve Your Deployment System Incrementally
Somos capaces de desplegar AUTOMÁTICAMENTE?
Touch
touch gulpfile.js
touch Gruntfile.js
touch Makefile
npm install grunt --save
npm install gulp --save
npm install -g grunt-cli
npm install -g gulp
Karma
npm install grunt-karma --save-dev
npm install gulp-karma --save-dev
/* ... */
karma: {
unit: {
configFile: 'karma.conf.js',
singleRun: true,
reporters: ['mocha'],
browsers: ['PhantomJS']
}
}
/* ... */
grunt.registerTask('test', ['karma']);
gulp.task('test', function (done) {
karma.start({
configFile: __dirname + '/karma.conf.js',
singleRun: true
}, done);
});
npm install karma --save-dev
KARMA = ./node_modules/karma/bin/karma
test: karma build
Additional karma config
npm install karma-jasmine //Jasmine Tests
npm install karma-phantomjs-launcher //Launcher
npm install karma-mocha-reporter //Reporters
npm install karma-sinon //Sinon. Yeah
karma.conf.js
module.exports = function(config) {
config.set({
basePath: './',
frameworks: ['jasmine', 'sinon'],
// list of files / patterns to load in the browser
files: [
'bower_components/jquery/dist/jquery.js',
'bower_components/underscore/underscore.js',
'bower_components/backbone/backbone.js',
'app/**/**.js',
'test/**/*.js'
],
// list of files to exclude
exclude: [],
singleRun: true,
reporters: ['mocha'],
browsers: ['PhantomJS']
});
};
Karma test output
gulp test
grunt test
make test
Creando Un plugin
Grunt
npm install -g grunt-init
git clone git://github.com/gruntjs/grunt-init-gruntplugin.git ~/.grunt-init/gruntplugin
grunt-init gruntplugin
//http://gruntjs.com/creating-plugins
npm install -g generator-gruntplugin
yo gruntplugin
//https://github.com/yeoman/generator-gruntplugin
Yeoman generator
Gulp
npm install -g generator-gulp-plugin
yo gulp-plugin
https://github.com/gulpjs/gulp/blob/master/docs/writing-a-plugin/README.md
https://github.com/sindresorhus/gulp-react/blob/master/index.js
Lecturas adecuadas
- http://yeoman.io/blog/performance-optimization.html
- https://github.com/tooling/book-of-modern-frontend-tooling
- https://github.com/substack/stream-handbook
Referencias
- Brunch http://brunch.io/
- Gulp http://gulpjs.com/
- Grunt http://gruntjs.com/
- Bower http://bower.io/
- Yeoman http://yeoman.io/
- Lineman http://linemanjs.com/
- Grunt usemin https://github.com/yeoman/grunt-usemin
- Karma http://karma-runner.github.io/
- NAR https://github.com/h2non/nar
- VINYL FS https://github.com/wearefractal/vinyl-fs
- MAKE "the ultimate front end build tool" https://algorithms.rdio.com/post/make/
Los gruñidos de mi build
By rafinskipg
Los gruñidos de mi build
- 1,561