Web pack, es6, and angular on the front end.
Webpack
A module bundler
Web Development is complex
We need tools that make us better developers
- Minify && Concat Javascript
- Minify && Concat CSS
- Vendor Prefix CSS
- Compile SASS?
- Transpile es6/Typescript
- Run unit tests
- Run e2e tests
- Run a development server
- Lint our Javascript
- Dependency Management
- Tree shaking
- Provide a developer and a build mode
Why Webpack
- Purpose driven.
- Webpack is a module bundler for front end development.
- Grunt/Gulp are task runners.
- A lot of mind share
- Plenty of tutorials, SO's, and code laying around to help us accomplish our goals.
- It plays well with es6 and NPM.
- It's fast.
How Do I use it as a developer?
{
"name": "yops",
"version": "1.0.0",
"description": "Ye Old Programme Shoppe",
"main": "gs-yops.js",
"scripts": {
"start": "node gs-yops",
"build": "webpack --config webpack.build.js --bail",
"dev": "webpack-dev-server --history-api-fallback --inline --progress",
"test": "karma start",
"test:live": "karma start --auto-watch --no-single-run"
},
"repository": {
"type": "git",
"url": "git+ssh://git@bitbucket.org/tssherpa/yops.git"
},
"author": "Kim Dang (kdang@globesherpa.com)",
"license": "ISC",
"homepage": "https://bitbucket.org/tssherpa/yops#readme",
"dependencies": {
"angular": "^1.5.0",
"angular-route": "^1.5.0",
"angular-ui-router": "^0.2.18",
"babel-polyfill": "^6.5.0",
"babel-runtime": "^6.5.0",
"bootstrap": "^3.3.6",
"config": "^1.19.0",
"express": "^4.13.4",
"gamma-logger": "git+ssh://git@bitbucket.org/tssherpa/gamma-logger.git",
"newrelic": "^1.25.1"
},
"devDependencies": {
"angular-mocks": "^1.5.0",
"autoprefixer": "^6.3.2",
"babel-core": "^6.5.1",
"babel-loader": "^6.2.2",
"babel-preset-es2015": "^6.5.0",
"chai": "^3.5.0",
"chai-as-promised": "^5.2.0",
"clean-webpack-plugin": "^0.1.8",
"compression-webpack-plugin": "0.2.0",
"css-loader": "^0.23.1",
"eslint": "^1.10.3",
"eslint-config-angular": "^0.4.0",
"eslint-loader": "^1.2.1",
"eslint-plugin-angular": "^0.15.0",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.8.5",
"html-webpack-plugin": "^2.8.1",
"isparta-instrumenter-loader": "^1.0.0",
"karma": "^0.13.19",
"karma-chai": "^0.1.0",
"karma-chai-as-promised": "^0.1.2",
"karma-chai-sinon": "^0.1.5",
"karma-coverage": "^0.5.3",
"karma-junit-reporter": "^0.3.8",
"karma-mocha": "^0.2.1",
"karma-phantomjs2-launcher": "^0.5.0",
"karma-sinon": "^1.0.4",
"karma-sinon-chai": "^1.1.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.24",
"karma-webpack": "^1.7.0",
"mocha": "^2.4.5",
"node-libs-browser": "^1.0.0",
"null-loader": "^0.1.1",
"postcss-loader": "^0.8.0",
"raw-loader": "^0.5.1",
"rimraf": "^2.5.1",
"sinon": "^1.17.3",
"sinon-chai": "^2.8.0",
"style-loader": "^0.13.0",
"webpack": "^1.12.13",
"webpack-dev-server": "^1.14.1"
}
}
How Does it work with my app?
import angular from 'angular';
import uirouter from 'angular-ui-router';
import 'bootstrap/dist/css/bootstrap.css';
import navigationModule from './navigation/navigation-module';
import apiModule from './api/api-module';
import {baseUrl} from './base-url';
var locationConfig = function($locationProvider){
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
};
locationConfig.$inject = ['$locationProvider'];
angular.module('gammaPhrase', [
uirouter,
navigationModule,
apiModule
])
.config(locationConfig)
.constant('baseUrl', baseUrl);

ecma2015
Javascript finally got good.
const moduleName = 'gammaPhrase.navigation.navigation-ctrl';
class NavigationCtrl {
constructor(languageList, tagList){
var navigation = this;
navigation.languageList = languageList;
navigation.tagList = tagList;
}
}
NavigationCtrl.$inject = ['languageList', 'tagList'];
angular.module(moduleName, []).controller('NavigationCtrl', NavigationCtrl);
export default moduleName;
Demo Controller
Demo Service
const moduleName = 'gammaPhrase.api.language';
/**
* LanguageService provides class methods for interacting with the Language API Resource
*/
export class LanguageService {
constructor($http, baseUrl){
this.$http = $http;
this.baseUrl = baseUrl;
}
/**
* Returns a collection representing available languages
* @return [Collection] Collection of objects with a id, description, and slug properties.
*/
getLanguage () {
return this.$http.get(`${this.baseUrl}language`).then(({data}) => data);
}
}
LanguageService.$inject = ['$http', 'baseUrl'];
angular.module(moduleName, []).service('LanguageService', LanguageService);
export default moduleName;
Why write our code this way?
- Easy to reason about
-
Does not rely on anything framework specific except for rendering
- Highly Portable
- Requires rebuilding views and minimal logic
- Relatively cheap
- Highly Testable
-
Not Es6 Reliant
- Es6 is a tool to assist in code design
- Can be replicated in ecma5
Makes Testing Easier
import {LanguageService} from '../language-service';
import {baseUrl} from '../../base-url';
describe('language api service', () => {
var $http, languageService, $httpBackend, languageData, languageList;
beforeEach(() => {
inject((_$http_, _$httpBackend_) => {
$http = _$http_;
$httpBackend = _$httpBackend_;
});
languageService = new LanguageService($http, baseUrl);
});
describe('getLanguage method', () => {
beforeEach(() => {
languageData = [{'id':1,'description':'english','slug':'en'},{'id':2,'description':'spanish','slug':'es'}];
$httpBackend.whenGET(`${baseUrl}language`).respond(200, {data: languageData});
languageList = languageService.getLanguage();
$httpBackend.flush();
});
it('should return a promise', () => {
languageList.should.be.fullfilled;
});
it('should return language data', () => {
languageList.should.become(languageData);
});
});
});
Old School
var mockWindow, mockModalSvc, sampleSvcObj;
beforeEach(function(){
module(function($provide){
$provide.service('$window', function(){
this.alert= jasmine.createSpy('alert');
});
$provide.service('modalSvc', function(){
this.showModalDialog = jasmine.createSpy('showModalDialog');
});
});
module('services');
});
beforeEach(inject(function($window, modalSvc, sampleSvc){
mockWindow=$window;
mockModalSvc=modalSvc;
sampleSvcObj=sampleSvc;
}));
Makes the Future attainable
import {Component} from 'angular2/angular2'
@Component({
selector: 'my-component',
template: `
<div>
Hello my name is {{name}}.
<button (click)="sayMyName()">
Say my name
</button>
</div>
`
})
export class MyComponent {
constructor() {
this.name = 'Max'
}
sayMyName() {
console.log('My name is', this.name)
}
}
What the Future Looks Like, and why.
By bobbiebarker
What the Future Looks Like, and why.
- 892