Angular 2 Migration - JHipster Meetup 6
-
Upload
william-marques -
Category
Internet
-
view
1.100 -
download
1
Transcript of Angular 2 Migration - JHipster Meetup 6
![Page 1: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/1.jpg)
JHipster 4.0The Angular Migration
by Flavien Cathala and William Marques
![Page 2: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/2.jpg)
Who are we ?William Marques Flavien Cathala
JHipster MemberIppon Consultant
@[email protected] MemberEpitech Student
![Page 3: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/3.jpg)
Summary
1.Introduction
2.Prepare your migration
3.Angular 2 ecosystem
4.Step-by-step migration
5.After the migration
![Page 4: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/4.jpg)
Migration on JHipsterJHipster Team
VictorJulien Deepu William
Flavien Sendil Kurma
n
![Page 5: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/5.jpg)
Migration on JHipsterContributors
Chris Thielen
UI Router founder
Sean Larkin
Webpack member
![Page 6: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/6.jpg)
Migration on JHipsterChronology
Start of migration
June
Migration to Webpack
November
Entities
Tests
December
End ?
JanuaryDependenci
es
September
![Page 7: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/7.jpg)
Angular 2
- New syntax- New concepts
Officially released in September 2016 with:
![Page 8: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/8.jpg)
AngularJS vs Angular 2
Javascript TypescriptMVC Component
OrientedPromise Observable
AngularJS Angular 2
![Page 9: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/9.jpg)
Why migrating ?
- Better performances- More adapted to mobile terminals- Better productivity- AngularJS will be deprecated
![Page 10: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/10.jpg)
PREPARE YOURSELF
![Page 11: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/11.jpg)
Follow the John Papa styleMajor rules :
Folder-By-Feature
Scope Isolation (controllerAs “vm”)
IIFE (avoid minification conflicts)
https://github.com/johnpapa/angular-styleguide/tree/master/a1
(that’s him)
![Page 12: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/12.jpg)
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
![Page 13: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/13.jpg)
Do ComponentsOnly 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: '='
}
});
![Page 14: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/14.jpg)
BONUS 1 : Do TypeScriptSpoiler : 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
![Page 15: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/15.jpg)
BONUS 2 : YarnNew package manager (another one)
Much faster
Easy to use (same command as NPM)
Avoid “works on my machine” issue
Offline Installation
![Page 16: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/16.jpg)
Angular 2 ecosystem
![Page 17: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/17.jpg)
Module loaderWhy ?
- Code complexity
- Performances- Avoid injection of huge number of files in index
![Page 18: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/18.jpg)
Module loader
Complexity ** **Maintainabilit
y* ***
Performances * ***
SystemJS WebpackWhich one ?
![Page 19: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/19.jpg)
Module loaderWhy Webpack ?
![Page 20: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/20.jpg)
Migration to Webpack
+
![Page 21: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/21.jpg)
Webpack
webpack.common
webpack.dev
webpack.prod
polyfills
vendor
![Page 22: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/22.jpg)
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') ]});
Webpackwebpack.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() ]});
![Page 23: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/23.jpg)
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
![Page 24: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/24.jpg)
WebpackHow to run Webpack ?webpack --watch --config
webpack/webpack.dev.js
webpack -p --config webpack/webpack.prod.js
Using NPM scriptspackage.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
![Page 25: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/25.jpg)
Package managers
![Page 26: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/26.jpg)
THE MIGRATION
![Page 27: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/27.jpg)
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
6.Bootstrap your Angular 2 App !
![Page 28: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/28.jpg)
upgradeAdapter
Incremental Update (hybrid app)Upgrade your Angular 1 Services, Controllers…Downgrade your Angular 2 Services, Components… Bad performance (temporary solution)
Why ?
![Page 29: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/29.jpg)
SetupRemove ng-app and strict-di attribute in your template
Create an app.main.ts :upgradeAdapter.bootstrap(document.body, ['myApp.app'], {strictDi: true});
![Page 30: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/30.jpg)
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
![Page 31: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/31.jpg)
UsageDowngrade 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));
![Page 32: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/32.jpg)
Controller Migration
- Remove the IIFE
- Remove the $inject
- Use the @Component annotation
- Replace controller function by class
- Remove controller declaration (angular.module…)
![Page 33: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/33.jpg)
Controller Migrationimport { 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'); } }})();
![Page 34: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/34.jpg)
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));
![Page 35: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/35.jpg)
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());
}
}
![Page 36: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/36.jpg)
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');
![Page 37: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/37.jpg)
Routes Migration
Angular 2 Router UI-Router NG2
Default solution for Angular TeamInspired by AngularJS UI RouterComponent Oriented
Easy migration from UI Router NG 1Visualizer 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 ?
![Page 38: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/38.jpg)
Route Migration: SetupInstall 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 {}
![Page 39: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/39.jpg)
Route Migration : UpgradeAdapterIn your upgrade_adapter.ts file, add these lines :
import { uiRouterNgUpgrade } from "ui-router-ng1-to-
ng2";
uiRouterNgUpgrade.setUpgradeAdapter(upgradeAdapter);
![Page 40: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/40.jpg)
Route migration : refactoringimport { 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(); }] } }); }})();
![Page 41: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/41.jpg)
Route migration : Route Declarationlet 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 :
![Page 42: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/42.jpg)
Templates migration
ng-class [ngClass]ng-click (click)
ng-if *ngIfng-model [(ngModel)]ng-repeat *ngFor
AngularJS Angular 2
![Page 43: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/43.jpg)
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()">×</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>
![Page 44: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/44.jpg)
Dependencies migration
- angular-ui ng-bootstrap- angular-translate ng2-translate
Some external dependencies needed to be replaced/updated:
- ...
![Page 45: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/45.jpg)
Remove AngularJS
- Remove upgradeAdapter- Remove all AngularJS files
Once everything has been migrated:
![Page 46: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/46.jpg)
CONCLUSION
![Page 47: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/47.jpg)
Migration Feedback
A lot of new technologies and architecturesDifficult processSome libs are poorly documented and in alphaOnly a few projects already migratedMany different choices (Router, Module Loader)Don’t do it yourself : Use JHipster ;-)
![Page 48: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/48.jpg)
About Angular 2...
Modern approach (Component oriented)
TypeScript Features (types, ES6)
Cleaner code
Less tools (only NPM)
![Page 49: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/49.jpg)
What’s next ?
Router discussions
Hot Module Loader
Ahead Of Time compilation
Finish migration for all configurations
![Page 50: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/50.jpg)
Demo
![Page 51: Angular 2 Migration - JHipster Meetup 6](https://reader031.fdocuments.in/reader031/viewer/2022020314/587112391a28abac6d8b60cb/html5/thumbnails/51.jpg)
Questions ?