Madrid JS
Octubre2014
Build
Drupal e integración continua
Desarrollo de juegos en html5
Señor agente,eso es tabaco de liar
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*
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/
RECIENTE
WTF
hasta make
PLUGIN
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
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
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/'
}]
}
},
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']
}
}
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/'));
});
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/
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");
});
})
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']
}
},
grunt.registerTask('build', [
'clean:dist',
'wiredep',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'filerev',
'usemin',
'htmlmin'
]);
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
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
Referencias