Slide 1

Slide 1 text

JavaScript build workflow Lessons learned Piotr Lewandowski @constjs

Slide 2

Slide 2 text

npm install npm install ­g bower bower install npm install ­g grunt grunt setup ./gradlew run npm gradle

Slide 3

Slide 3 text

use npm scripts + more control on remote env e.g. Jenkins + all packages can be local { "scripts": { "postinstall": "bower install", "start": "grunt", "release": "grunt build ­­release" } } > npm install > npm start > npm run release

Slide 4

Slide 4 text

do we need bower? + flat directory tree + simple dependency resolution + no big problems actually - the same work as npm - additional tool in stack - no clear future

Slide 5

Slide 5 text

nope. not yet. still missing some front-end packages can I switch to npm?

Slide 6

Slide 6 text

npm goals for 2016 npm for front-end developers 1. Treat git dependencies like registry dependencies. 2. Front-end asset installer. 3. Support the new ECMAScript module system. https://github.com/npm/npm/wiki/Roadmap

Slide 7

Slide 7 text

Don't install libraries with 10 lines of code

Slide 8

Slide 8 text

npm + Jenkins = ? build = 200MB and 25k files* Cache problems Quota Limit of inodes Internet connection *backend and other stuff per job = ~1GB

Slide 9

Slide 9 text

npm install ­­no­optional ­­cache­min=999999 ­­quiet npm + Jenkins = ❤ npm 3 is even better better architecture less files less space npm 2+

Slide 10

Slide 10 text

build

Slide 11

Slide 11 text

we use Grunt 1000+ lines of config file a bit messy ... not only in config file ... regular changes needed

Slide 12

Slide 12 text

clean config an unexpected journey

Slide 13

Slide 13 text

single responsibility one reason to change a file separate list of libraries list of modules encapsulated tasks linters optimizations releases

Slide 14

Slide 14 text

instead of... dashboard: { files: { 'dist/js/dashboard.min.js': [ 'src/modules/dashboard/module.js', '!src/modules/dashboard/route.js' 'src/modules/dashboard/**/*.js' ] } // ... repeat for 40 other modules // ... add new tasks at the end of file

Slide 15

Slide 15 text

create project abstraction var APP_MODULES = [ { module: 'app.modules.monitor', dir: 'monitor', outFile: 'monitor' }, { module: 'app.modules.dashboard', dir: 'dashboard', outFile: 'dashboard' }, { module: 'app.modules.account', dir: 'account', outFile: 'account' } ]; important: project files structure RegEx friendly

Slide 16

Slide 16 text

envoriment variables var properties = { VERSION: version, API: '/* @echo API */', TYPE: '/* @echo TYPE */', REVISION: '/* @echo REVISION */', DATE: '/* @echo DATE */' }; one file! can be Injected anywhere can be unit tested list of all possibilities in one place

Slide 17

Slide 17 text

the same rules as clean code Gandalf approves

Slide 18

Slide 18 text

gulp.task("compile", ["tslint"], () => { return gulp.src("src/**/*.ts") .pipe(sourcemaps.init()) .pipe(tsc(tsProject)).js .pipe(ngAnnotate()) .pipe(sourcemaps.write(".")) .pipe(gulp.dest("build")); }); Gulp > Grunt for more complex apps + simple API + code over configuration + easily separated for many files

Slide 19

Slide 19 text

separated front-end ... you're gonna have a bad time + less team communication required + easier setup for front-end devs - synchronization problem - security

Slide 20

Slide 20 text

single page app = different security

Slide 21

Slide 21 text

serve app from back-end resources if your app is the only client of your API

Slide 22

Slide 22 text

End Of File Thanks