Ionic 3中基于不同配置在单项目下构建多应用的实现方案
当然可行!我之前在Ionic 3 + Angular 5项目里实现过类似需求,结合Angular的多应用配置思路,完全能做到单项目下构建组件差异的两个应用。下面一步步给你拆解实现方案:
核心思路
本质是借助Angular CLI的多应用配置能力,给项目设置两个独立的应用入口,通过依赖注入或环境变量控制同一页面加载不同组件,同时适配Ionic的构建流程。
步骤1:配置Angular CLI多应用(修改.angular-cli.json)
Angular 5使用.angular-cli.json配置项目,找到apps数组,在原有应用基础上添加第二个应用的配置:
{ "apps": [ // 第一个应用(SMS登录版) { "root": "src", "outDir": "www", "main": "app/main.ts", "name": "sms-app", "environmentSource": "environments/environment.ts", "environments": { "dev": "environments/environment.ts", "prod": "environments/environment.prod.ts" }, "assets": [ "assets", "favicon.ico", {"glob": "config.xml", "input": "./", "output": "./"} ] }, // 第二个应用(账号密码登录版) { "root": "src", "outDir": "www-cred", "main": "app/main-cred.ts", "name": "cred-app", "environmentSource": "environments/environment.ts", "environments": { "dev": "environments/environment.cred.ts", "prod": "environments/environment.cred.prod.ts" }, "assets": [ "assets", "favicon.ico", {"glob": "config-cred.xml", "input": "./", "output": "./config.xml"} ] } ] }
重点说明:
outDir:两个应用的构建输出目录要分开,避免覆盖main:第二个应用的入口文件单独创建(比如main-cred.ts)assets:指定各自的config.xml(复制一份原配置改名为config-cred.xml,修改包名、图标等差异化配置)
步骤2:创建差异化的应用入口与模块
① 第二个应用的入口文件(src/app/main-cred.ts)
复制原main.ts,修改导入的模块为第二个应用的根模块:
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { enableProdMode } from '@angular/core'; import { environment } from '../environments/environment.cred'; import { CredAppModule } from './app-cred.module'; if (environment.production) { enableProdMode(); } platformBrowserDynamic().bootstrapModule(CredAppModule);
② 第二个应用的根模块(src/app/app-cred.module.ts)
复制原app.module.ts,核心是替换登录组件的依赖:
import { NgModule } from '@angular/core'; import { IonicApp, IonicModule } from 'ionic-angular'; import { MyApp } from './app.component'; import { LoginPage } from '../pages/login/login'; // 替换为账号密码组件 import { CredAuthComponent } from './auth/cred-auth.component'; import { AuthComponent } from './auth/auth.abstract'; @NgModule({ declarations: [MyApp, LoginPage, CredAuthComponent], imports: [IonicModule.forRoot(MyApp)], bootstrap: [IonicApp], entryComponents: [MyApp, LoginPage, CredAuthComponent], providers: [ // 依赖注入:指定Auth抽象类的实现为CredAuthComponent { provide: AuthComponent, useClass: CredAuthComponent } ] }) export class CredAppModule {}
③ 定义抽象类统一组件接口
为了让LoginPage能兼容两种组件,先定义一个抽象类:
// src/app/auth/auth.abstract.ts import { Component } from '@angular/core'; export abstract class AuthComponent { abstract handleLogin(): void; }
然后让两个登录组件都继承这个抽象类:
// SMS登录组件(src/app/auth/sms-auth.component.ts) import { Component } from '@angular/core'; import { AuthComponent } from './auth.abstract'; @Component({ selector: 'app-sms-auth', template: `<button (click)="handleLogin()">短信验证码登录</button>` }) export class SmsAuthComponent extends AuthComponent { handleLogin() { console.log('执行短信登录逻辑'); } }
// 账号密码登录组件(src/app/auth/cred-auth.component.ts) import { Component } from '@angular/core'; import { AuthComponent } from './auth.abstract'; @Component({ selector: 'app-cred-auth', template: ` <input placeholder="用户名" type="text"> <input placeholder="密码" type="password"> <button (click)="handleLogin()">账号密码登录</button> ` }) export class CredAuthComponent extends AuthComponent { handleLogin() { console.log('执行账号密码登录逻辑'); } }
步骤3:修改LoginPage动态加载组件
在LoginPage中通过依赖注入获取对应的组件,用ngComponentOutlet动态渲染:
// src/pages/login/login.ts import { Component, Inject } from '@angular/core'; import { AuthComponent } from '../../app/auth/auth.abstract'; @Component({ selector: 'page-login', template: `<ng-container *ngComponentOutlet="authComponent"></ng-container>` }) export class LoginPage { authComponent: typeof AuthComponent; constructor(@Inject(AuthComponent) private authComp: AuthComponent) { this.authComponent = authComp.constructor as typeof AuthComponent; } }
如果你觉得依赖注入太复杂,也可以用环境变量直接判断:
在environment.cred.ts中添加标识:
export const environment = { production: false, appType: 'cred' };
然后LoginPage里用ngIf切换组件:
import { environment } from '../../environments/environment'; @Component({ selector: 'page-login', template: ` <app-sms-auth *ngIf="environment.appType === 'sms'"></app-sms-auth> <app-cred-auth *ngIf="environment.appType === 'cred'"></app-cred-auth> ` }) export class LoginPage { environment = environment; }
步骤4:配置Ionic支持多应用构建
修改ionic.config.js,添加第二个应用的配置:
module.exports = { apps: [ { name: 'sms-app', type: 'ionic-angular', root: 'src', webDir: 'www' }, { name: 'cred-app', type: 'ionic-angular', root: 'src', webDir: 'www-cred' } ] };
构建命令
- 构建第一个应用:
ionic build --prod或ng build --app=0 --prod - 构建第二个应用:
ionic build --prod --app=cred-app或ng build --app=1 --prod
如果需要打包成原生APP,可以写个npm脚本简化流程:
"scripts": { "build:sms": "ionic build --prod", "build:cred": "ionic build --prod --app=cred-app", "cordova:sms:android": "npm run build:sms && cordova build android --release", "cordova:cred:android": "npm run build:cred && rm -rf www && cp -r www-cred www && cordova build android --release" }
内容的提问来源于stack exchange,提问作者barakdofinity
相关产品推荐
相关产品推荐

