Ini adalah artikel lanjutan dari Aplikasi seluler hibrid: berbagi logika antara aplikasi Angular2 dan Ionic2. Pada tahun 2016, ini adalah upaya pertama kami untuk berbagi logika bisnis berbasis Ngrx antara aplikasi Angular2 dan aplikasi seluler Ionic2, tetapi menggunakan npm link
“hack” yang cukup tidak stabil, dengan tiga proyek TypeScript npm yang terpisah.
Dengan CLI terbaru Angular8 dan Ionic4, kini ada cara yang lebih elegan untuk mencapai hal ini, berkat struktur proyek mono-repo.
Tujuannya tetap sama:
- meringkas semua logika bisnis (berdasarkan @ngrx/store) dalam modul inti, dan
- menjaga tata letak tampilan tertentu, markup, dan logika navigasi dalam proyek aplikasi seluler dan web.
Catatan: @ngrx/store adalah manajemen status yang didukung RxJS yang terinspirasi oleh aplikasi Redux untuk Angular. Saat ini merupakan cara paling populer untuk menyusun logika bisnis yang kompleks di aplikasi Angular.
Aplikasi demo dan repo Github
Berikut adalah repo bukti konsep kami:
Repo menggunakan struktur mono-repo Nx Workspace (dengan integrasi Ionic khusus yang dirinci nanti):
- /, root proyek berdasarkan Angular (versi 8.1.2) dan @ngrx/store (versi 8.1.0), dikelola oleh Angular CLI
- /libs/core,modul bersama dengan logika status, reduksi, dan tindakan,
- /apps/web, aplikasi web
- /apps/mobile, aplikasi seluler, berdasarkan Ionic (versi 4.7.1), dikelola oleh Ionic CLI
Untuk demonya, kami menggunakan kode contoh counter (tindakan dan reduksi) dari @ngrx/store.
Modul inti menyediakan:
- Antarmuka CounterState, model counter state
- peredam counterReducer, manajemen status counter berdasarkan tindakan yang dikirim,
- Tindakan balasan Menambah, mengurangi, dan mengatur ulang
Di aplikasi seluler atau web, kami menggunakan aset tersebut untuk membangun model status aplikasi.
import {CounterState} from ‘@ngrx-demo/core’; export interface AppState { counter: CounterState, // Add other states here }
Dan, berikan tindakan, layanan, dan reduksi selama bootstrap aplikasi.
import {ActionReducerMap} from '@ngrx/store'; import {counterReducer} from '@ngrx-demo/core'; import {AppState} from './app.state'; const reducers: ActionReducerMap<AppState> = { counter: counterReducer }; @NgModule({ imports: [ BrowserModule, StoreModule.forRoot(reducers) ] bootstrap: [ AppComponent ], declarations: [ AppComponent ], }) export class AppModule { }
Sekarang kita dapat menggunakan aset tersebut di komponen tampilan mana pun pada aplikasi.
// HTML component template <h2> {{counter$ | async}} </h2> <p> <button (click)=”increment()”> +1 </button> <button (click)=”decrement()”> -1 </button> </p> <p> <button (click)=”reset()”> Reset </button> </p>
Dengan komponen yang sesuai:
// Typescript angular component import {CounterActions} from '@ngrx-demo/core'; import {AppState} from './app.state'; @Component({ templateUrl: 'some.component.html' }) export class SomeComponent { counter$: Observable<number>; constructor(private store: Store<AppState>) { this.counter$ = this.store.select(s => s.counter.total); } decrement() { this.store.dispatch(new CounterActions.DecrementAction()); } increment() { this.store.dispatch(new CounterActions.IncrementAction()); } reset() { this.store.dispatch(new CounterActions.ResetAction()); } }
Semua logika bisnis dikemas sepenuhnya dalam modul bersama. Misalnya, kita dapat menambahkan @ngrx/effects ke dalam campuran, untuk menangani panggilan asinkron API.
Tampilan hanya “mengetahui” tentang tindakan yang tersedia untuk dikirim dan model status yang dapat digunakannya.
Integrasi aplikasi ionik ke dalam Nx Workspace
Secara default, Nx Workspaces tidak mendukung aplikasi Ionic. Karena Ionic menggunakan CLI dan dependensinya sendiri untuk membuat, menguji, dan menjalankan aplikasi, /app/mobile memiliki /app/mobile/package.json sendiri (yang independen dari ruang kerja utama /package.json), sehingga menjadi /app/mobile/node_modules miliknya sendiri.
Konfigurasi khusus ionik
Di package.json, Ionic menyediakan beberapa hook untuk menyesuaikan konfigurasi default. Kami menggunakan opsi konfigurasi ionic_watch dan ionic_webpack serta 2 file konfigurasi khusus yang disimpan di /app/mobile/config.
// app/mobile/package.json { ... "description": “An Ionic project”, "config": { "ionic_watch": "./config/watch.config.js", "ionic_webpack": "./config/webpack.config.js" }, ... }
Resolusi modul skrip ketikan
Agar dapat menggunakan modul bersama dan mendapatkan resolusi modul TypeScript yang benar, kami menggunakan properti pemetaan jalur khusus di /app/mobile/tsconfig.json. Di aplikasi kami, kami menggunakan @ngrx-demo, namun Anda dapat menggunakan @local misalnya.
// app/mobile/tsconfig.json { "compilerOptions": { ... "baseUrl": ".", "paths": { "@ngrx-demo/*": ["../../libs/*"] } ... }
Dan plugin webpack jalur TSConfig di konfigurasi Webpack khusus kami, sehingga Webpack mengetahui pemetaan jalur khusus tersebut.
// app/mobile/config/webpack.config.js const TsconfigPathsPlugin = require(‘tsconfig-paths-webpack-plugin’); const resolveConfig = { extensions: [‘.ts’, ‘.js’, ‘.json’], modules: [path.resolve(‘node_modules’)], plugins: [ new TsconfigPathsPlugin({}) ] }; // Default config update const webpackConfig = require(‘../node_modules/@ionic/app-scripts/config/webpack.config’); webpackConfig.dev.resolve = resolveConfig; webpackConfig.prod.resolve = resolveConfig;
Isi ulang langsung
Senang rasanya bisa memanfaatkan live reload selama pengembangan: saat menjalankan ionic serve
, jika file diperbarui di /libs/*, perubahan akan terdeteksi dan aplikasi seluler secara otomatis dimuat ulang di browser Anda. Kami menggunakan konfigurasi jam tangan khusus untuk itu:
// app/mobile/config/watch.config.js // Default config update const watchConfig = require(‘../node_modules/@ionic/app-scripts/config/watch.config’); watchConfig.srcFiles.paths = [ ‘{{SRC}}/**/*.(ts|html|s(c|a)ss)’, ‘../../libs/**/*.(ts|html|s(c|a)ss)’ ];
Alat Pengembang Toko Ngrx
Dan yang terakhir, selama pengembangan, Alat Pengembang Ngrx Store adalah suatu keharusan untuk men-debug aplikasi Anda, tetapi harus dinonaktifkan di lingkungan produksi. Kami menggunakan pemetaan jalur @app/env khusus untuk itu (untuk meniru variabel lingkungan di aplikasi Angular), berkat https://github.com/gshigeto/ionic-environment-variables.
// app/mobile/tsconfig.json { "compilerOptions": { ... "baseUrl": ".", "paths": { "@app/env": ["src/environments/environment"], "@ngrx-demo/*": ["../../libs/*"] } ... }
Dengan pemetaan alias di konfigurasi Webpack khusus kami.
// app/mobile/config/webpack/config.json ... webpackConfig.dev.resolve.alias = { "@app/env": path.resolve('../src/environments/environment.ts') }; webpackConfig.prod.resolve.alias = { "@app/env": path.resolve('../src/environments/environment.prod.ts') };
Kemudian, kita cukup mengimpor variabel lingkungan di aplikasi Ionic kita!
import {StoreModule} from '@ngrx/store'; import {StoreDevtoolsModule} from '@ngrx/store-devtools'; ... import {environment} from '@app/env'; @NgModule({ ... imports: [ BrowserModule, IonicModule.forRoot(AppComponent), DemoCoreModule, StoreModule.forRoot(reducers), EffectsModule.forRoot([]), !environment.production ? StoreDevtoolsModule.instrument({maxAge: 25}) : [] ], ... }) export class AppModule { }
Keunggulan ruang kerja dan mono-repo
Itu dia! Seperti yang Anda lihat, struktur proyek baru ini jauh lebih bersih daripada solusi awal tahun 2016.
Ini mendapat manfaat dari semua keuntungan yang dijelaskan dalam dokumentasi Nx, Mengapa Ruang Kerja (kecuali untuk manajemen ketergantungan terpadu karena aplikasi Ionic memerlukan ketergantungannya sendiri):
Versi terpadu
Segala sesuatu di komitmen saat ini bekerja bersama
Label atau cabang dapat menangkap hal yang sama
Mempromosikan berbagi kode dan penggunaan kembali
Mudah untuk membagi kode menjadi modul lib
Mudah untuk menggunakan/menerapkan kode tersebut dan perubahan terbarunya
Manfaat pemfaktoran ulang
Editor kode dan IDE sadar akan “ruang kerja”.
Dapat memiliki satu komit untuk refactor yang mencakup aplikasi di domain
Pengalaman pengembang yang konsisten
Memastikan semua kode dependen yang diperlukan tersedia
Jika Anda memiliki pertanyaan atau saran untuk meningkatkan aplikasi demo, jangan ragu untuk mengirimkan masalah atau permintaan penarikan!
Catatan:kami sedang membuka lowongan! Apakah Anda pengembang fullstack atau front-end keren yang ingin bekerja di Angular, Java, atau Groovy? Anda harus menghubungi saya untuk bergabung dengan tim impian kami di Paris!
Jika Anda menyukai artikel ini, silakan tekan tombol ❤ untuk merekomendasikannya. Hal ini akan memudahkan pengguna Medium lainnya untuk menemukan hal ini.