SlideShare a Scribd company logo
JHipster 4.0
The Angular Migration
by Flavien Cathala and William Marques
Who are we ?
William Marques Flavien Cathala
@wylmarq
wmarques@ippon.fr
JHipster Member
Ippon Consultant
@flaviencathala
fcathala@ippon.fr
JHipster Member
Epitech Student
Summary
1. Introduction
2. Prepare your migration
3. Angular 2 ecosystem
4. Step-by-step migration
5. After the migration
Migration on JHipster
JHipster Team
VictorJulien Deepu William Flavien Sendil
Kurman
Migration on JHipster
Contributors
Chris Thielen
UI Router founder
Sean Larkin
Webpack member
Migration on JHipster
Chronology
Start of
migration
June
Migration to
Webpack
November
Entities
Tests
December
End ?
January
Dependencies
September
Angular 2
- New syntax
- New concepts
Officially released in September 2016 with:
AngularJS vs Angular 2
Javascript Typescript
MVC Component Oriented
Promise Observable
AngularJS Angular 2
Why migrating ?
- Better performances
- More adapted to mobile terminals
- Better productivity
- AngularJS will be deprecated
PREPARE
YOURSELF
Follow the John Papa style
Major rules :
Folder-By-Feature
Scope Isolation (controllerAs “vm”)
IIFE (avoid minification conflicts)
https://github.com/johnpapa/angular-styleguide/tree/master/a1
(that’s him)
Be modular !
Create module files and declare your controllers and factories there
Code is cleaner
Easy module loader setup
Source: https://github.com/tuchk4/requirejs-angular-loader
Do Components
Only available in >= 1.5.x
Easy switch to Angular 2 Component
Promote best practices (scope isolation)
One-way binding possible
angular.module('heroApp').component('heroDetail', {
templateUrl: 'heroDetail.html',
controller: HeroDetailController,
bindings: {
hero: '='
}
});
BONUS 1 : Do TypeScript
Spoiler : You will write TypeScript with Angular 2 (widely recommended)
Add classes, types, imports in your code
Very easy migration to Angular 2
https://codepen.io/martinmcwhorter/post/angularjs-1-x-with-typescript-or-es6-best-practices
BONUS 2 : Yarn
New package manager (another one)
Much faster
Easy to use (same command as NPM)
Avoid “works on my machine” issue
Offline Installation
Angular 2 ecosystem
Module loader
Why ?
- Code complexity
- Performances
- Avoid injection of huge number of files in index
Module loader
Complexity ** **
Maintainability * ***
Performances * ***
SystemJS Webpack
Which one ?
Module loader
Why Webpack ?
Migration to Webpack
+
Webpack
webpack.common
webpack.dev
webpack.prod
polyfills
vendor
webpack.dev.js
const webpackMerge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
const ENV = 'prod';
module.exports = webpackMerge(commonConfig({env: ENV}), {
output: {
filename: '[hash].[name].bundle.js',
chunkFilename: '[hash].[id].chunk.js'
},
plugins: [
new ExtractTextPlugin('[hash].styles.css')
]
});
Webpack
webpack.prod.js
const webpackMerge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
const ENV = 'dev';
module.exports = webpackMerge(commonConfig({env: ENV}),
{
module: {
rules: [{
test: /.ts$/,
loaders: [
'tslint'
]
}]
},
plugins: [
new BrowserSyncPlugin({
host: 'localhost',
port: 9000,
proxy: 'http://localhost:8080'
}),
new ExtractTextPlugin('styles.css'),
new webpack.NoErrorsPlugin()
]
});
polyfills.ts
import 'bootstrap/dist/css/bootstrap.min.css';
import 'font-awesome/css/font-awesome.min.css';
Webpack
vendor.ts
import 'reflect-metadata/Reflect';
import 'zone.js/dist/zone';
module.exports = function (options) {
const DATAS = {
VERSION:
JSON.stringify(require("../package.json").version),
DEBUG_INFO_ENABLED: options.env === 'dev'
};
return {
entry: {
'polyfills': './src/main/webapp/app/polyfills',
'vendor': './src/main/webapp/app/vendor',
'main': './src/main/webapp/app/app.main'
},
resolve: {
extensions: ['.ts', '.js'],
modules: ['node_modules']
},
output: {
path: './target/www',
filename: '[name].bundle.js',
chunkFilename: '[id].chunk.js'
},
webpack.common.js
Webpack
How to run Webpack ?
webpack --watch --config webpack/webpack.dev.js
webpack -p --config webpack/webpack.prod.js
Using NPM scripts
package.json
"scripts": {
"webpack:dev": "webpack --watch --config
webpack/webpack.dev.js",
"webpack:prod": "webpack -p --config webpack/webpack.prod.js"
}
npm run webpack:dev
npm run webpack:prod
Command lines
Package managers
THE MIGRATION
Migration Plan : Bottom Up
1. Setup migration (install Angular 2 packages, the hybrid app)
2. Migrate small controllers, services, templates (leafs) and then their
parents
3. Migrate routes
4. Check 3rd party dependencies (Angular UI, Angular Translate)
5. Remove AngularJS Code / Dependencies
upgradeAdapter
Incremental Update (hybrid app)
Upgrade your Angular 1 Services, Controllers…
Downgrade your Angular 2 Services, Components…
Bad performance (temporary solution)
Why ?
Setup
Remove ng-app and strict-di attribute in your template
Create an app.main.ts :
upgradeAdapter.bootstrap(document.body, ['myApp.app'], {strictDi: true});
Setup
import * as angular from 'angular';
import { UpgradeAdapter } from '@angular/upgrade';
import { forwardRef } from '@angular/core';
import { Ng2BasicAppModule } from './app.ng2module';
export var upgradeAdapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2BasicAppModule));
Create an upgrade_adapter.ts file
Usage
Downgrade an Angular 2 Component to use it in your Angular 1 App,
add in your module file :
For a service :
.directive(‘home’, <angular.IDirectiveFactory> upgradeAdapter.downgradeNg2Component(HomeComponent))
.factory(‘example’, adapter.downgradeNg2Provider(Example));
Controller Migration
- Remove the IIFE
- Remove the $inject
- Use the @Component annotation
- Replace controller function by class
Controller Migration
import { Component, OnInit, Inject } from '@angular/core';
import { StateService } from "ui-router-ng2";
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { Account, LoginModalService, Principal } from "../shared";
@Component({
selector: 'home',
templateUrl: './home.html'
})
export class HomeComponent implements OnInit {
account: Account;
modalRef: NgbModalRef;
constructor(
private principal: Principal,
private $state: StateService,
private loginModalService: LoginModalService
) {}
ngOnInit() {
this.principal.identity().then((account) => {
this.account = account;
});
}
isAuthenticated() {
return this.principal.isAuthenticated();
}
login() {
this.modalRef = this.loginModalService.open();
}
}
(function() {
'use strict';
angular
.module('ng2FinalApp')
.controller('HomeController', HomeController);
HomeController.$inject = ['$scope', 'Principal', 'LoginService', '$state'];
function HomeController ($scope, Principal, LoginService, $state) {
var vm = this;
vm.account = null;
vm.isAuthenticated = null;
vm.login = LoginService.open;
vm.register = register;
$scope.$on('authenticationSuccess', function() {
getAccount();
});
getAccount();
function getAccount() {
Principal.identity().then(function(account) {
vm.account = account;
vm.isAuthenticated = Principal.isAuthenticated;
});
}
function register () {
$state.go('register');
}
}
})();
Same refactoring as controllers
Add your service in the providers array of your Angular 2 Module in order to
inject it in your Angular 2 Components
Downgrade it using the upgradeAdapter in your Angular 1 Module :
Service migration
.factory('example', adapter.downgradeNg2Provider(Example));
Service Migration
1 2
(function() {
'use strict';
angular
.module('ng2FinalApp')
.factory('LogsService', LogsService);
LogsService.$inject = ['$resource'];
function LogsService ($resource) {
var service = $resource('management/jhipster/logs', {}, {
'findAll': { method: 'GET', isArray: true},
'changeLevel': { method: 'PUT'}
});
return service;
}
})();
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { Log } from './log.model';
@Injectable()
export class LogsService {
constructor(private http: Http) { }
changeLevel(log: Log): Observable<Response> {
return this.http.put('management/jhipster/logs', log);
}
findAll(): Observable<Log[]> {
return this.http.get('management/jhipster/logs').map((res:
Response) => res.json());
}
}
Angular 1 Dependency in Angular 2 ?
Upgrade the Angular 1 provider in your module file, using the upgradeAdapter:
Use the @Inject annotation in your Angular 2 controller/service constructor :
Same for Angular 1 lib dependencies ($state, $rootScope… )
@Inject('heroes') heroes: HeroesService
adapter.upgradeNg1Provider('heroes');
Routes Migration
Angular 2 Router UI-Router NG2
Default solution for Angular Team
Inspired by AngularJS UI Router
Component Oriented
Easy migration from UI Router NG 1
Visualizer feature
Breaking changes from UI Router NG1 Not the official Solution
Final Decision : UI-Router NG2, because of their contribution to JHipster
NG2 Router or UI-Router ?
Route Migration: Setup
Install ui-router-ng1-to-ng2 and ui-router-ng2 NPM packages
Add uirouter.upgrade module dependency in your Angular 1 Module
Add Ng1ToNg2Module in your Angular 2 Module
let ng1module = angular.module("myApp", [uiRouter, 'ui.router.upgrade']);
@NgModule({
imports: [ BrowserModule, Ng1ToNg2Module ]
}) class SampleAppModule {}
Route Migration : UpgradeAdapter
In your upgrade_adapter.ts file, add these lines :
import { uiRouterNgUpgrade } from "ui-router-ng1-to-ng2";
uiRouterNgUpgrade.setUpgradeAdapter(upgradeAdapter);
Route migration : refactoring
import { RegisterComponent } from './register.component';
import { JhiLanguageService } from '../../shared';
export const registerState = {
name: 'register',
parent: 'account',
url: '/register',
data: {
authorities: [],
pageTitle: 'register.title'
},
views: {
'content@': { component: RegisterComponent }
},
resolve: [{
token: 'translate',
deps: [JhiLanguageService],
resolveFn: (languageService) => languageService.setLocations(['register'])
}]
};
(function() {
'use strict';
angular
.module('ng2FinalApp')
.config(stateConfig);
stateConfig.$inject = ['$stateProvider'];
function stateConfig($stateProvider) {
$stateProvider.state('register', {
parent: 'account',
url: '/register',
data: {
authorities: [],
pageTitle: 'register.title'
},
views: {
'content@': {
templateUrl: 'app/account/register/register.html',
controller: 'RegisterController',
controllerAs: 'vm'
}
},
resolve: {
translatePartialLoader: ['$translate', '$translatePartialLoader',
function ($translate, $translatePartialLoader) {
$translatePartialLoader.addPart('register');
return $translate.refresh();
}]
}
});
}
})();
Route migration : Route Declaration
let ACCOUNT_STATES = [
accountState,
activateState,
passwordState,
finishResetState,
requestResetState,
registerState,
sessionsState,
settingsState
];
@NgModule({
imports: [
Ng2BasicSharedModule,
UIRouterModule.forChild({ states: ACCOUNT_STATES })
],
declarations: [
ActivateComponent,
RegisterComponent,
PasswordComponent,
PasswordResetInitComponent,
PasswordResetFinishComponent,
SessionsComponent,
SettingsComponent
],
providers: [
SessionsService,
Register,
Activate,
Password,
PasswordResetInit,
PasswordResetFinish
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class Ng2BasicAccountModule {}
Add your routes in a variable and then import them using UIRouterModule.forChild :
Templates migration
ng-class [ngClass]
ng-click (click)
ng-if *ngIf
ng-model [(ngModel)]
ng-repeat *ngFor
AngularJS Angular 2
Templates migration
<div class="modal-header">
<button class="close" type="button"
(click)="activeModal.dismiss('closed')">x
</button>
<h4 class="modal-title">Sign in</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<h1 jhi-translate="login.title">Sign in</h1>
</div>
<div class="col-md-8 col-md-offset-2">
<div class="alert-danger" *ngIf="authenticationError">
<strong>Failed to sign in!</strong>
</div>
</div>
<div class="col-md-8 col-md-offset-2">
<form class="form" role="form" (ngSubmit)="login()">
<div class="form-group">
<label for="username">Login</label>
<input type="text" class="form-control" name="username"
id="username" [(ngModel)]="username">
</div>
<div class="modal-header">
<button type="button" class="close"
ng-click="vm.cancel()">&times;</button>
<h4 class="modal-title">Sign in</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<h1 data-translate="login.title">Sign in</h1>
</div>
<div class="col-md-8 col-md-offset-2">
<div class="alert-danger" ng-show="vm.authenticationError">
<strong>Failed to sign in!</strong>
</div>
</div>
<div class="col-md-8 col-md-offset-2">
<form class="form" role="form" ng-submit="vm.login($event)">
<div class="form-group">
<label for="username">Login</label>
<input type="text" class="form-control"
id="username" ng-model="vm.username">
</div>
Dependencies migration
- angular-ui
ng-bootstrap- angular-translate
ng2-translate
Some external dependencies needed to be replaced/updated:
- ...
Remove AngularJS
- Remove upgradeAdapter
- Remove all AngularJS files
Once everything has been migrated:
CONCLUSION
Migration Feedback
A lot of new technologies and architectures
Difficult process
Some libs are poorly documented and in alpha
Only a few projects already migrated
Many different choices (Router, Module Loader)
Don’t do it yourself : Use JHipster ;-)
About Angular 2...
Modern approach (Component oriented)
TypeScript Features (types, ES6)
Cleaner code
Less tools (only NPM)
What’s next ?
Router discussions
Hot Module Loader
Ahead Of Time compilation
Finish migration for all configurations
Demo
Questions ?

More Related Content

What's hot (20)

PPTX
Introduction to react_js
MicroPyramid .
 
PDF
A Closer Look At React Native
Ian Wang
 
ODP
Introduction to Angular 2
Knoldus Inc.
 
PDF
Java Intro: Unit1. Hello World
Yakov Fain
 
PDF
Intro to JavaScript
Yakov Fain
 
PPTX
Web Performance & Latest in React
Talentica Software
 
PDF
Web sockets in Angular
Yakov Fain
 
PDF
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
Fwdays
 
PPTX
Migrating an application from Angular 1 to Angular 2
Ross Dederer
 
PDF
Spring Boot and Microservices
seges
 
PDF
ReactJS vs AngularJS - Head to Head comparison
500Tech
 
PDF
GWTcon 2015 - Beyond GWT 3.0 Panic
Cristiano Costantini
 
PPT
sbt 0.10 for beginners?
k4200
 
PPT
Lifthub (rpscala #31)
k4200
 
PDF
Building Universal Applications with Angular 2
Minko Gechev
 
PPTX
Angular1x and Angular 2 for Beginners
Oswald Campesato
 
PDF
React on es6+
Nikolaus Graf
 
PDF
Angular 2: What's New?
jbandi
 
PDF
Angular2 with type script
Ravi Mone
 
PDF
Type script for_java_dev_jul_2020
Yakov Fain
 
Introduction to react_js
MicroPyramid .
 
A Closer Look At React Native
Ian Wang
 
Introduction to Angular 2
Knoldus Inc.
 
Java Intro: Unit1. Hello World
Yakov Fain
 
Intro to JavaScript
Yakov Fain
 
Web Performance & Latest in React
Talentica Software
 
Web sockets in Angular
Yakov Fain
 
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
Fwdays
 
Migrating an application from Angular 1 to Angular 2
Ross Dederer
 
Spring Boot and Microservices
seges
 
ReactJS vs AngularJS - Head to Head comparison
500Tech
 
GWTcon 2015 - Beyond GWT 3.0 Panic
Cristiano Costantini
 
sbt 0.10 for beginners?
k4200
 
Lifthub (rpscala #31)
k4200
 
Building Universal Applications with Angular 2
Minko Gechev
 
Angular1x and Angular 2 for Beginners
Oswald Campesato
 
React on es6+
Nikolaus Graf
 
Angular 2: What's New?
jbandi
 
Angular2 with type script
Ravi Mone
 
Type script for_java_dev_jul_2020
Yakov Fain
 

Viewers also liked (20)

PDF
第三回ありえる社内勉強会 「いわががのLombok」
yoshiaki iwanaga
 
PDF
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - DOSUG February 2016
Matt Raible
 
PDF
Hipster lab
Hipster LAB
 
PPT
1.3 y 1.4 subject and predicate
paolyta28
 
PPTX
AngularJS Version 1.3
Nir Noy
 
PDF
Angular 1.x reloaded: improve your app now! and get ready for 2.0
Carlo Bonamico
 
PPTX
Componentes en angularjs 1.5
Hugo Biarge
 
PPTX
さわってみようReact.js、AngularJS(1系、2系)
Kazuhiro Yoshimoto
 
PPTX
Code migration from Angular 1.x to Angular 2.0
Ran Wahle
 
PPTX
Comment réussir son projet en Angular 1.5 ?
Maxime Bernard
 
PDF
Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016
Matt Raible
 
PPTX
Typescript ppt
akhilsreyas
 
PDF
Introduction to angular 2
Dhyego Fernando
 
PDF
What's New in JHipsterLand - DevNexus 2017
Matt Raible
 
PDF
Angular 2 - The Next Framework
Commit University
 
PPTX
Angular 2 vs Angular 1
GDG Odessa
 
PDF
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Angular Summit 2015
Matt Raible
 
PDF
AngularJS 2, version 1 and ReactJS
Kenneth Ceyer
 
PDF
Quick introduction to Angular 4 for AngularJS 1.5 developers
Paweł Żurowski
 
PPTX
Angular 2 - Better or worse
Vladimir Georgiev
 
第三回ありえる社内勉強会 「いわががのLombok」
yoshiaki iwanaga
 
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - DOSUG February 2016
Matt Raible
 
Hipster lab
Hipster LAB
 
1.3 y 1.4 subject and predicate
paolyta28
 
AngularJS Version 1.3
Nir Noy
 
Angular 1.x reloaded: improve your app now! and get ready for 2.0
Carlo Bonamico
 
Componentes en angularjs 1.5
Hugo Biarge
 
さわってみようReact.js、AngularJS(1系、2系)
Kazuhiro Yoshimoto
 
Code migration from Angular 1.x to Angular 2.0
Ran Wahle
 
Comment réussir son projet en Angular 1.5 ?
Maxime Bernard
 
Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016
Matt Raible
 
Typescript ppt
akhilsreyas
 
Introduction to angular 2
Dhyego Fernando
 
What's New in JHipsterLand - DevNexus 2017
Matt Raible
 
Angular 2 - The Next Framework
Commit University
 
Angular 2 vs Angular 1
GDG Odessa
 
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Angular Summit 2015
Matt Raible
 
AngularJS 2, version 1 and ReactJS
Kenneth Ceyer
 
Quick introduction to Angular 4 for AngularJS 1.5 developers
Paweł Żurowski
 
Angular 2 - Better or worse
Vladimir Georgiev
 
Ad

Similar to Angular 2 Migration - JHipster Meetup 6 (20)

PPTX
Angular2 + rxjs
Christoffer Noring
 
PPTX
Angular%201%20to%20angular%202
Ran Wahle
 
PDF
Commit University - Exploring Angular 2
Commit University
 
PDF
Spring Performance Gains
VMware Tanzu
 
PPTX
Angular 2 - a New Hope
Sami Suo-Heikki
 
PPTX
Angular 2.0
Mallikarjuna G D
 
PDF
Angular 2.0 - What to expect
Allan Marques Baptista
 
PDF
Sharper Better Faster Dagger ‡ - Droidcon SF
Pierre-Yves Ricau
 
PDF
Front End Development for Back End Developers - UberConf 2017
Matt Raible
 
PPTX
Peggy angular 2 in meteor
LearningTech
 
PDF
Angular 2 - Core Concepts
Fabio Biondi
 
PDF
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Ontico
 
PDF
Zukunftssichere Anwendungen mit AngularJS 1.x entwickeln (GDG DevFest Karlsru...
Christian Janz
 
PPTX
Introduction to Angular2
Ivan Matiishyn
 
PDF
Angular 2 for Java Developers
Yakov Fain
 
PDF
Meetup SkillValue - Angular 6 : Bien démarrer son application
Thibault Even
 
PPTX
Reactive application using meteor
Sapna Upreti
 
PDF
Angular 2: core concepts
Codemotion
 
PPTX
Meteor
Noam Kfir
 
PPTX
Front end development with Angular JS
Bipin
 
Angular2 + rxjs
Christoffer Noring
 
Angular%201%20to%20angular%202
Ran Wahle
 
Commit University - Exploring Angular 2
Commit University
 
Spring Performance Gains
VMware Tanzu
 
Angular 2 - a New Hope
Sami Suo-Heikki
 
Angular 2.0
Mallikarjuna G D
 
Angular 2.0 - What to expect
Allan Marques Baptista
 
Sharper Better Faster Dagger ‡ - Droidcon SF
Pierre-Yves Ricau
 
Front End Development for Back End Developers - UberConf 2017
Matt Raible
 
Peggy angular 2 in meteor
LearningTech
 
Angular 2 - Core Concepts
Fabio Biondi
 
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Ontico
 
Zukunftssichere Anwendungen mit AngularJS 1.x entwickeln (GDG DevFest Karlsru...
Christian Janz
 
Introduction to Angular2
Ivan Matiishyn
 
Angular 2 for Java Developers
Yakov Fain
 
Meetup SkillValue - Angular 6 : Bien démarrer son application
Thibault Even
 
Reactive application using meteor
Sapna Upreti
 
Angular 2: core concepts
Codemotion
 
Meteor
Noam Kfir
 
Front end development with Angular JS
Bipin
 
Ad

Recently uploaded (20)

PDF
BRKSP-2551 - Introduction to Segment Routing.pdf
fcesargonca
 
PDF
Top 10 Testing Procedures to Ensure Your Magento to Shopify Migration Success...
CartCoders
 
PPTX
04 Output 1 Instruments & Tools (3).pptx
GEDYIONGebre
 
PPTX
法国巴黎第二大学本科毕业证{Paris 2学费发票Paris 2成绩单}办理方法
Taqyea
 
PDF
Enhancing Parental Roles in Protecting Children from Online Sexual Exploitati...
ICT Frame Magazine Pvt. Ltd.
 
PPTX
L1A Season 1 ENGLISH made by A hegy fixed
toszolder91
 
PPTX
西班牙巴利阿里群岛大学电子版毕业证{UIBLetterUIB文凭证书}文凭复刻
Taqyea
 
PPTX
Metaphysics_Presentation_With_Visuals.pptx
erikjohnsales1
 
PDF
BRKAPP-1102 - Proactive Network and Application Monitoring.pdf
fcesargonca
 
PDF
BRKACI-1003 ACI Brownfield Migration - Real World Experiences and Best Practi...
fcesargonca
 
PDF
Digital burnout toolkit for youth workers and teachers
asociatiastart123
 
PPTX
Networking_Essentials_version_3.0_-_Module_5.pptx
ryan622010
 
PDF
Boardroom AI: The Next 10 Moves | Cerebraix Talent Tech
ssuser73bdb11
 
PPTX
Networking_Essentials_version_3.0_-_Module_3.pptx
ryan622010
 
PPTX
Presentation3gsgsgsgsdfgadgsfgfgsfgagsfgsfgzfdgsdgs.pptx
SUB03
 
DOCX
Custom vs. Off-the-Shelf Banking Software
KristenCarter35
 
PPTX
Softuni - Psychology of entrepreneurship
Kalin Karakehayov
 
PDF
BRKACI-1001 - Your First 7 Days of ACI.pdf
fcesargonca
 
PPTX
Lec15_Mutability Immutability-converted.pptx
khanjahanzaib1
 
PDF
Cleaning up your RPKI invalids, presented at PacNOG 35
APNIC
 
BRKSP-2551 - Introduction to Segment Routing.pdf
fcesargonca
 
Top 10 Testing Procedures to Ensure Your Magento to Shopify Migration Success...
CartCoders
 
04 Output 1 Instruments & Tools (3).pptx
GEDYIONGebre
 
法国巴黎第二大学本科毕业证{Paris 2学费发票Paris 2成绩单}办理方法
Taqyea
 
Enhancing Parental Roles in Protecting Children from Online Sexual Exploitati...
ICT Frame Magazine Pvt. Ltd.
 
L1A Season 1 ENGLISH made by A hegy fixed
toszolder91
 
西班牙巴利阿里群岛大学电子版毕业证{UIBLetterUIB文凭证书}文凭复刻
Taqyea
 
Metaphysics_Presentation_With_Visuals.pptx
erikjohnsales1
 
BRKAPP-1102 - Proactive Network and Application Monitoring.pdf
fcesargonca
 
BRKACI-1003 ACI Brownfield Migration - Real World Experiences and Best Practi...
fcesargonca
 
Digital burnout toolkit for youth workers and teachers
asociatiastart123
 
Networking_Essentials_version_3.0_-_Module_5.pptx
ryan622010
 
Boardroom AI: The Next 10 Moves | Cerebraix Talent Tech
ssuser73bdb11
 
Networking_Essentials_version_3.0_-_Module_3.pptx
ryan622010
 
Presentation3gsgsgsgsdfgadgsfgfgsfgagsfgsfgzfdgsdgs.pptx
SUB03
 
Custom vs. Off-the-Shelf Banking Software
KristenCarter35
 
Softuni - Psychology of entrepreneurship
Kalin Karakehayov
 
BRKACI-1001 - Your First 7 Days of ACI.pdf
fcesargonca
 
Lec15_Mutability Immutability-converted.pptx
khanjahanzaib1
 
Cleaning up your RPKI invalids, presented at PacNOG 35
APNIC
 

Angular 2 Migration - JHipster Meetup 6

  • 1. JHipster 4.0 The Angular Migration by Flavien Cathala and William Marques
  • 2. Who are we ? William Marques Flavien Cathala @wylmarq [email protected] JHipster Member Ippon Consultant @flaviencathala [email protected] JHipster Member Epitech Student
  • 3. Summary 1. Introduction 2. Prepare your migration 3. Angular 2 ecosystem 4. Step-by-step migration 5. After the migration
  • 4. Migration on JHipster JHipster Team VictorJulien Deepu William Flavien Sendil Kurman
  • 5. Migration on JHipster Contributors Chris Thielen UI Router founder Sean Larkin Webpack member
  • 6. Migration on JHipster Chronology Start of migration June Migration to Webpack November Entities Tests December End ? January Dependencies September
  • 7. Angular 2 - New syntax - New concepts Officially released in September 2016 with:
  • 8. AngularJS vs Angular 2 Javascript Typescript MVC Component Oriented Promise Observable AngularJS Angular 2
  • 9. Why migrating ? - Better performances - More adapted to mobile terminals - Better productivity - AngularJS will be deprecated
  • 11. Follow the John Papa style Major rules : Folder-By-Feature Scope Isolation (controllerAs “vm”) IIFE (avoid minification conflicts) https://github.com/johnpapa/angular-styleguide/tree/master/a1 (that’s him)
  • 12. Be modular ! Create module files and declare your controllers and factories there Code is cleaner Easy module loader setup Source: https://github.com/tuchk4/requirejs-angular-loader
  • 13. Do Components Only available in >= 1.5.x Easy switch to Angular 2 Component Promote best practices (scope isolation) One-way binding possible angular.module('heroApp').component('heroDetail', { templateUrl: 'heroDetail.html', controller: HeroDetailController, bindings: { hero: '=' } });
  • 14. BONUS 1 : Do TypeScript Spoiler : You will write TypeScript with Angular 2 (widely recommended) Add classes, types, imports in your code Very easy migration to Angular 2 https://codepen.io/martinmcwhorter/post/angularjs-1-x-with-typescript-or-es6-best-practices
  • 15. BONUS 2 : Yarn New package manager (another one) Much faster Easy to use (same command as NPM) Avoid “works on my machine” issue Offline Installation
  • 17. Module loader Why ? - Code complexity - Performances - Avoid injection of huge number of files in index
  • 18. Module loader Complexity ** ** Maintainability * *** Performances * *** SystemJS Webpack Which one ?
  • 22. webpack.dev.js const webpackMerge = require('webpack-merge'); const commonConfig = require('./webpack.common.js'); const ENV = 'prod'; module.exports = webpackMerge(commonConfig({env: ENV}), { output: { filename: '[hash].[name].bundle.js', chunkFilename: '[hash].[id].chunk.js' }, plugins: [ new ExtractTextPlugin('[hash].styles.css') ] }); Webpack webpack.prod.js const webpackMerge = require('webpack-merge'); const commonConfig = require('./webpack.common.js'); const ENV = 'dev'; module.exports = webpackMerge(commonConfig({env: ENV}), { module: { rules: [{ test: /.ts$/, loaders: [ 'tslint' ] }] }, plugins: [ new BrowserSyncPlugin({ host: 'localhost', port: 9000, proxy: 'http://localhost:8080' }), new ExtractTextPlugin('styles.css'), new webpack.NoErrorsPlugin() ] });
  • 23. polyfills.ts import 'bootstrap/dist/css/bootstrap.min.css'; import 'font-awesome/css/font-awesome.min.css'; Webpack vendor.ts import 'reflect-metadata/Reflect'; import 'zone.js/dist/zone'; module.exports = function (options) { const DATAS = { VERSION: JSON.stringify(require("../package.json").version), DEBUG_INFO_ENABLED: options.env === 'dev' }; return { entry: { 'polyfills': './src/main/webapp/app/polyfills', 'vendor': './src/main/webapp/app/vendor', 'main': './src/main/webapp/app/app.main' }, resolve: { extensions: ['.ts', '.js'], modules: ['node_modules'] }, output: { path: './target/www', filename: '[name].bundle.js', chunkFilename: '[id].chunk.js' }, webpack.common.js
  • 24. Webpack How to run Webpack ? webpack --watch --config webpack/webpack.dev.js webpack -p --config webpack/webpack.prod.js Using NPM scripts package.json "scripts": { "webpack:dev": "webpack --watch --config webpack/webpack.dev.js", "webpack:prod": "webpack -p --config webpack/webpack.prod.js" } npm run webpack:dev npm run webpack:prod Command lines
  • 27. Migration Plan : Bottom Up 1. Setup migration (install Angular 2 packages, the hybrid app) 2. Migrate small controllers, services, templates (leafs) and then their parents 3. Migrate routes 4. Check 3rd party dependencies (Angular UI, Angular Translate) 5. Remove AngularJS Code / Dependencies
  • 28. upgradeAdapter Incremental Update (hybrid app) Upgrade your Angular 1 Services, Controllers… Downgrade your Angular 2 Services, Components… Bad performance (temporary solution) Why ?
  • 29. Setup Remove ng-app and strict-di attribute in your template Create an app.main.ts : upgradeAdapter.bootstrap(document.body, ['myApp.app'], {strictDi: true});
  • 30. Setup import * as angular from 'angular'; import { UpgradeAdapter } from '@angular/upgrade'; import { forwardRef } from '@angular/core'; import { Ng2BasicAppModule } from './app.ng2module'; export var upgradeAdapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2BasicAppModule)); Create an upgrade_adapter.ts file
  • 31. Usage Downgrade an Angular 2 Component to use it in your Angular 1 App, add in your module file : For a service : .directive(‘home’, <angular.IDirectiveFactory> upgradeAdapter.downgradeNg2Component(HomeComponent)) .factory(‘example’, adapter.downgradeNg2Provider(Example));
  • 32. Controller Migration - Remove the IIFE - Remove the $inject - Use the @Component annotation - Replace controller function by class
  • 33. Controller Migration import { Component, OnInit, Inject } from '@angular/core'; import { StateService } from "ui-router-ng2"; import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { Account, LoginModalService, Principal } from "../shared"; @Component({ selector: 'home', templateUrl: './home.html' }) export class HomeComponent implements OnInit { account: Account; modalRef: NgbModalRef; constructor( private principal: Principal, private $state: StateService, private loginModalService: LoginModalService ) {} ngOnInit() { this.principal.identity().then((account) => { this.account = account; }); } isAuthenticated() { return this.principal.isAuthenticated(); } login() { this.modalRef = this.loginModalService.open(); } } (function() { 'use strict'; angular .module('ng2FinalApp') .controller('HomeController', HomeController); HomeController.$inject = ['$scope', 'Principal', 'LoginService', '$state']; function HomeController ($scope, Principal, LoginService, $state) { var vm = this; vm.account = null; vm.isAuthenticated = null; vm.login = LoginService.open; vm.register = register; $scope.$on('authenticationSuccess', function() { getAccount(); }); getAccount(); function getAccount() { Principal.identity().then(function(account) { vm.account = account; vm.isAuthenticated = Principal.isAuthenticated; }); } function register () { $state.go('register'); } } })();
  • 34. Same refactoring as controllers Add your service in the providers array of your Angular 2 Module in order to inject it in your Angular 2 Components Downgrade it using the upgradeAdapter in your Angular 1 Module : Service migration .factory('example', adapter.downgradeNg2Provider(Example));
  • 35. Service Migration 1 2 (function() { 'use strict'; angular .module('ng2FinalApp') .factory('LogsService', LogsService); LogsService.$inject = ['$resource']; function LogsService ($resource) { var service = $resource('management/jhipster/logs', {}, { 'findAll': { method: 'GET', isArray: true}, 'changeLevel': { method: 'PUT'} }); return service; } })(); import { Injectable } from '@angular/core'; import { Http, Response } from '@angular/http'; import { Observable } from 'rxjs/Rx'; import { Log } from './log.model'; @Injectable() export class LogsService { constructor(private http: Http) { } changeLevel(log: Log): Observable<Response> { return this.http.put('management/jhipster/logs', log); } findAll(): Observable<Log[]> { return this.http.get('management/jhipster/logs').map((res: Response) => res.json()); } }
  • 36. Angular 1 Dependency in Angular 2 ? Upgrade the Angular 1 provider in your module file, using the upgradeAdapter: Use the @Inject annotation in your Angular 2 controller/service constructor : Same for Angular 1 lib dependencies ($state, $rootScope… ) @Inject('heroes') heroes: HeroesService adapter.upgradeNg1Provider('heroes');
  • 37. Routes Migration Angular 2 Router UI-Router NG2 Default solution for Angular Team Inspired by AngularJS UI Router Component Oriented Easy migration from UI Router NG 1 Visualizer feature Breaking changes from UI Router NG1 Not the official Solution Final Decision : UI-Router NG2, because of their contribution to JHipster NG2 Router or UI-Router ?
  • 38. Route Migration: Setup Install ui-router-ng1-to-ng2 and ui-router-ng2 NPM packages Add uirouter.upgrade module dependency in your Angular 1 Module Add Ng1ToNg2Module in your Angular 2 Module let ng1module = angular.module("myApp", [uiRouter, 'ui.router.upgrade']); @NgModule({ imports: [ BrowserModule, Ng1ToNg2Module ] }) class SampleAppModule {}
  • 39. Route Migration : UpgradeAdapter In your upgrade_adapter.ts file, add these lines : import { uiRouterNgUpgrade } from "ui-router-ng1-to-ng2"; uiRouterNgUpgrade.setUpgradeAdapter(upgradeAdapter);
  • 40. Route migration : refactoring import { RegisterComponent } from './register.component'; import { JhiLanguageService } from '../../shared'; export const registerState = { name: 'register', parent: 'account', url: '/register', data: { authorities: [], pageTitle: 'register.title' }, views: { 'content@': { component: RegisterComponent } }, resolve: [{ token: 'translate', deps: [JhiLanguageService], resolveFn: (languageService) => languageService.setLocations(['register']) }] }; (function() { 'use strict'; angular .module('ng2FinalApp') .config(stateConfig); stateConfig.$inject = ['$stateProvider']; function stateConfig($stateProvider) { $stateProvider.state('register', { parent: 'account', url: '/register', data: { authorities: [], pageTitle: 'register.title' }, views: { 'content@': { templateUrl: 'app/account/register/register.html', controller: 'RegisterController', controllerAs: 'vm' } }, resolve: { translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) { $translatePartialLoader.addPart('register'); return $translate.refresh(); }] } }); } })();
  • 41. Route migration : Route Declaration let ACCOUNT_STATES = [ accountState, activateState, passwordState, finishResetState, requestResetState, registerState, sessionsState, settingsState ]; @NgModule({ imports: [ Ng2BasicSharedModule, UIRouterModule.forChild({ states: ACCOUNT_STATES }) ], declarations: [ ActivateComponent, RegisterComponent, PasswordComponent, PasswordResetInitComponent, PasswordResetFinishComponent, SessionsComponent, SettingsComponent ], providers: [ SessionsService, Register, Activate, Password, PasswordResetInit, PasswordResetFinish ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class Ng2BasicAccountModule {} Add your routes in a variable and then import them using UIRouterModule.forChild :
  • 42. Templates migration ng-class [ngClass] ng-click (click) ng-if *ngIf ng-model [(ngModel)] ng-repeat *ngFor AngularJS Angular 2
  • 43. Templates migration <div class="modal-header"> <button class="close" type="button" (click)="activeModal.dismiss('closed')">x </button> <h4 class="modal-title">Sign in</h4> </div> <div class="modal-body"> <div class="row"> <div class="col-md-4 col-md-offset-4"> <h1 jhi-translate="login.title">Sign in</h1> </div> <div class="col-md-8 col-md-offset-2"> <div class="alert-danger" *ngIf="authenticationError"> <strong>Failed to sign in!</strong> </div> </div> <div class="col-md-8 col-md-offset-2"> <form class="form" role="form" (ngSubmit)="login()"> <div class="form-group"> <label for="username">Login</label> <input type="text" class="form-control" name="username" id="username" [(ngModel)]="username"> </div> <div class="modal-header"> <button type="button" class="close" ng-click="vm.cancel()">&times;</button> <h4 class="modal-title">Sign in</h4> </div> <div class="modal-body"> <div class="row"> <div class="col-md-4 col-md-offset-4"> <h1 data-translate="login.title">Sign in</h1> </div> <div class="col-md-8 col-md-offset-2"> <div class="alert-danger" ng-show="vm.authenticationError"> <strong>Failed to sign in!</strong> </div> </div> <div class="col-md-8 col-md-offset-2"> <form class="form" role="form" ng-submit="vm.login($event)"> <div class="form-group"> <label for="username">Login</label> <input type="text" class="form-control" id="username" ng-model="vm.username"> </div>
  • 44. Dependencies migration - angular-ui ng-bootstrap- angular-translate ng2-translate Some external dependencies needed to be replaced/updated: - ...
  • 45. Remove AngularJS - Remove upgradeAdapter - Remove all AngularJS files Once everything has been migrated:
  • 47. Migration Feedback A lot of new technologies and architectures Difficult process Some libs are poorly documented and in alpha Only a few projects already migrated Many different choices (Router, Module Loader) Don’t do it yourself : Use JHipster ;-)
  • 48. About Angular 2... Modern approach (Component oriented) TypeScript Features (types, ES6) Cleaner code Less tools (only NPM)
  • 49. What’s next ? Router discussions Hot Module Loader Ahead Of Time compilation Finish migration for all configurations
  • 50. Demo

Editor's Notes

  • #11: TODO : choisir un GIF